Mutant created against commit 37912ec.
+0 -1 · c
This mutant deletes the original lines without replacement.
This description is AI generated, mistakes can be made.
Intent: The snapshot set keeps growing across rounds, because SnapshotLocalSet uses insert, not assignment. Failed rounds then re-announce every tx from earlier rounds, and per-peer memory grows without bound. An inbound peer can drive this by requesting reconciliation repeatedly. That is close to high, but it is bounded by real relayed txs, so medium.
Behaviour change: Original: after HandleReconcilDiff/HandleSketch, the snapshot is empty. Mutant: it keeps all txs from earlier rounds. A later failed reconciliation (GetAllTransactions(from_snapshot=true)) announces all of them, and TryRemovingFromSet/RemoveFromSets keep adding stale wtxids to m_announced_while_reconciling.
Trigger: Inbound recon peer: round 1 REQTXRCNCL, then SKETCH, then RECONCILDIFF(success). Round 2: REQTXRCNCL with set_size 0, then RECONCILDIFF(false). HandleReconcilDiff returns the round 1 txs plus the round 2 txs as INVs. Every later failed round re-announces everything ever reconciled with that peer.
Spec violation: ClearLocalSetSnapshot doc: 'Clears the snapshot of a peer's local set. To be called once the reconciliation flow has completed.' SnapshotLocalSet's Assume(m_local_set_snapshot.empty()) premise.
Severity if undetected: medium
Why tests miss it: HandleReconcilDiffTest (first round is empty, later rounds use the mapping snapshot only), RemoveFromSetsKeepsExtensionConsistentTest (extension uses m_short_id_mapping_snapshot, which is still reset by assignment), p2p_txrecon_responder.py interleaved (second round is success, so it reads the mapping snapshot)
Plausibility: This is one dropped line in a list of resets. The extension sketch and the short-ID lookups still work because they go through the mapping snapshot, which is reassigned every round, so the bug stays hidden.
Equivalence risk: Success paths read only m_short_id_mapping_snapshot, which SnapshotLocalSet reassigns, so only failed rounds, removal tracking, and memory differ. In Debug builds the Assume in SnapshotLocalSet would abort and kill it.
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: TxReconciliationState::ClearLocalSetSnapshot lines 236-243
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.