From 163a7e0156d9b30c656851727af5690222c07098 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 26 Feb 2018 13:13:56 +0300 Subject: [PATCH] spv cache block headers, use cache in linstunspent and merkle --- routes/shepherd/electrum/balance.js | 2 +- routes/shepherd/electrum/listunspent.js | 6 ++-- routes/shepherd/electrum/merkle.js | 7 +++-- routes/shepherd/electrum/transactions.js | 39 +++++++++++++++++++----- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/routes/shepherd/electrum/balance.js b/routes/shepherd/electrum/balance.js index 6b73d9b..9c4aa25 100644 --- a/routes/shepherd/electrum/balance.js +++ b/routes/shepherd/electrum/balance.js @@ -37,7 +37,7 @@ module.exports = (shepherd) => { shepherd.Promise.all(_utxo.map((_utxoItem, index) => { return new shepherd.Promise((resolve, reject) => { - ecl.blockchainTransactionGet(_utxoItem['tx_hash']) + shepherd.getTransaction(_utxoItem['tx_hash'], network, ecl) .then((_rawtxJSON) => { shepherd.log('electrum gettransaction ==>', true); shepherd.log((index + ' | ' + (_rawtxJSON.length - 1)), true); diff --git a/routes/shepherd/electrum/listunspent.js b/routes/shepherd/electrum/listunspent.js index b280ee4..0e662a7 100644 --- a/routes/shepherd/electrum/listunspent.js +++ b/routes/shepherd/electrum/listunspent.js @@ -31,7 +31,7 @@ module.exports = (shepherd) => { } else { shepherd.Promise.all(_utxo.map((_utxoItem, index) => { return new shepherd.Promise((resolve, reject) => { - ecl.blockchainTransactionGet(_utxoItem['tx_hash']) + shepherd.getTransaction(_utxoItem['tx_hash'], network, ecl) .then((_rawtxJSON) => { shepherd.log('electrum gettransaction ==>', true); shepherd.log(index + ' | ' + (_rawtxJSON.length - 1), true); @@ -70,7 +70,7 @@ module.exports = (shepherd) => { verified: false, }; - // merkle root verification agains another electrum server + // merkle root verification against another electrum server if (verify) { shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height) .then((verifyMerkleRes) => { @@ -97,7 +97,7 @@ module.exports = (shepherd) => { verified: false, }; - // merkle root verification agains another electrum server + // merkle root verification against another electrum server if (verify) { shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height) .then((verifyMerkleRes) => { diff --git a/routes/shepherd/electrum/merkle.js b/routes/shepherd/electrum/merkle.js index 39cde0e..2385d67 100644 --- a/routes/shepherd/electrum/merkle.js +++ b/routes/shepherd/electrum/merkle.js @@ -30,7 +30,7 @@ module.exports = (shepherd) => { return hash; } - shepherd.verifyMerkle = (txid, height, serverList, mainServer) => { + shepherd.verifyMerkle = (txid, height, serverList, mainServer, network) => { // select random server const getRandomIntInclusive = (min, max) => { min = Math.ceil(min); @@ -66,7 +66,7 @@ module.exports = (shepherd) => { ecl = new shepherd.electrumJSCore(_randomServer[1], _randomServer[0], _mainServer[2]); ecl.connect(); - ecl.blockchainBlockGetHeader(height) + shepherd.getBlockHeader(height, network, ecl) .then((blockInfo) => { if (blockInfo && blockInfo['merkle_root']) { @@ -120,7 +120,8 @@ module.exports = (shepherd) => { txid, height, _filteredServerList, - shepherd.electrumCoins[coin].server.ip + ':' + shepherd.electrumCoins[coin].server.port + ':' + shepherd.electrumServers[coin === 'KMD' || coin === 'komodo' ? 'komodo' : coin.toLowerCase()].proto + shepherd.electrumCoins[coin].server.ip + ':' + shepherd.electrumCoins[coin].server.port + ':' + shepherd.electrumServers[coin === 'KMD' || coin === 'komodo' ? 'komodo' : coin.toLowerCase()].proto, + coin ) .then((proof) => { resolve(proof); diff --git a/routes/shepherd/electrum/transactions.js b/routes/shepherd/electrum/transactions.js index fef94af..cd15b05 100644 --- a/routes/shepherd/electrum/transactions.js +++ b/routes/shepherd/electrum/transactions.js @@ -18,24 +18,51 @@ module.exports = (shepherd) => { shepherd.getTransaction = (txid, network, ecl) => { return new shepherd.Promise((resolve, reject) => { if (!shepherd.electrumCache[network]) { - shepherd.electrumCache[network] = { - tx: {}, - blocksHeaders: {}, - }; + shepherd.electrumCache[network] = {}; + } + if (!shepherd.electrumCache[network].tx) { + shepherd.electrumCache[network]['tx'] = {}; } if (!shepherd.electrumCache[network].tx[txid]) { + shepherd.log(`electrum raw input tx ${txid}`, true); + ecl.blockchainTransactionGet(txid) .then((_rawtxJSON) => { shepherd.electrumCache[network].tx[txid] = _rawtxJSON; resolve(_rawtxJSON); }); } else { + shepherd.log(`electrum cached raw input tx ${txid}`, true); resolve(shepherd.electrumCache[network].tx[txid]); } }); } + shepherd.getBlockHeader = (height, network, ecl) => { + return new shepherd.Promise((resolve, reject) => { + if (!shepherd.electrumCache[network]) { + shepherd.electrumCache[network] = {}; + } + if (!shepherd.electrumCache[network].blockHeader) { + shepherd.electrumCache[network]['blockHeader'] = {}; + } + + if (!shepherd.electrumCache[network].blockHeader[height]) { + shepherd.log(`electrum raw block ${height}`, true); + + ecl.blockchainBlockGetHeader(height) + .then((_rawtxJSON) => { + shepherd.electrumCache[network].blockHeader[height] = _rawtxJSON; + resolve(_rawtxJSON); + }); + } else { + shepherd.log(`electrum cached raw block ${height}`, true); + resolve(shepherd.electrumCache[network].blockHeader[height]); + } + }); + } + shepherd.get('/electrum/listtransactions', (req, res, next) => { if (shepherd.checkToken(req.query.token)) { const network = req.query.network || shepherd.findNetworkObj(req.query.coin); @@ -82,7 +109,7 @@ module.exports = (shepherd) => { let index = 0; async.eachOfSeries(json, (transaction, ind, callback) => { - ecl.blockchainBlockGetHeader(transaction.height) + shepherd.getBlockHeader(transaction.height, network, ecl) .then((blockInfo) => { if (blockInfo && blockInfo.timestamp) { @@ -175,8 +202,6 @@ module.exports = (shepherd) => { .then((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]);