aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2022-01-03 14:34:06 +0100
committerMarcoFalke <falke.marco@gmail.com>2022-01-03 14:34:39 +0100
commit75a227e39e37d475d6088209f24f32c070071219 (patch)
tree9d6fd51fcb543b7ed2b1181ba36eae9e436193fb /src/txmempool.cpp
parentd69af93223c4008c3255f7e4848ff05d78c514fa (diff)
parentb4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b (diff)
Merge bitcoin/bitcoin#23683: bug fix: valid but different LockPoints after a reorg
b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b [bugfix] update lockpoints correctly during reorg (glozow) b6002b07a36f0d58dc6becd04bfcf78599056b7c MOVEONLY: update_lock_points to txmempool.h (glozow) Pull request description: I introduced a bug in #22677 (sorry! :sweat_smile:) Mempool entries cache `LockPoints`, containing the first height/blockhash/`CBlockIndex*` at which the transaction becomes valid. During a reorg, we re-check timelocks on all mempool entries using `CheckSequenceLocks(useExistingLockPoints=false)` and remove any now-invalid entries. `CheckSequenceLocks()` also mutates the `LockPoints` passed in, and we update valid entries' `LockPoints` using `update_lock_points`. Thus, `update_lock_points(lp)` needs to be called right after `CheckSequenceLocks(lp)`, otherwise we lose the data in `lp`. I incorrectly assumed they could be called in separate loops. The incorrect behavior introduced is: if we have a reorg in which a timelocked mempool transaction is still valid but becomes valid at a different block, the cached `LockPoints` will be incorrect. This PR fixes the bug, adds a test, and adds an assertion at the end of `removeForReorg()` to check that all mempool entries' lockpoints are valid. You can reproduce the bug by running the test added in the [test] commit on the code before the [bugfix] commit. ACKs for top commit: jnewbery: ACK b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b vasild: ACK b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b mzumsande: Code Review ACK b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b hebasto: ACK b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b MarcoFalke: re-ACK b4adc5ad6769e4a5a6179dfff271cd4c9dc47a5b 🏁 Tree-SHA512: 16b59f6ff8140d0229079ca1c6b04f2f4a00a2e49931275150e4f3fe5ac4ec109698b083fa6b223ba9511f328271cc1ab081263669d5da020af7fee83c13e401
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp15
1 files changed, 1 insertions, 14 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 66beb0a9b3..dc2769b81e 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -64,16 +64,6 @@ private:
int64_t feeDelta;
};
-struct update_lock_points
-{
- explicit update_lock_points(const LockPoints& _lp) : lp(_lp) { }
-
- void operator() (CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); }
-
-private:
- const LockPoints& lp;
-};
-
bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp)
{
AssertLockHeld(cs_main);
@@ -649,10 +639,7 @@ void CTxMemPool::removeForReorg(CChain& chain, std::function<bool(txiter)> check
}
RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG);
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
- const LockPoints lp{it->GetLockPoints()};
- if (!TestLockPointValidity(chain, lp)) {
- mapTx.modify(it, update_lock_points(lp));
- }
+ assert(TestLockPointValidity(chain, it->GetLockPoints()));
}
}