From 703a89cc59c4382490bab6246a792147dc87d66f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 31 Mar 2016 20:39:47 -0700 Subject: [PATCH] more mempool work. --- lib/bcoin/mempool.js | 90 +++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 21 deletions(-) diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index 9157dea7..f86d8690 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -581,11 +581,11 @@ Mempool.prototype.addTX = function addTX(tx, callback, force) { }; function AddressMap() { - this.map = {}; + this.map = { tx: {}, coin: {} }; } AddressMap.prototype.getTX = function getTX(address) { - var map = this.map[address]; + var map = this.map.tx[address]; var keys = []; var i, key; @@ -594,8 +594,7 @@ AddressMap.prototype.getTX = function getTX(address) { for (i = 0; i < map.length; i++) { key = map[i]; - if (key.length !== 32) - continue; + assert(key.length === 32); keys.push(key.toString('hex')); } @@ -603,7 +602,7 @@ AddressMap.prototype.getTX = function getTX(address) { }; AddressMap.prototype.getCoins = function getCoins(address) { - var map = this.map[address]; + var map = this.map.coin[address]; var keys = []; var i, p, key; @@ -613,8 +612,7 @@ AddressMap.prototype.getCoins = function getCoins(address) { for (i = 0; i < map.length; i++) { key = map[i]; - if (key.length !== 36) - continue; + assert(key.length === 36); p = new BufferReader(key); p.start(); @@ -640,9 +638,9 @@ AddressMap.prototype.addTX = function addTX(tx) { for (i = 0; i < addresses.length; i++) { address = addresses[i]; - if (!this.map[address]) - this.map[address] = []; - map = this.map[address]; + if (!this.map.tx[address]) + this.map.tx[address] = []; + map = this.map.tx[address]; index = binarySearch(map, hash, true); map.splice(index + 1, 0, hash); } @@ -682,14 +680,14 @@ AddressMap.prototype.removeTX = function removeTX(tx) { for (i = 0; i < addresses.length; i++) { address = addresses[i]; - map = this.map[address]; + map = this.map.tx[address]; if (map) { index = binarySearch(map, hash); if (index !== -1) map.splice(index, 1); if (map.length === 0) - delete this.map[address]; + delete this.map.tx[address]; } } }; @@ -700,9 +698,9 @@ AddressMap.prototype.addCoin = function addCoin(coin) { var map, index; if (address) { - if (!this.map[address]) - this.map[address] = []; - map = this.map[address]; + if (!this.map.coin[address]) + this.map.coin[address] = []; + map = this.map.coin[address]; index = binarySearch(map, key, true); map.splice(index + 1, 0, key); } @@ -726,14 +724,14 @@ AddressMap.prototype.removeCoin = function removeCoin(tx, i) { key = this._coinKey(tx.hash(), i); } - map = this.map[address]; + map = this.map.coin[address]; if (map) { index = binarySearch(map, key); if (index !== -1) map.splice(index, 1); if (map.length === 0) - delete this.map[address]; + delete this.map.coin[address]; } }; @@ -756,8 +754,8 @@ Mempool.prototype.addUnchecked = function addUnchecked(tx, callback) { for (i = 0; i < tx.outputs.length; i++) { output = tx.outputs[i]; + key = hash + '/' + i; coin = bcoin.coin(tx, i); - key = coin.hash + '/' + coin.index; this.coins[key] = coin.toRaw(); this.addressMap.addCoin(coin); } @@ -804,7 +802,12 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(tx, callback) { hash = tx.hash('hex'); delete this.txs[hash]; - delete this.orphans[hash]; + + try { + this.removeOrphanSync(hash); + } catch (e) { + return callback(e); + } this.addressMap.removeTX(tx); @@ -830,6 +833,51 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(tx, callback) { return callback(); }; +Mempool.prototype.removeOrphanSync = function removeOrphanSync(tx) { + var prevout, i, hex, hash, prev, index; + + if (typeof tx === 'string') + tx = this.getOrphanSync(tx); + + hash = tx.hash(); + hex = hash.toString('hex'); + prevout = tx.getPrevout(); + + if (!this.orphans[hex]) + return false; + + delete this.orphans[hex]; + + for (i = 0; i < prevout.length; i++) { + prev = prevout[i]; + if (!this.waiting[prev]) + continue; + // TODO BINARY SEARCH/INSERT + index = utils.indexOf(this.waiting[prev], hash); + if (index !== -1) { + this.waiting[prev].splice(index, 1); + if (this.waiting[prev].length === 0) + delete this.waiting[prev]; + } + } + + return true; +}; + +Mempool.prototype.removeOrphan = function removeOrphan(tx, callback) { + var ret; + + callback = utils.asyncify(callback); + + try { + ret = this.removeOrphanSync(tx); + } catch (e) { + return callback(e); + } + + return callback(null, ret); +}; + Mempool.prototype.verify = function verify(tx, callback) { var self = this; var height = this.chain.height + 1; @@ -962,14 +1010,14 @@ Mempool.prototype.countAncestorsSync = function countAncestorsSync(tx) { for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; - prev = self.getTXSync(input.prevout.hash); + prev = this.getTXSync(input.prevout.hash); inputs[i] = 0; if (!prev) continue; inputs[i] += 1; - inputs[i] += self.countAncestorsSync(prev); + inputs[i] += this.countAncestorsSync(prev); } return inputs.sort().pop();