From 97ecd5c59fb811a6f06bc76e5d1c8814c32ca8d0 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 18 Dec 2016 19:35:38 -0800 Subject: [PATCH] mempool: refactor indexing. --- lib/mempool/mempool.js | 119 ++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index bbe6870a..6453879e 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -85,7 +85,7 @@ function Mempool(options) { this.waiting = {}; this.orphans = {}; - this.tx = {}; + this.map = {}; this.spents = {}; this.currentTX = null; this.coinIndex = new CoinIndex(this); @@ -289,7 +289,7 @@ Mempool.prototype._reset = function reset() { this.waiting = {}; this.orphans = {}; - this.tx = {}; + this.map = {}; this.spents = {}; this.coinIndex.reset(); this.txIndex.reset(); @@ -385,7 +385,7 @@ Mempool.prototype.limitOrphans = function limitOrphans() { */ Mempool.prototype.getTX = function getTX(hash) { - var entry = this.tx[hash]; + var entry = this.map[hash]; if (!entry) return; return entry.tx; @@ -398,7 +398,7 @@ Mempool.prototype.getTX = function getTX(hash) { */ Mempool.prototype.getEntry = function getEntry(hash) { - return this.tx[hash]; + return this.map[hash]; }; /** @@ -409,7 +409,7 @@ Mempool.prototype.getEntry = function getEntry(hash) { */ Mempool.prototype.getCoin = function getCoin(hash, index) { - var entry = this.tx[hash]; + var entry = this.map[hash]; if (!entry) return; @@ -577,7 +577,7 @@ Mempool.prototype.getMeta = function getMeta(hash) { */ Mempool.prototype.hasTX = function hasTX(hash) { - return this.tx[hash] != null; + return this.map[hash] != null; }; /** @@ -1596,7 +1596,7 @@ Mempool.prototype.findMissing = function findMissing(tx, view) { */ Mempool.prototype.getSnapshot = function getSnapshot() { - return Object.keys(this.tx); + return Object.keys(this.map); }; /** @@ -1632,36 +1632,21 @@ Mempool.prototype.verifyFinal = function verifyFinal(tx, flags) { Mempool.prototype.trackEntry = function trackEntry(entry, view) { var tx = entry.tx; var hash = tx.hash('hex'); - var i, input, output, key; + var i, input, key; - assert(!this.tx[hash]); - this.tx[hash] = entry; - - if (this.options.indexAddress) - this.txIndex.insert(tx, view); + assert(!this.map[hash]); + this.map[hash] = entry; assert(!tx.isCoinbase()); for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; key = input.prevout.toKey(); - - if (this.options.indexAddress) - this.coinIndex.remove(input.prevout); - this.spents[key] = entry; } - if (this.options.indexAddress) { - for (i = 0; i < tx.outputs.length; i++) { - output = tx.outputs[i]; - - if (output.script.isUnspendable()) - continue; - - this.coinIndex.insert(tx, i); - } - } + if (this.options.indexAddress) + this.indexEntry(entry, view); this.size += this.memUsage(tx); this.totalTX++; @@ -1676,43 +1661,78 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) { Mempool.prototype.untrackEntry = function untrackEntry(entry) { var tx = entry.tx; var hash = tx.hash('hex'); - var i, input, output, outpoint, key; + var i, input, key; - assert(this.tx[hash]); - delete this.tx[hash]; - - if (this.options.indexAddress) - this.txIndex.remove(tx); + assert(this.map[hash]); + delete this.map[hash]; assert(!tx.isCoinbase()); for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; key = input.prevout.toKey(); - - if (this.options.indexAddress) - this.coinIndex.remove(input.prevout); - delete this.spents[key]; } - if (this.options.indexAddress) { - for (i = 0; i < tx.outputs.length; i++) { - output = tx.outputs[i]; - - if (output.script.isUnspendable()) - continue; - - outpoint = Outpoint.fromTX(tx, i); - - this.coinIndex.remove(outpoint); - } - } + if (this.options.indexAddress) + this.unindexEntry(entry); this.size -= this.memUsage(tx); this.totalTX--; }; +/** + * Index an entry by address. + * @private + * @param {MempoolEntry} entry + * @param {CoinView} view + */ + +Mempool.prototype.indexEntry = function indexEntry(entry, view) { + var tx = entry.tx; + var i, input; + + this.txIndex.insert(tx, view); + + for (i = 0; i < tx.inputs.length; i++) { + input = tx.inputs[i]; + this.coinIndex.remove(input.prevout); + } + + for (i = 0; i < tx.outputs.length; i++) + this.coinIndex.insert(tx, i); +}; + +/** + * Unindex an entry by address. + * @private + * @param {MempoolEntry} entry + */ + +Mempool.prototype.unindexEntry = function unindexEntry(entry) { + var tx = entry.tx; + var hash = tx.hash('hex'); + var i, input, prevout, prev, key; + + this.txIndex.remove(tx); + + for (i = 0; i < tx.inputs.length; i++) { + input = tx.inputs[i]; + prevout = input.prevout.hash; + prev = this.getTX(prevout.hash); + + if (!prev) + continue; + + this.coinIndex.insert(prev, prevout.index); + } + + for (i = 0; i < tx.outputs.length; i++) { + prevout = Outpoint.fromTX(tx, i); + this.coinIndex.remove(prevout); + } +}; + /** * Recursively remove spenders of a transaction. * @private @@ -2020,7 +2040,6 @@ CoinIndex.prototype.remove = function remove(outpoint) { delete this.map[key]; }; - /* * Helpers */