Browse Source

spv transaction history use one time caching

v0.25
pbca26 7 years ago
parent
commit
8f2efde629
  1. 348
      routes/shepherd/electrum/transactions.js

348
routes/shepherd/electrum/transactions.js

@ -60,119 +60,94 @@ module.exports = (shepherd) => {
shepherd.log(json.length, true); shepherd.log(json.length, true);
let index = 0; let index = 0;
const _getTransaction = (txid) => {
return new shepherd.Promise((resolve, reject) => {
if (!_inputTxs[txid]) {
ecl.blockchainTransactionGet(txid)
.then((_rawtxJSON) => {
resolve(_rawtxJSON);
});
} else {
resolve(_inputTxs[txid]);
}
});
} ;
async.eachOfSeries(json, (transaction, ind, callback) => { async.eachOfSeries(json, (transaction, ind, callback) => {
console.log(`index ${index}`); ecl.blockchainBlockGetHeader(transaction.height)
//return new shepherd.Promise((resolve, reject) => { .then((blockInfo) => {
ecl.blockchainBlockGetHeader(transaction.height) if (blockInfo &&
.then((blockInfo) => { blockInfo.timestamp) {
if (blockInfo && _getTransaction(transaction['tx_hash'])
blockInfo.timestamp) { .then((_rawtxJSON) => {
ecl.blockchainTransactionGet(transaction['tx_hash']) if (!_inputTxs[transaction['tx_hash']]) {
.then((_rawtxJSON) => { _inputTxs[transaction['tx_hash']] = _rawtxJSON;
shepherd.log('electrum gettransaction ==>', true); }
shepherd.log((index + ' | ' + (_rawtxJSON.length - 1)), true); shepherd.log('electrum gettransaction ==>', true);
shepherd.log(_rawtxJSON, true); shepherd.log((index + ' | ' + (_rawtxJSON.length - 1)), true);
// shepherd.log(_rawtxJSON, true);
// decode tx
const _network = shepherd.getNetworkData(network); // decode tx
const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); const _network = shepherd.getNetworkData(network);
const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network);
let txInputs = [];
shepherd.log(`decodedtx network ${network}`, true); let txInputs = [];
shepherd.log(`decodedtx network ${network}`, true);
shepherd.log('decodedtx =>', true);
shepherd.log(decodedTx.outputs, true); shepherd.log('decodedtx =>', true);
// shepherd.log(decodedTx.outputs, true);
let index2 = 0;
if (decodedTx && let index2 = 0;
decodedTx.inputs) { if (decodedTx &&
async.eachOfSeries(decodedTx.inputs, (_decodedInput, index2, callback2) => { decodedTx.inputs &&
//shepherd.Promise.all(decodedTx.inputs.map((_decodedInput, index) => { decodedTx.inputs.length) {
//return new shepherd.Promise((_resolve, _reject) => { async.eachOfSeries(decodedTx.inputs, (_decodedInput, ind2, callback2) => {
if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') { function checkLoop() {
if (!_inputTxs[_decodedInput.txid]) { index2++;
ecl.blockchainTransactionGet(_decodedInput.txid)
.then((rawInput) => {
_inputTxs[_decodedInput.txid] = rawInput;
const decodedVinVout = shepherd.electrumJSTxDecoder(rawInput, network, _network);
shepherd.log(`electrum raw input tx ${_decodedInput.txid} ==>`, true);
if (decodedVinVout) {
shepherd.log(decodedVinVout.outputs[_decodedInput.n], true);
txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
index2++;
callback2();
} else {
index2++;
callback2();
}
});
} else {
const decodedVinVout = shepherd.electrumJSTxDecoder(_inputTxs[_decodedInput.txid], network, _network);
shepherd.log(`electrum raw one time cached input tx ${_decodedInput.txid} ==>`, true);
if (decodedVinVout) {
shepherd.log(decodedVinVout.outputs[_decodedInput.n], true);
txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
index2++;
callback2();
} else {
index2++;
callback2();
}
}
} else {
index2++;
callback2();
}
console.log(`${index2} | ${decodedTx.inputs.length - 1} => main callback`); if (index2 === decodedTx.inputs.length) {
if (index2 === decodedTx.inputs.length - 1) { shepherd.log(`tx history decode inputs ${decodedTx.inputs.length} | ${index2} => main callback`, true);
index++; const _parsedTx = {
const _parsedTx = { network: decodedTx.network,
network: decodedTx.network, format: decodedTx.format,
format: decodedTx.format, inputs: txInputs,
inputs: txInputs, outputs: decodedTx.outputs,
outputs: decodedTx.outputs, height: transaction.height,
height: transaction.height, timestamp: Number(transaction.height) === 0 ? Math.floor(Date.now() / 1000) : blockInfo.timestamp,
timestamp: Number(transaction.height) === 0 ? Math.floor(Date.now() / 1000) : blockInfo.timestamp, confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height,
confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height, };
};
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
if (formattedTx.type) {
if (formattedTx.type) { formattedTx.height = transaction.height;
formattedTx.height = transaction.height; formattedTx.blocktime = blockInfo.timestamp;
formattedTx.blocktime = blockInfo.timestamp; formattedTx.timereceived = blockInfo.timereceived;
formattedTx.timereceived = blockInfo.timereceived; formattedTx.hex = _rawtxJSON;
formattedTx.hex = _rawtxJSON; formattedTx.inputs = decodedTx.inputs;
formattedTx.inputs = decodedTx.inputs; formattedTx.outputs = decodedTx.outputs;
formattedTx.outputs = decodedTx.outputs; formattedTx.locktime = decodedTx.format.locktime;
formattedTx.locktime = decodedTx.format.locktime; _rawtx.push(formattedTx);
_rawtx.push(formattedTx); } else {
} else { formattedTx[0].height = transaction.height;
formattedTx[0].height = transaction.height; formattedTx[0].blocktime = blockInfo.timestamp;
formattedTx[0].blocktime = blockInfo.timestamp; formattedTx[0].timereceived = blockInfo.timereceived;
formattedTx[0].timereceived = blockInfo.timereceived; formattedTx[0].hex = _rawtxJSON;
formattedTx[0].hex = _rawtxJSON; formattedTx[0].inputs = decodedTx.inputs;
formattedTx[0].inputs = decodedTx.inputs; formattedTx[0].outputs = decodedTx.outputs;
formattedTx[0].outputs = decodedTx.outputs; formattedTx[0].locktime = decodedTx.format.locktime;
formattedTx[0].locktime = decodedTx.format.locktime; formattedTx[1].height = transaction.height;
formattedTx[1].height = transaction.height; formattedTx[1].blocktime = blockInfo.timestamp;
formattedTx[1].blocktime = blockInfo.timestamp; formattedTx[1].timereceived = blockInfo.timereceived;
formattedTx[1].timereceived = blockInfo.timereceived; formattedTx[1].hex = _rawtxJSON;
formattedTx[1].hex = _rawtxJSON; formattedTx[1].inputs = decodedTx.inputs;
formattedTx[1].inputs = decodedTx.inputs; formattedTx[1].outputs = decodedTx.outputs;
formattedTx[1].outputs = decodedTx.outputs; formattedTx[1].locktime = decodedTx.format.locktime;
formattedTx[1].locktime = decodedTx.format.locktime; _rawtx.push(formattedTx[0]);
_rawtx.push(formattedTx[0]); _rawtx.push(formattedTx[1]);
_rawtx.push(formattedTx[1]);
}
callback();
} }
index++;
if (index === json.length) { if (index === json.length) {
ecl.close(); ecl.close();
@ -181,82 +156,105 @@ module.exports = (shepherd) => {
msg: 'success', msg: 'success',
result: _rawtx, result: _rawtx,
}; };
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
} }
//});
});
/*.then(promiseResult => {
resolve(true); callback();
});*/ shepherd.log(`tx history main loop ${json.length} | ${index}`, true);
} else { }
const _parsedTx = { callback2();
network: decodedTx.network, }
format: 'cant parse',
inputs: 'cant parse',
outputs: 'cant parse',
height: transaction.height,
timestamp: Number(transaction.height) === 0 ? Math.floor(Date.now() / 1000) : blockInfo.timestamp,
confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height,
};
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') {
_rawtx.push(formattedTx); if (!_inputTxs[_decodedInput.txid]) {
index++; ecl.blockchainTransactionGet(_decodedInput.txid)
callback(); .then((rawInput) => {
_inputTxs[_decodedInput.txid] = rawInput;
if (index === json.length) { const decodedVinVout = shepherd.electrumJSTxDecoder(rawInput, network, _network);
ecl.close();
shepherd.log(`electrum raw input tx ${_decodedInput.txid} ==>`, true);
const successObj = {
msg: 'success', if (decodedVinVout) {
result: _rawtx, shepherd.log(decodedVinVout.outputs[_decodedInput.n], true);
}; txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
}
res.end(JSON.stringify(successObj)); checkLoop();
});
} else {
const decodedVinVout = shepherd.electrumJSTxDecoder(_inputTxs[_decodedInput.txid], network, _network);
shepherd.log(`electrum raw one time cached input tx ${_decodedInput.txid} ==>`, true);
if (decodedVinVout) {
shepherd.log(decodedVinVout.outputs[_decodedInput.n], true);
txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
}
checkLoop();
}
} else {
checkLoop();
} }
});
} else {
const _parsedTx = {
network: decodedTx.network,
format: 'cant parse',
inputs: 'cant parse',
outputs: 'cant parse',
height: transaction.height,
timestamp: Number(transaction.height) === 0 ? Math.floor(Date.now() / 1000) : blockInfo.timestamp,
confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height,
};
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx);
index++;
if (index === json.length) {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
};
res.end(JSON.stringify(successObj));
} else {
callback();
} }
}); }
} else { });
const _parsedTx = { } else {
network: 'cant parse', const _parsedTx = {
format: 'cant parse', network: 'cant parse',
inputs: 'cant parse', format: 'cant parse',
outputs: 'cant parse', inputs: 'cant parse',
height: transaction.height, outputs: 'cant parse',
timestamp: 'cant get block info', height: transaction.height,
confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height, timestamp: 'cant get block info',
confirmations: Number(transaction.height) === 0 ? 0 : currentHeight - transaction.height,
};
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx);
index++;
if (index === json.length) {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
}; };
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx); res.end(JSON.stringify(successObj));
} else {
callback(); callback();
index++;
} }
}); }
//}); });
if (index === json.length) {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
};
res.end(JSON.stringify(successObj));
}
}); });
/*.then(promiseResult => {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
};
res.end(JSON.stringify(successObj));
});*/
} else { } else {
ecl.close(); ecl.close();

Loading…
Cancel
Save