mempool: handle trimming differently.
This commit is contained in:
parent
47c1955e2c
commit
c2b8dc37c7
@ -366,39 +366,43 @@ Mempool.prototype._reset = co(function* reset() {
|
|||||||
|
|
||||||
Mempool.prototype.limitSize = function limitSize(added) {
|
Mempool.prototype.limitSize = function limitSize(added) {
|
||||||
var maxSize = this.options.maxSize;
|
var maxSize = this.options.maxSize;
|
||||||
|
var threshold = maxSize - (maxSize / 10);
|
||||||
var expiryTime = this.options.expiryTime;
|
var expiryTime = this.options.expiryTime;
|
||||||
var now = util.now();
|
var now = util.now();
|
||||||
var trimmed = false;
|
var i, queue, hashes, hash, entry, start;
|
||||||
var i, queue, entry, keys, hash, start;
|
|
||||||
|
|
||||||
if (this.size <= maxSize)
|
if (this.size <= maxSize)
|
||||||
return trimmed;
|
return false;
|
||||||
|
|
||||||
queue = new Heap(cmpRate);
|
queue = new Heap(cmpRate);
|
||||||
keys = this.getSnapshot();
|
hashes = this.getSnapshot();
|
||||||
|
|
||||||
start = util.hrtime();
|
start = util.hrtime();
|
||||||
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
for (i = 0; i < hashes.length; i++) {
|
||||||
hash = keys[i];
|
hash = hashes[i];
|
||||||
entry = this.getEntry(hash);
|
entry = this.getEntry(hash);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (this.hasDepends(entry.tx))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (now < entry.ts + expiryTime) {
|
if (now < entry.ts + expiryTime) {
|
||||||
queue.insert(entry);
|
queue.insert(entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry === added)
|
this.logger.debug(
|
||||||
trimmed = true;
|
'Removing package %s from mempool (too old).',
|
||||||
|
entry.txid());
|
||||||
|
|
||||||
this.evictEntry(entry);
|
this.evictEntry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.size <= maxSize)
|
if (this.size <= threshold)
|
||||||
return trimmed;
|
return !this.hasEntry(added);
|
||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'(bench) Heap mempool traversal: %d.',
|
'(bench) Heap mempool traversal: %d.',
|
||||||
@ -406,19 +410,23 @@ Mempool.prototype.limitSize = function limitSize(added) {
|
|||||||
|
|
||||||
start = util.hrtime();
|
start = util.hrtime();
|
||||||
|
|
||||||
|
this.logger.debug(
|
||||||
|
'(bench) Heap mempool queue size: %d.',
|
||||||
|
queue.size());
|
||||||
|
|
||||||
while (queue.size() > 0) {
|
while (queue.size() > 0) {
|
||||||
entry = queue.shift();
|
entry = queue.shift();
|
||||||
hash = entry.hash('hex');
|
hash = entry.hash('hex');
|
||||||
|
|
||||||
if (!this.hasEntry(hash))
|
assert(this.hasEntry(hash));
|
||||||
continue;
|
|
||||||
|
this.logger.debug(
|
||||||
|
'Removing package %s from mempool (low fee).',
|
||||||
|
entry.txid());
|
||||||
|
|
||||||
this.evictEntry(entry);
|
this.evictEntry(entry);
|
||||||
|
|
||||||
if (entry === added)
|
if (this.size <= threshold)
|
||||||
trimmed = true;
|
|
||||||
|
|
||||||
if (this.size <= maxSize - (maxSize / 10))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +434,7 @@ Mempool.prototype.limitSize = function limitSize(added) {
|
|||||||
'(bench) Heap mempool map removal: %d.',
|
'(bench) Heap mempool map removal: %d.',
|
||||||
util.hrtime(start));
|
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);
|
yield this.addEntry(entry, view);
|
||||||
|
|
||||||
// Trim size if we're too big.
|
// Trim size if we're too big.
|
||||||
if (this.limitSize(entry)) {
|
if (this.limitSize(hash)) {
|
||||||
throw new VerifyError(tx,
|
throw new VerifyError(tx,
|
||||||
'insufficientfee',
|
'insufficientfee',
|
||||||
'mempool full',
|
'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.
|
* Recursively remove its spenders.
|
||||||
* @param {MempoolEntry} entry
|
* @param {MempoolEntry} entry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Mempool.prototype.evictEntry = function evictEntry(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.removeSpenders(entry);
|
||||||
this.updateAncestors(entry, removeFee);
|
this.updateAncestors(entry, removeFee);
|
||||||
|
|
||||||
this.removeEntry(entry);
|
this.removeEntry(entry);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1388,6 +1391,25 @@ Mempool.prototype.getDepends = function getDepends(tx) {
|
|||||||
return depends;
|
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
|
* Return the full balance of all unspents in the mempool
|
||||||
* (not very useful in practice, only used for testing).
|
* (not very useful in practice, only used for testing).
|
||||||
@ -1900,7 +1922,7 @@ Mempool.prototype.removeDoubleSpends = function removeDoubleSpends(tx) {
|
|||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'Removing double spender from mempool: %s.',
|
'Removing double spender from mempool: %s.',
|
||||||
spent.tx.rhash());
|
spent.txid());
|
||||||
|
|
||||||
this.evictEntry(spent);
|
this.evictEntry(spent);
|
||||||
|
|
||||||
|
|||||||
@ -142,6 +142,15 @@ MempoolEntry.prototype.hash = function hash(enc) {
|
|||||||
return this.tx.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
|
* Calculate priority, taking into account
|
||||||
* the entry height delta, modified size,
|
* the entry height delta, modified size,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user