From 3dddfcf7eac0ec8bd39eeecfb5dd7fe9b8032ed5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 1 Apr 2016 00:57:26 -0700 Subject: [PATCH] more mempool work. --- lib/bcoin/mempool.js | 128 ++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index 74f6fd54..f3a11d34 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -119,7 +119,7 @@ Mempool.prototype.addBlock = function addBlock(block, callback, force) { callback = utils.wrap(callback, unlock); utils.forEachSerial(block.txs, function(tx, next) { - self.removeUnchecked(tx, next); + self.removeUnchecked(tx.hash('hex'), next); }, callback); }; @@ -539,6 +539,7 @@ Mempool.prototype.fillAllTX = function fillAllTX(tx, callback) { Mempool.prototype.fillAllCoins = function fillAllCoins(tx, callback) { var self = this; + var doubleSpend = false; this.fillCoins(tx, function(err) { if (err) @@ -547,7 +548,32 @@ Mempool.prototype.fillAllCoins = function fillAllCoins(tx, callback) { if (tx.hasCoins()) return callback(null, tx); - self.chain.db.fillCoins(tx, callback); + utils.forEach(tx.inputs, function(input, next) { + var hash = input.prevout.hash; + var index = input.prevout.index; + + if (self.isSpentSync(hash, index)) { + doubleSpend = true; + return next(); + } + + self.chain.db.getCoin(hash, index, function(err, coin) { + if (err) + return next(err); + + if (!coin) + return next(); + + input.coin = coin; + + next(); + }); + }, function(err) { + if (err) + return callback(err); + + return callback(null, tx, doubleSpend); + }); }); }; @@ -603,64 +629,64 @@ Mempool.prototype.addUnchecked = function addUnchecked(tx, callback) { }); }; -Mempool.prototype.removeUnchecked = function removeUnchecked(tx, callback) { +Mempool.prototype.removeUnchecked = function removeUnchecked(hash, callback) { var self = this; - var hash, input, output, i, key, coin, prev; + var tx, input, output, i, key, coin; - callback = utils.asyncify(callback); - - try { - tx = this.getTXSync(tx); - } catch (e) { - return callback(e); + if (hash instanceof bcoin.tx) { + tx = hash; + hash = tx.hash('hex'); + } else { + try { + tx = this.getTXSync(hash); + } catch (e) { + return utils.asyncify(callback)(e); + } } if (!tx) - return callback(); + return utils.nextTick(callback); - hash = tx.hash('hex'); + this.fillAllTX(tx, function(err, tx) { + if (err) + return callback(err); - delete this.txs[hash]; + delete self.txs[hash]; - try { - this.removeOrphanSync(hash); - } catch (e) { - return callback(e); - } - - this.addressMap.removeTX(tx); - this.psIndex.remove(tx); - - for (i = 0; i < tx.inputs.length; i++) { - inputs = tx.outputs[i]; - key = input.prevout.hash + '/' + input.prevout.index; - delete this.coins[key]; - delete this.spent[key]; - this.addressMap.removeCoin(input); try { - prev = this.getTXSync(input.prevout.hash); + self.removeOrphanSync(hash); } catch (e) { return callback(e); } - if (prev) { - coin = bcoin.coin(prev, input.prevout.index); - this.coins[key] = coin.toRaw(); - this.addressMap.addCoin(coin); + + self.addressMap.removeTX(tx); + self.psIndex.remove(tx); + + for (i = 0; i < tx.inputs.length; i++) { + inputs = tx.outputs[i]; + key = input.prevout.hash + '/' + input.prevout.index; + delete self.spent[key]; + delete self.coins[key]; + self.addressMap.removeCoin(input); + if (self.hasTXSync(input.prevout.hash)) { + self.coins[key] = input.coin.toRaw(); + self.addressMap.addCoin(input.coin); + } } - } - for (i = 0; i < tx.outputs.length; i++) { - output = tx.outputs[i]; - key = hash + '/' + i; - delete this.coins[key]; - delete this.spent[key]; - this.addressMap.removeCoin(tx, i); - } + for (i = 0; i < tx.outputs.length; i++) { + output = tx.outputs[i]; + key = hash + '/' + i; + delete self.coins[key]; + delete self.spent[key]; + self.addressMap.removeCoin(tx, i); + } - this.totalSize -= tx.getSize(); - this.emit('remove tx', tx); + self.totalSize -= tx.getSize(); + self.emit('remove tx', tx); - return callback(); + return callback(); + }); }; Mempool.prototype.removeOrphanSync = function removeOrphanSync(tx) { @@ -1328,10 +1354,11 @@ AddressMap.prototype.removeTX = function removeTX(tx) { if (map) { index = binarySearch(map, hash); - if (index !== -1) + if (index !== -1) { map.splice(index, 1); - if (map.length === 0) - delete this.map.tx[address]; + if (map.length === 0) + delete this.map.tx[address]; + } } } }; @@ -1372,10 +1399,11 @@ AddressMap.prototype.removeCoin = function removeCoin(tx, i) { if (map) { index = binarySearch(map, key); - if (index !== -1) + if (index !== -1) { map.splice(index, 1); - if (map.length === 0) - delete this.map.coin[address]; + if (map.length === 0) + delete this.map.coin[address]; + } } };