mempool: refactor indexing.

This commit is contained in:
Christopher Jeffrey 2016-12-18 19:35:38 -08:00
parent 01f21b0399
commit 97ecd5c59f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -85,7 +85,7 @@ function Mempool(options) {
this.waiting = {}; this.waiting = {};
this.orphans = {}; this.orphans = {};
this.tx = {}; this.map = {};
this.spents = {}; this.spents = {};
this.currentTX = null; this.currentTX = null;
this.coinIndex = new CoinIndex(this); this.coinIndex = new CoinIndex(this);
@ -289,7 +289,7 @@ Mempool.prototype._reset = function reset() {
this.waiting = {}; this.waiting = {};
this.orphans = {}; this.orphans = {};
this.tx = {}; this.map = {};
this.spents = {}; this.spents = {};
this.coinIndex.reset(); this.coinIndex.reset();
this.txIndex.reset(); this.txIndex.reset();
@ -385,7 +385,7 @@ Mempool.prototype.limitOrphans = function limitOrphans() {
*/ */
Mempool.prototype.getTX = function getTX(hash) { Mempool.prototype.getTX = function getTX(hash) {
var entry = this.tx[hash]; var entry = this.map[hash];
if (!entry) if (!entry)
return; return;
return entry.tx; return entry.tx;
@ -398,7 +398,7 @@ Mempool.prototype.getTX = function getTX(hash) {
*/ */
Mempool.prototype.getEntry = function getEntry(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) { Mempool.prototype.getCoin = function getCoin(hash, index) {
var entry = this.tx[hash]; var entry = this.map[hash];
if (!entry) if (!entry)
return; return;
@ -577,7 +577,7 @@ Mempool.prototype.getMeta = function getMeta(hash) {
*/ */
Mempool.prototype.hasTX = function hasTX(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() { 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) { Mempool.prototype.trackEntry = function trackEntry(entry, view) {
var tx = entry.tx; var tx = entry.tx;
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var i, input, output, key; var i, input, key;
assert(!this.tx[hash]); assert(!this.map[hash]);
this.tx[hash] = entry; this.map[hash] = entry;
if (this.options.indexAddress)
this.txIndex.insert(tx, view);
assert(!tx.isCoinbase()); assert(!tx.isCoinbase());
for (i = 0; i < tx.inputs.length; i++) { for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i]; input = tx.inputs[i];
key = input.prevout.toKey(); key = input.prevout.toKey();
if (this.options.indexAddress)
this.coinIndex.remove(input.prevout);
this.spents[key] = entry; this.spents[key] = entry;
} }
if (this.options.indexAddress) { if (this.options.indexAddress)
for (i = 0; i < tx.outputs.length; i++) { this.indexEntry(entry, view);
output = tx.outputs[i];
if (output.script.isUnspendable())
continue;
this.coinIndex.insert(tx, i);
}
}
this.size += this.memUsage(tx); this.size += this.memUsage(tx);
this.totalTX++; this.totalTX++;
@ -1676,43 +1661,78 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) {
Mempool.prototype.untrackEntry = function untrackEntry(entry) { Mempool.prototype.untrackEntry = function untrackEntry(entry) {
var tx = entry.tx; var tx = entry.tx;
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var i, input, output, outpoint, key; var i, input, key;
assert(this.tx[hash]); assert(this.map[hash]);
delete this.tx[hash]; delete this.map[hash];
if (this.options.indexAddress)
this.txIndex.remove(tx);
assert(!tx.isCoinbase()); assert(!tx.isCoinbase());
for (i = 0; i < tx.inputs.length; i++) { for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i]; input = tx.inputs[i];
key = input.prevout.toKey(); key = input.prevout.toKey();
if (this.options.indexAddress)
this.coinIndex.remove(input.prevout);
delete this.spents[key]; delete this.spents[key];
} }
if (this.options.indexAddress) { if (this.options.indexAddress)
for (i = 0; i < tx.outputs.length; i++) { this.unindexEntry(entry);
output = tx.outputs[i];
if (output.script.isUnspendable())
continue;
outpoint = Outpoint.fromTX(tx, i);
this.coinIndex.remove(outpoint);
}
}
this.size -= this.memUsage(tx); this.size -= this.memUsage(tx);
this.totalTX--; 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. * Recursively remove spenders of a transaction.
* @private * @private
@ -2020,7 +2040,6 @@ CoinIndex.prototype.remove = function remove(outpoint) {
delete this.map[key]; delete this.map[key];
}; };
/* /*
* Helpers * Helpers
*/ */