Mutant created against commit 37912ec.
+0 -1 · cpp
This mutant deletes the original lines without replacement.
This description is AI generated, mistakes can be made.
Intent: Transactions evicted by RBF replacement, expiry, size limit or block conflicts stay in every peer's reconciliation set. They are then sketched, and possibly asked for, but cannot be served. An attacker who RBF-churns cheap transactions fills sets toward MAX_RECONSET_SIZE with dead entries. That inflates sketch differences, causes decode failures, and pushes honest transactions into fanout fallback.
Behaviour change: Original: tx A replaced by B is removed from all sets, so only B is reconciled. Mutant: A and B both stay in the set. The next sketch carries A and, when we are responder and the peer asks for A's short id, AnnounceReconciliationTxs silently finds nothing in the mempool.
Trigger: Node with -txreconciliation and a registered inbound recon peer. Submit tx A, wait one trickle so A is in the peer's set, then submit an RBF replacement B. The peer sends REQTXRCNCL. The node's sketch covers 2 elements (A and B) instead of 1, and the set size the node reports includes A.
Spec violation: Comment in TransactionRemovedFromMempool: 'A transaction we can no longer serve must not stay in any reconciliation set: it would be sketched, asked for, and then dropped, wasting sketch capacity and a round trip.'
Severity if undetected: medium
Why tests miss it: p2p_txrecon_responder.py test_reconciliation_responder_mempool_removal only mines a block, which goes through MempoolTransactionsRemovedForBlock. Grepped the PR tests for replace/RBF/expiry/bumpfee near txrecon and found nothing. txreconciliation_tests.cpp calls RemoveFromSets directly.
Plausibility: A contributor who knows that mined txs arrive via MempoolTransactionsRemovedForBlock could consider this override redundant and drop the call. It looks like dead code because the tested path never exercises it.
Equivalence risk: Sets are cleared after each reconciliation round, so stale entries last at most one round. The impact is bounded but observable in the sketch and set size.
Commands and environment reported by the submitter
cmake -B build -DBUILD_GUI=OFF -DWITH_ZMQ=OFF -DENABLE_IPC=OFF && cmake --build build -j$(nproc)ctest --test-dir build -j$(nproc) && build/test/functional/test_runner.py -j$(nproc) --failfastmutant-harness operator: deletion; location: PeerManagerImpl::TransactionRemovedFromMempool lines 2265-2270
Imported from mutant-harness 474b4f7.
Commands are shown as text and never executed by MutantHub.
0 comments
No comments yet
Discuss equivalence, reproduction difficulties, or a test that kills this mutant.