mempool: Invert reorg transaction handling. #2956
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit inverts the order that transactions are added to the mempool during a reorg so that they are accepted into the mempool in reverse block order.
MaybeAcceptTransactions
to mempool for processing not new transactions. It expects transactions to be provided in block order, though this restriction could be relaxed as a non-breaking change if it makes sense to do so at a later time. Some reasons behind adding a new public function is toThis PR addresses a scenario where statistics that are calculated for the initial sort used during block template generation may become inaccurate after a reorg under special circumstances.
A set of unconfirmed transactions in the mempool that spends or is spent by another in the set are referred to here as a transaction chain. Consider the following transaction chain in the mempool.
Block: []
Mempool: [A <— B <— C]
A scenario is possible where the tail of the transaction chain (C) is left in the mempool while the other 2 are included in the blockchain.
Block: [A <— B]
Mempool: [C]
If a reorg occurs causing the first two transactions to re-enter the mempool, then the aggregate statistics for the transaction already in the mempool will become inaccurate due to its ancestors being added out of order. Currently, transactions are added back to the mempool in block-order.
So, when transaction A is added to the mempool, there is no path to update the descendant C’s statistics to account for it since B is neither in the mempool nor the blockchain. When transaction B is added to the mempool, its statistics are applied to C’s aggregate statistics. The problem here is that C’s aggregate statistics are missing information about A. If A is removed from the mempool, leaving C and B in the mempool, then A’s statistics would be subtracted from C’s statistics despite not having been added to those statistics during the last reorg.
The solution here is to add transactions in reverse-block order so that there is continuity in unconfirmed transaction chains from the perspective of the mining view as they are added and removed from the mempool / transaction graph.