mempool: refactor addr index.

This commit is contained in:
Christopher Jeffrey 2016-12-18 16:26:07 -08:00
parent 37770aa6df
commit 42f0b2aa19
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -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
*/