txdb: fix double spends and replace by fee.

This commit is contained in:
Christopher Jeffrey 2016-10-23 14:52:25 -07:00
parent 0c85aeae44
commit 6e1c4d27b5
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -1027,10 +1027,6 @@ TXDB.prototype._add = co(function* add(tx, block) {
}
if (tx.height === -1) {
// We ignore double spends from the mempool.
if (yield this.isDoubleSpend(tx))
return;
// We ignore any unconfirmed txs
// that are replace-by-fee.
if (yield this.isRBF(tx)) {
@ -1040,12 +1036,17 @@ TXDB.prototype._add = co(function* add(tx, block) {
this.put(layout.r(hash), DUMMY);
return;
}
} else {
// Potentially remove double-spenders.
yield this.removeConflicts(tx);
// Potentially remove double-spenders.
// Only remove if they're not confirmed.
if (!(yield this.removeConflicts(tx, true)))
return;
} else {
// Delete the replace-by-fee record.
this.del(layout.r(hash));
// Potentially remove double-spenders.
yield this.removeConflicts(tx, false);
}
// Finally we can do a regular insertion.
@ -1353,6 +1354,9 @@ TXDB.prototype._confirm = co(function* confirm(tx, block) {
this.saveCredit(credit, path);
}
// Remove the RBF index if we have one.
this.del(layout.r(hash));
// Save the new serialized transaction as
// the block-related properties have been
// updated. Also reindex for height.
@ -1473,6 +1477,9 @@ TXDB.prototype.erase = co(function* erase(tx) {
this.removeCredit(credit, path);
}
// Remove the RBF index if we have one.
this.del(layout.r(hash));
// Remove the transaction data
// itself as well as unindex.
this.del(layout.t(hash));
@ -1735,13 +1742,15 @@ TXDB.prototype.removeConflict = co(function* removeConflict(hash, ref) {
* @returns {Promise}
*/
TXDB.prototype.removeConflicts = co(function* removeConflicts(tx) {
TXDB.prototype.removeConflicts = co(function* removeConflicts(tx, conf) {
var hash = tx.hash('hex');
var spends = [];
var i, input, prevout, spent;
if (tx.isCoinbase())
return;
return true;
// Gather all spent records first.
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
@ -1756,9 +1765,26 @@ TXDB.prototype.removeConflicts = co(function* removeConflicts(tx) {
if (spent.hash === hash)
continue;
if (conf && tx.height !== -1)
return false;
spends[i] = spent;
}
// Once we know we're not going to
// screw things up, remove the double
// spenders.
for (i = 0; i < tx.inputs.length; i++) {
spent = spends[i];
if (!spent)
continue;
// Remove the double spender.
yield this.removeConflict(spent.hash, tx);
}
return true;
});
/**