Browse Source

spv cache block headers, use cache in linstunspent and merkle

v0.25
pbca26 7 years ago
parent
commit
163a7e0156
  1. 2
      routes/shepherd/electrum/balance.js
  2. 6
      routes/shepherd/electrum/listunspent.js
  3. 7
      routes/shepherd/electrum/merkle.js
  4. 39
      routes/shepherd/electrum/transactions.js

2
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);

6
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) => {

7
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);

39
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]);

Loading…
Cancel
Save