When a transaction with nSequence=0 (BIP68 relative locktime 0) enters
the mempool with an unconfirmed parent, CalculatePrevHeights assigns
nCoinHeight=tip+1 and the resulting LockPoints are cached with
maxInputBlock=genesis. After invalidateblock lowers the tip,
TestLockPointValidity returns true for genesis (always on chain),
so the stale cached lockpoints are reused. CheckSequenceLocksAtTip
then incorrectly determines the lock is not satisfied and removes
the transaction along with all its descendants.
The fix detects the genesis sentinel (maxInputBlock->nHeight==0 with
lp.height>0) in filter_final_and_mature, which indicates lockpoints
computed with mempool parent inputs, and forces fresh recalculation via
CalculateLockPointsAtTip instead of using the stale cache.
Added mempool_reorg_bip68_stale_lockpoints.py which verifies that
both BIP68-disabled and BIP68-enabled children with mempool parents
survive a multi-block reorg via invalidateblock.
Reproducer for unpatched nodes: https://gist.github.com/javierpmateos/c55d365973adbf488a852dc5e0b77dec
Same class of issue fixed for TRUC in #33504.
Closes #35007