Is there an existing issue for this?
- I have searched the existing issues
Current behaviour
Upon reorgs, the mempool has its transactions filtered near the end of every call of ActivateBestChainStep
via MaybeUpdateMempoolForReorg
: https://github.com/bitcoin/bitcoin/blob/a763497b1d6661bc5a7b8943d8f04a4459fd6827/src/validation.cpp#L3403
If the fork being activated is actually invalid this can happen:
- Chain at height
T
, with transaction in mempool which relies on height T or higher for lock validity (nsequence f.e.) - Alternative chain to height
T+1
, forking atT-1
is encountered. ActivateBestChainStep
fires once, rolling back to heightT-1
, then stopping when it attempts to validate the invalid block fork at heightT
.- Since
fBlocksDisconnected
is true,MaybeUpdateMempoolForReorg
is called at heightT-1
- Transaction is filtered due to non-final locks at height
T-1
, and function returns - Next
ActivateBestChainStep
is called, but with an empty disconnect pool, getting back to heightT
with original chain tip at step (1)
I think this can also happen if a valid reorg is longer than 32 blocks: https://github.com/bitcoin/bitcoin/blob/a763497b1d6661bc5a7b8943d8f04a4459fd6827/src/validation.cpp#L3360
Expected behaviour
Ideally, the disconnectpool would not be re-applied until the known reorg is complete.
Steps to reproduce
An example causing this was found during debugging a related fuzzing crash: #28676 (comment)
Relevant log output
No response
How did you obtain Bitcoin Core
Compiled from source
What version of Bitcoin Core are you using?
https://github.com/dergoegge/bitcoin/commit/6329ce979f63b396aa036a1ad39798bb83fa4ade
Operating system and version
Ubuntu
Machine specifications
No response