From 0b2023d62cfb0c92d5087fc3e1d97d8c914fdff5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 16 Aug 2016 11:34:25 -0700 Subject: [PATCH] mempool: refactor. --- lib/bcoin/http/rpc.js | 1 - lib/bcoin/mempool.js | 71 +++++++++++++++++-------------------------- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/lib/bcoin/http/rpc.js b/lib/bcoin/http/rpc.js index dd026c0b..5a220b52 100644 --- a/lib/bcoin/http/rpc.js +++ b/lib/bcoin/http/rpc.js @@ -1563,7 +1563,6 @@ RPC.prototype.getnetworkhashps = function getnetworkhashps(args, callback) { }; RPC.prototype.prioritisetransaction = function prioritisetransaction(args, callback) { - var self = this; var hash, pri, fee, entry; if (args.help || args.length !== 3) { diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index 994916e9..78c12c87 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -102,6 +102,7 @@ function Mempool(options) { this.prematureWitness = !!this.options.prematureWitness; this.maxSize = options.maxSize || constants.mempool.MAX_MEMPOOL_SIZE; + this.expiryTime = options.expiryTime || constants.mempool.MEMPOOL_EXPIRY; this.blockSinceBump = false; this.lastFeeUpdate = utils.now(); this.minFeeRate = 0; @@ -236,7 +237,7 @@ Mempool.prototype.limitMempoolSize = function limitMempoolSize(entryHash) { return trimmed; hashes = this.getSnapshot(); - end = utils.now() - constants.mempool.MEMPOOL_EXPIRY; + end = utils.now() - this.expiryTime; for (i = 0; i < hashes.length; i++) { hash = hashes[i]; @@ -661,11 +662,8 @@ Mempool.prototype.addUnchecked = function addUnchecked(entry, callback, force) { callback = utils.wrap(callback, unlock); - this._addUnchecked(entry); + this.trackEntry(entry); - this.totalSpent += entry.tx.inputs.length; - this.size += this.memUsage(entry.tx); - this.totalTX++; this.emit('tx', entry.tx); this.emit('add tx', entry.tx); @@ -714,11 +712,14 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(entry, limit) { this.removeOrphan(entry.tx); - this._removeUnchecked(entry, limit); + // We do not remove spenders if this is + // being removed for a block. The spenders + // are still spending valid coins (which + // now exist on the blockchain). + if (limit) + this._removeSpenders(entry); - this.totalSpent -= entry.tx.inputs.length; - this.size -= this.memUsage(entry.tx); - this.totalTX--; + this.untrackEntry(entry); if (this.fees) { hash = entry.tx.hash('hex'); @@ -1353,12 +1354,12 @@ Mempool.prototype.getConfidence = function getConfidence(hash, callback) { }; /** - * Add a transaction to the mempool database. + * Map a transaction to the mempool. * @private * @param {MempoolEntry} entry */ -Mempool.prototype._addUnchecked = function _addUnchecked(entry) { +Mempool.prototype.trackEntry = function trackEntry(entry) { var tx = entry.tx; var hash = tx.hash('hex'); var i, input, output, key, coin; @@ -1368,13 +1369,12 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) { if (this.options.indexAddress) this.indexTX.addTX(tx); + assert(!tx.isCoinbase()); + for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; key = input.prevout.hash + input.prevout.index; - if (tx.isCoinbase()) - break; - assert(input.coin); if (this.options.indexAddress) @@ -1394,55 +1394,34 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) { this.coinIndex.addCoin(coin); } } + + this.totalSpent += tx.inputs.length; + this.size += this.memUsage(tx); + this.totalTX++; }; /** - * Remove a transaction from the database. Note - * that this _may_ not disconnect the inputs. - * Transactions get removed for 2 reasons: - * Either they are included in a block, - * or they are limited. - * - * - If they are limited, we want to disconnect - * the inputs and also remove all spender - * transactions along with their outputs/coins. - * - * - If they are included in a block, we do not - * disconnect the inputs (the coins have already - * been used on the blockchain-layer). We also - * do not remove spenders, since they are still - * spending valid coins that exist on the blockchain. - * + * Unmap a transaction from the mempool. * @private * @param {MempoolEntry} entry - * @param {Boolean} limit - * @param {Function} callback */ -Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit) { +Mempool.prototype.untrackEntry = function untrackEntry(entry) { var tx = entry.tx; var hash = tx.hash('hex'); var i, input, output, key, coin; - // We do not remove spenders if this is - // being removed for a block. The spenders - // are still spending valid coins (which - // now exist on the blockchain). - if (limit) - this._removeSpenders(entry); - delete this.tx[hash]; if (this.options.indexAddress) this.txIndex.removeTX(tx); + assert(!tx.isCoinbase()); + for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; key = input.prevout.hash + input.prevout.index; - if (tx.isCoinbase()) - break; - delete this.spents[key]; assert(input.coin); @@ -1462,6 +1441,10 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit) { this.coinIndex.removeCoin(coin); } } + + this.totalSpent -= tx.inputs.length; + this.size -= this.memUsage(tx); + this.totalTX--; }; /** @@ -1497,6 +1480,8 @@ Mempool.prototype.memUsage = function memUsage(tx) { var mem = 0; var i, j, input, output; + mem += 8; + mem += 8; mem += 8; for (i = 0; i < tx.inputs.length; i++) {