diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index e7129282..18af6ff5 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -89,8 +89,8 @@ function Mempool(options) { this.tx = {}; this.spents = {}; this.currentTX = null; - this.coinIndex = new AddressIndex(this); - this.txIndex = new AddressIndex(this); + this.coinIndex = new CoinIndex(this); + this.txIndex = new TXIndex(this); this.rejects = new Bloom.Rolling(120000, 0.000001); @@ -381,7 +381,6 @@ Mempool.prototype.limitOrphans = function limitOrphans() { /** * Retrieve a transaction from the mempool. - * Note that this will not be filled with coins. * @param {Hash} hash * @returns {TX} */ @@ -422,7 +421,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) { if (index >= entry.tx.outputs.length) return; - return Coin.fromTX(entry.tx, index, entry.height); + return Coin.fromTX(entry.tx, index, -1); }; /** @@ -488,7 +487,7 @@ Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addresses) { if (!hash) continue; - coin = this.coinIndex.getCoins(hash); + coin = this.coinIndex.get(hash); for (j = 0; j < coin.length; j++) coins.push(coin[j]); @@ -516,7 +515,7 @@ Mempool.prototype.getTXByAddress = function getTXByAddress(addresses) { if (!hash) continue; - tx = this.txIndex.getTX(hash); + tx = this.txIndex.get(hash); for (j = 0; j < tx.length; j++) txs.push(tx[j]); @@ -555,7 +554,6 @@ Mempool.prototype.getMetaByAddress = function getMetaByAddress(addresses) { /** * Retrieve a transaction from the mempool. - * Note that this will not be filled with coins. * @param {Hash} hash * @returns {TXMeta} */ @@ -1636,10 +1634,11 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) { var hash = tx.hash('hex'); var i, input, output, key, coin; + assert(!this.tx[hash]); this.tx[hash] = entry; if (this.options.indexAddress) - this.txIndex.addTX(tx, view); + this.txIndex.insert(tx, view); assert(!tx.isCoinbase()); @@ -1648,7 +1647,7 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) { key = input.prevout.toKey(); if (this.options.indexAddress) - this.coinIndex.removeCoin(input.prevout); + this.coinIndex.remove(input.prevout); this.spents[key] = entry; } @@ -1660,9 +1659,7 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) { if (output.script.isUnspendable()) continue; - coin = Coin.fromTX(tx, i, entry.height); - - this.coinIndex.addCoin(coin); + this.coinIndex.insert(tx, i); } } @@ -1679,12 +1676,13 @@ 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, key, coin; + var i, input, output, outpoint, key; + assert(this.tx[hash]); delete this.tx[hash]; if (this.options.indexAddress) - this.txIndex.removeTX(tx); + this.txIndex.remove(tx); assert(!tx.isCoinbase()); @@ -1693,7 +1691,7 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) { key = input.prevout.toKey(); if (this.options.indexAddress) - this.coinIndex.removeCoin(input.prevout); + this.coinIndex.remove(input.prevout); delete this.spents[key]; } @@ -1705,9 +1703,9 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) { if (output.script.isUnspendable()) continue; - coin = Coin.fromTX(tx, i, entry.height); + outpoint = Outpoint.fromTX(tx, i); - this.coinIndex.removeCoin(coin); + this.coinIndex.remove(outpoint); } } @@ -1848,22 +1846,26 @@ Mempool.prototype.getSize = function getSize() { }; /** - * Address Index + * TX Address Index */ -function AddressIndex(mempool) { +function TXIndex(mempool) { this.mempool = mempool; + + // Map of addr->txids. this.index = {}; + + // Map of txid->addrs. this.map = {}; } -AddressIndex.prototype.reset = function reset() { +TXIndex.prototype.reset = function reset() { this.index = {}; this.map = {}; }; -AddressIndex.prototype.getTX = function getTX(address) { - var items = this.index[address]; +TXIndex.prototype.get = function get(addr) { + var items = this.index[addr]; var out = []; var i, hash, tx; @@ -1880,8 +1882,8 @@ AddressIndex.prototype.getTX = function getTX(address) { return out; }; -AddressIndex.prototype.getMeta = function getMeta(address) { - var items = this.index[address]; +TXIndex.prototype.getMeta = function getMeta(addr) { + var items = this.index[addr]; var out = []; var i, hash, tx; @@ -1898,37 +1900,37 @@ AddressIndex.prototype.getMeta = function getMeta(address) { return out; }; -AddressIndex.prototype.addTX = function addTX(tx, view) { +TXIndex.prototype.insert = function insert(tx, view) { var key = tx.hash('hex'); - var hashes = tx.getHashes(view, 'hex'); - var i, hash, items; + var addrs = tx.getHashes(view, 'hex'); + var i, addr, items; - for (i = 0; i < hashes.length; i++) { - hash = hashes[i]; - items = this.index[hash]; + for (i = 0; i < addrs.length; i++) { + addr = addrs[i]; + items = this.index[addr]; if (!items) { items = []; - this.index[hash] = items; + this.index[addr] = items; } util.binaryInsert(items, tx.hash(), util.cmp); } - this.map[key] = hashes; + this.map[key] = addrs; }; -AddressIndex.prototype.removeTX = function removeTX(tx) { +TXIndex.prototype.remove = function remove(tx) { var key = tx.hash('hex'); - var hashes = this.map[key]; - var i, hash, items; + var addrs = this.map[key]; + var i, addr, items; - if (!hashes) + if (!addrs) return; - for (i = 0; i < hashes.length; i++) { - hash = hashes[i]; - items = this.index[hash]; + for (i = 0; i < addrs.length; i++) { + addr = addrs[i]; + items = this.index[addr]; if (!items) continue; @@ -1936,14 +1938,33 @@ AddressIndex.prototype.removeTX = function removeTX(tx) { util.binaryRemove(items, tx.hash(), util.cmp); if (items.length === 0) - delete this.index[hash]; + delete this.index[addr]; } delete this.map[key]; }; -AddressIndex.prototype.getCoins = function getCoins(address) { - var items = this.index[address]; +/** + * Coin Address Index + */ + +function CoinIndex(mempool) { + this.mempool = mempool; + + // Map of addr->outpoints. + this.index = {}; + + // Map of outpoint->addr. + this.map = {}; +} + +CoinIndex.prototype.reset = function reset() { + this.index = {}; + this.map = {}; +}; + +CoinIndex.prototype.get = function get(addr) { + var items = this.index[addr]; var out = []; var i, item, outpoint, coin; @@ -1961,49 +1982,51 @@ AddressIndex.prototype.getCoins = function getCoins(address) { return out; }; -AddressIndex.prototype.addCoin = function addCoin(coin) { - var key = coin.toKey(); - var hash = coin.getHash('hex'); - var outpoint, items; +CoinIndex.prototype.insert = function insert(tx, i) { + var output = tx.outputs[i]; + var addr = output.getHash('hex'); + var items, outpoint, key; - if (!hash) + if (!addr) return; - items = this.index[hash]; + items = this.index[addr]; if (!items) { items = []; - this.index[hash] = items; + this.index[addr] = items; } - outpoint = Outpoint(coin.hash, coin.index).toRaw(); - util.binaryInsert(items, outpoint, util.cmp); + outpoint = Outpoint.fromTX(tx, i); + key = outpoint.toKey(); - this.map[key] = hash; + util.binaryInsert(items, outpoint.toRaw(), util.cmp); + + this.map[key] = addr; }; -AddressIndex.prototype.removeCoin = function removeCoin(coin) { - var key = coin.toKey(); - var hash = this.map[key]; - var outpoint, items; +CoinIndex.prototype.remove = function remove(outpoint) { + var key = outpoint.toKey(); + var addr = this.map[key]; + var items; - if (!hash) + if (!addr) return; - items = this.index[hash]; + items = this.index[addr]; if (!items) return; - outpoint = Outpoint(coin.hash, coin.index).toRaw(); - util.binaryRemove(items, outpoint, util.cmp); + util.binaryRemove(items, outpoint.toRaw(), util.cmp); if (items.length === 0) - delete this.index[hash]; + delete this.index[addr]; delete this.map[key]; }; + /* * Helpers */