mempool: handle trimming differently.

This commit is contained in:
Christopher Jeffrey 2017-03-05 10:27:12 -08:00
parent 47c1955e2c
commit c2b8dc37c7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 56 additions and 25 deletions

View File

@ -366,39 +366,43 @@ Mempool.prototype._reset = co(function* reset() {
Mempool.prototype.limitSize = function limitSize(added) {
var maxSize = this.options.maxSize;
var threshold = maxSize - (maxSize / 10);
var expiryTime = this.options.expiryTime;
var now = util.now();
var trimmed = false;
var i, queue, entry, keys, hash, start;
var i, queue, hashes, hash, entry, start;
if (this.size <= maxSize)
return trimmed;
return false;
queue = new Heap(cmpRate);
keys = this.getSnapshot();
hashes = this.getSnapshot();
start = util.hrtime();
for (i = 0; i < keys.length; i++) {
hash = keys[i];
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
entry = this.getEntry(hash);
if (!entry)
continue;
if (this.hasDepends(entry.tx))
continue;
if (now < entry.ts + expiryTime) {
queue.insert(entry);
continue;
}
if (entry === added)
trimmed = true;
this.logger.debug(
'Removing package %s from mempool (too old).',
entry.txid());
this.evictEntry(entry);
}
if (this.size <= maxSize)
return trimmed;
if (this.size <= threshold)
return !this.hasEntry(added);
this.logger.debug(
'(bench) Heap mempool traversal: %d.',
@ -406,19 +410,23 @@ Mempool.prototype.limitSize = function limitSize(added) {
start = util.hrtime();
this.logger.debug(
'(bench) Heap mempool queue size: %d.',
queue.size());
while (queue.size() > 0) {
entry = queue.shift();
hash = entry.hash('hex');
if (!this.hasEntry(hash))
continue;
assert(this.hasEntry(hash));
this.logger.debug(
'Removing package %s from mempool (low fee).',
entry.txid());
this.evictEntry(entry);
if (entry === added)
trimmed = true;
if (this.size <= maxSize - (maxSize / 10))
if (this.size <= threshold)
break;
}
@ -426,7 +434,7 @@ Mempool.prototype.limitSize = function limitSize(added) {
'(bench) Heap mempool map removal: %d.',
util.hrtime(start));
return trimmed;
return !this.hasEntry(added);
};
/**
@ -877,7 +885,7 @@ Mempool.prototype.insertTX = co(function* insertTX(tx) {
yield this.addEntry(entry, view);
// Trim size if we're too big.
if (this.limitSize(entry)) {
if (this.limitSize(hash)) {
throw new VerifyError(tx,
'insufficientfee',
'mempool full',
@ -1132,19 +1140,14 @@ Mempool.prototype.removeEntry = function removeEntry(entry) {
};
/**
* Evict a transaction from the mempool.
* Remove a transaction from the mempool.
* Recursively remove its spenders.
* @param {MempoolEntry} entry
*/
Mempool.prototype.evictEntry = function evictEntry(entry) {
var tx = entry.tx;
this.logger.debug('Evicting %s from the mempool.', tx.txid());
this.removeSpenders(entry);
this.updateAncestors(entry, removeFee);
this.removeEntry(entry);
};
@ -1388,6 +1391,25 @@ Mempool.prototype.getDepends = function getDepends(tx) {
return depends;
};
/**
* Test whether a transaction has dependencies.
* @param {TX} tx
* @returns {Boolean}
*/
Mempool.prototype.hasDepends = function hasDepends(tx) {
var i, input, hash;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
hash = input.prevout.hash;
if (this.hasEntry(hash))
return true;
}
return false;
};
/**
* Return the full balance of all unspents in the mempool
* (not very useful in practice, only used for testing).
@ -1900,7 +1922,7 @@ Mempool.prototype.removeDoubleSpends = function removeDoubleSpends(tx) {
this.logger.debug(
'Removing double spender from mempool: %s.',
spent.tx.rhash());
spent.txid());
this.evictEntry(spent);

View File

@ -142,6 +142,15 @@ MempoolEntry.prototype.hash = function hash(enc) {
return this.tx.hash(enc);
};
/**
* Calculate reverse transaction hash.
* @returns {Hash}
*/
MempoolEntry.prototype.txid = function txid() {
return this.tx.txid();
};
/**
* Calculate priority, taking into account
* the entry height delta, modified size,