From b0caa3f03aeaf39e698ab97c0fddc19cf8009e9e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Aug 2016 17:27:11 -0700 Subject: [PATCH] mempool: keep everything on the js heap. --- lib/bcoin/mempool.js | 118 +++++++++++++------------------------------ lib/bcoin/pool.js | 2 +- 2 files changed, 35 insertions(+), 85 deletions(-) diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index 021a7341..cc6826cf 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -87,7 +87,6 @@ function Mempool(options) { this.total = 0; this.tx = {}; this.spents = {}; - this.coins = {}; this.time = new RBT(timeCmp); this.coinIndex = new AddressIndex(this); this.txIndex = new AddressIndex(this); @@ -325,22 +324,11 @@ Mempool.prototype.limitOrphans = function limitOrphans() { * @param {Function} callback - Returns [Error, {@link TX}]. */ -Mempool.prototype.getTX = function getTX(hash, callback) { - var data = this.tx[hash]; - var tx; - - if (!data) +Mempool.prototype.getTX = function getTX(hash) { + var entry = this.tx[hash]; + if (!entry) return; - - try { - tx = bcoin.tx.fromRaw(data); - } catch (e) { - delete this.tx[hash]; - this.logger.warning('Possible memory corruption.'); - return; - } - - return tx; + return entry.tx; }; /** @@ -350,22 +338,8 @@ Mempool.prototype.getTX = function getTX(hash, callback) { * @param {Function} callback - Returns [Error, {@link TX}]. */ -Mempool.prototype.getEntry = function getEntry(hash, callback) { - var data = this.tx[hash]; - var tx; - - if (!data) - return; - - try { - tx = MempoolEntry.fromRaw(data); - } catch (e) { - delete this.tx[hash]; - this.logger.warning('Possible memory corruption.'); - return; - } - - return tx; +Mempool.prototype.getEntry = function getEntry(hash) { + return this.tx[hash]; }; /** @@ -375,25 +349,19 @@ Mempool.prototype.getEntry = function getEntry(hash, callback) { * @param {Function} callback - Returns [Error, {@link Coin}]. */ -Mempool.prototype.getCoin = function getCoin(hash, index, callback) { - var key = hash + index; - var data = this.coins[key]; - var coin; +Mempool.prototype.getCoin = function getCoin(hash, index) { + var entry = this.tx[hash]; - if (!data) + if (!entry) return; - try { - coin = bcoin.coin.fromRaw(data); - coin.hash = hash; - coin.index = index; - } catch (e) { - delete this.coins[key]; - this.logger.warning('Possible memory corruption.'); + if (this.isSpent(hash, index)) return; - } - return coin; + if (index >= entry.tx.outputs.length) + return; + + return bcoin.coin.fromTX(entry.tx, index); }; /** @@ -406,23 +374,9 @@ Mempool.prototype.getCoin = function getCoin(hash, index, callback) { * @param {Function} callback - Returns [Error, Boolean]. */ -Mempool.prototype.isSpent = function isSpent(hash, index, callback) { +Mempool.prototype.isSpent = function isSpent(hash, index) { var key = hash + index; - var data = this.spents[key]; - var spender; - - if (!data) - return; - - try { - spender = bcoin.outpoint.fromRaw(data); - } catch (e) { - delete this.spents[key]; - this.logger.warning('Possible memory corruption.'); - return; - } - - return spender; + return this.spents[key]; }; /** @@ -545,7 +499,7 @@ Mempool.prototype.fillCoins = function fillCoins(tx) { * @param {Function} callback - Returns [Error, Boolean]. */ -Mempool.prototype.hasTX = function hasTX(hash, callback) { +Mempool.prototype.hasTX = function hasTX(hash) { return this.tx[hash] != null; }; @@ -555,7 +509,7 @@ Mempool.prototype.hasTX = function hasTX(hash, callback) { * @param {Function} callback - Returns [Error, {@link TX}[]]. */ -Mempool.prototype.getRange = function getRange(start, end, callback) { +Mempool.prototype.getRange = function getRange(start, end) { var items = this.time.range(start, end); var entries = []; var i, item, hash, entry; @@ -1107,15 +1061,20 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx) { * (not very useful in practice, only used for testing). */ -Mempool.prototype.getBalance = function getBalance(callback) { - var keys = Object.keys(this.coins); +Mempool.prototype.getBalance = function getBalance() { + var keys = Object.keys(this.tx); var total = 0; - var i, key, data; + var i, j, key, tx, hash, coin; for (i = 0; i < keys.length; i++) { key = keys[i]; - data = this.coins[key]; - total += utils.read64N(data, 8); + tx = this.tx[key].tx; + hash = tx.hash('hex'); + for (j = 0; j < tx.outputs.length; j++) { + coin = this.getCoin(hash, j); + if (coin) + total += coin.value; + } } return total; @@ -1126,7 +1085,7 @@ Mempool.prototype.getBalance = function getBalance(callback) { * @param {Function} callback - Returns [Error, {@link TX}[]]. */ -Mempool.prototype.getHistory = function getHistory(callback) { +Mempool.prototype.getHistory = function getHistory() { var keys = Object.keys(this.tx); var txs = []; var i, key, tx; @@ -1431,7 +1390,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) { var hash = tx.hash('hex'); var i, input, output, key, coin, spender; - this.tx[hash] = entry.toRaw(); + this.tx[hash] = entry; this.time.insert(entry.ts, hash); if (this.options.indexAddress) @@ -1449,10 +1408,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) { if (this.options.indexAddress) this.coinIndex.removeCoin(input.coin); - spender = bcoin.outpoint.fromTX(tx, i).toRaw(); - - delete this.coins[key]; - this.spents[key] = spender; + this.spents[key] = bcoin.outpoint.fromTX(tx, i); } for (i = 0; i < tx.outputs.length; i++) { @@ -1462,12 +1418,10 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) { if (output.script.isUnspendable()) continue; - coin = bcoin.coin.fromTX(tx, i); - - if (this.options.indexAddress) + if (this.options.indexAddress) { + coin = bcoin.coin.fromTX(tx, i); this.coinIndex.addCoin(coin); - - this.coins[key] = coin.toRaw(); + } } }; @@ -1534,8 +1488,6 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit, cal if (self.options.indexAddress) self.coinIndex.removeCoin(input.coin); - - self.coins[key] = input.coin.toRaw(); } for (i = 0; i < tx.outputs.length; i++) { @@ -1549,8 +1501,6 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit, cal coin = bcoin.coin.fromTX(tx, i); self.coinIndex.removeCoin(coin); } - - delete self.coins[key]; } return callback(); diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 11b09d11..fe914766 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -1539,7 +1539,7 @@ Pool.prototype.has = function has(type, hash, force, callback) { } else { // If we recently rejected this item. Ignore. if (self.rejects.test(hash, 'hex')) { - self.logger.debug('Peer sent a known reject: %s.', utils.revHex(hash)); + self.logger.spam('Peer sent a known reject: %s.', utils.revHex(hash)); return callback(null, true); } }