Browse Source

refactor spv tx history to use async series

v0.25
pbca26 7 years ago
parent
commit
00c1617e82
  1. 1
      package.json
  2. 193
      routes/shepherd/electrum/transactions.js

1
package.json

@ -30,6 +30,7 @@
"dependencies": { "dependencies": {
"adm-zip": "^0.4.7", "adm-zip": "^0.4.7",
"arch": "^2.1.0", "arch": "^2.1.0",
"async": "^2.6.0",
"bigi": "^1.4.2", "bigi": "^1.4.2",
"bip39": "^2.4.0", "bip39": "^2.4.0",
"bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash", "bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash",

193
routes/shepherd/electrum/transactions.js

@ -1,3 +1,5 @@
const async = require('async');
module.exports = (shepherd) => { module.exports = (shepherd) => {
shepherd.sortTransactions = (transactions) => { shepherd.sortTransactions = (transactions) => {
return transactions.sort((b, a) => { return transactions.sort((b, a) => {
@ -51,14 +53,16 @@ module.exports = (shepherd) => {
if (json && if (json &&
json.length) { json.length) {
let _rawtx = []; let _rawtx = [];
let _inputTxs = {};
json = shepherd.sortTransactions(json); json = shepherd.sortTransactions(json);
json = json.length > MAX_TX ? json.slice(0, MAX_TX) : json; json = json.length > MAX_TX ? json.slice(0, MAX_TX) : json;
shepherd.log(json.length, true); shepherd.log(json.length, true);
let index = 0;
shepherd.Promise.all(json.map((transaction, index) => { async.eachOfSeries(json, (transaction, ind, callback) => {
return new shepherd.Promise((resolve, reject) => { console.log(`index ${index}`);
//return new shepherd.Promise((resolve, reject) => {
ecl.blockchainBlockGetHeader(transaction.height) ecl.blockchainBlockGetHeader(transaction.height)
.then((blockInfo) => { .then((blockInfo) => {
if (blockInfo && if (blockInfo &&
@ -79,72 +83,113 @@ module.exports = (shepherd) => {
shepherd.log('decodedtx =>', true); shepherd.log('decodedtx =>', true);
shepherd.log(decodedTx.outputs, true); shepherd.log(decodedTx.outputs, true);
let index2 = 0;
if (decodedTx && if (decodedTx &&
decodedTx.inputs) { decodedTx.inputs) {
shepherd.Promise.all(decodedTx.inputs.map((_decodedInput, index) => { async.eachOfSeries(decodedTx.inputs, (_decodedInput, index2, callback2) => {
return new shepherd.Promise((_resolve, _reject) => { //shepherd.Promise.all(decodedTx.inputs.map((_decodedInput, index) => {
//return new shepherd.Promise((_resolve, _reject) => {
if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') { if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') {
ecl.blockchainTransactionGet(_decodedInput.txid) if (!_inputTxs[_decodedInput.txid]) {
.then((rawInput) => { ecl.blockchainTransactionGet(_decodedInput.txid)
const decodedVinVout = shepherd.electrumJSTxDecoder(rawInput, network, _network); .then((rawInput) => {
_inputTxs[_decodedInput.txid] = rawInput;
shepherd.log('electrum raw input tx ==>', true);
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) { if (decodedVinVout) {
shepherd.log(decodedVinVout.outputs[_decodedInput.n], true); shepherd.log(decodedVinVout.outputs[_decodedInput.n], true);
txInputs.push(decodedVinVout.outputs[_decodedInput.n]); txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
_resolve(true); index2++;
callback2();
} else { } else {
_resolve(true); index2++;
callback2();
} }
}); }
} else { } else {
_resolve(true); index2++;
callback2();
}
console.log(`${index2} | ${decodedTx.inputs.length - 1} => main callback`);
if (index2 === decodedTx.inputs.length - 1) {
index++;
const _parsedTx = {
network: decodedTx.network,
format: decodedTx.format,
inputs: txInputs,
outputs: decodedTx.outputs,
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 (formattedTx.type) {
formattedTx.height = transaction.height;
formattedTx.blocktime = blockInfo.timestamp;
formattedTx.timereceived = blockInfo.timereceived;
formattedTx.hex = _rawtxJSON;
formattedTx.inputs = decodedTx.inputs;
formattedTx.outputs = decodedTx.outputs;
formattedTx.locktime = decodedTx.format.locktime;
_rawtx.push(formattedTx);
} else {
formattedTx[0].height = transaction.height;
formattedTx[0].blocktime = blockInfo.timestamp;
formattedTx[0].timereceived = blockInfo.timereceived;
formattedTx[0].hex = _rawtxJSON;
formattedTx[0].inputs = decodedTx.inputs;
formattedTx[0].outputs = decodedTx.outputs;
formattedTx[0].locktime = decodedTx.format.locktime;
formattedTx[1].height = transaction.height;
formattedTx[1].blocktime = blockInfo.timestamp;
formattedTx[1].timereceived = blockInfo.timereceived;
formattedTx[1].hex = _rawtxJSON;
formattedTx[1].inputs = decodedTx.inputs;
formattedTx[1].outputs = decodedTx.outputs;
formattedTx[1].locktime = decodedTx.format.locktime;
_rawtx.push(formattedTx[0]);
_rawtx.push(formattedTx[1]);
}
callback();
} }
});
}))
.then(promiseResult => {
const _parsedTx = {
network: decodedTx.network,
format: decodedTx.format,
inputs: txInputs,
outputs: decodedTx.outputs,
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 (index === json.length) {
ecl.close();
if (formattedTx.type) {
formattedTx.height = transaction.height; const successObj = {
formattedTx.blocktime = blockInfo.timestamp; msg: 'success',
formattedTx.timereceived = blockInfo.timereceived; result: _rawtx,
formattedTx.hex = _rawtxJSON; };
formattedTx.inputs = decodedTx.inputs;
formattedTx.outputs = decodedTx.outputs; res.end(JSON.stringify(successObj));
formattedTx.locktime = decodedTx.format.locktime; }
_rawtx.push(formattedTx); //});
} else {
formattedTx[0].height = transaction.height;
formattedTx[0].blocktime = blockInfo.timestamp;
formattedTx[0].timereceived = blockInfo.timereceived;
formattedTx[0].hex = _rawtxJSON;
formattedTx[0].inputs = decodedTx.inputs;
formattedTx[0].outputs = decodedTx.outputs;
formattedTx[0].locktime = decodedTx.format.locktime;
formattedTx[1].height = transaction.height;
formattedTx[1].blocktime = blockInfo.timestamp;
formattedTx[1].timereceived = blockInfo.timereceived;
formattedTx[1].hex = _rawtxJSON;
formattedTx[1].inputs = decodedTx.inputs;
formattedTx[1].outputs = decodedTx.outputs;
formattedTx[1].locktime = decodedTx.format.locktime;
_rawtx.push(formattedTx[0]);
_rawtx.push(formattedTx[1]);
}
resolve(true);
}); });
/*.then(promiseResult => {
resolve(true);
});*/
} else { } else {
const _parsedTx = { const _parsedTx = {
network: decodedTx.network, network: decodedTx.network,
@ -158,7 +203,19 @@ module.exports = (shepherd) => {
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx); _rawtx.push(formattedTx);
resolve(true); index++;
callback();
if (index === json.length) {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
};
res.end(JSON.stringify(successObj));
}
} }
}); });
} else { } else {
@ -173,12 +230,24 @@ module.exports = (shepherd) => {
}; };
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx); _rawtx.push(formattedTx);
resolve(true); callback();
index++;
} }
}); });
}); //});
}))
.then(promiseResult => { if (index === json.length) {
ecl.close();
const successObj = {
msg: 'success',
result: _rawtx,
};
res.end(JSON.stringify(successObj));
}
});
/*.then(promiseResult => {
ecl.close(); ecl.close();
const successObj = { const successObj = {
@ -187,7 +256,7 @@ module.exports = (shepherd) => {
}; };
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
}); });*/
} else { } else {
ecl.close(); ecl.close();

Loading…
Cancel
Save