@TheBlueMatt This is a rebased version of #6656 (which in turn built off #6595).
As previously reported in #6595, there’s currently a bug where we don’t remove transactions that become invalid after a reorg due to the transaction’s locktime. The solution proposed in #6595 doesn’t exhibit great behavior because it doesn’t make sense to evict locktime-invalid transactions in the middle of a reorg before the new tip is updated (since typically the block height is the same or greater at the end); @TheBlueMatt addressed this in #6656, which is rebased and included here.
I have also added a commit that vastly improves the efficiency of CTxMemPool::removeForReorg()
, by tracking in each mempool entry whether or not the transaction spends a coinbase. Then in removeForReorg()
, we only access coins for those transactions that spend a coinbase, instead of looking up all inputs for all transactions in the mempool (which is slow and blows up the UTXO cache).
I compared this code with and without this last commit on some historical data, and observed that this drastically improves runtime of removeForReorg()
and reduces memory usage in pcoinsTip
. Running this code on historical data on a few days in July, I observed 4 reorgs, and the runtime of removeForReorg()
went from ranging between 167ms - 719ms down to between 5.5ms-16ms; meanwhile pcoinsTip
memory usage (after the call to removeForReorg()
) was reduced by between 144MB - 413MB.
When BIP68 support is merged we’ll probably want to update this approach, since IsFinalTx()
will become a more expensive function that needs to look at inputs.