Mutant created against commit b821585.
+1 -1 · cpp
This description is AI generated, mistakes can be made.
Intent: Drop activated softforks out of getblocktemplate's 'rules' list and, with them, the guard in rpc/mining.cpp that refuses to serve a template to a client which has not declared support for a non-optional active rule; the template also starts signalling a bit for an already-active deployment.
Behaviour change: Original: an ACTIVE deployment appears in the template's 'rules' array and a client that did not list a non-optional rule gets 'Support for rule requires explicit client support'. Mutant: it appears in 'vbavailable' instead, rpc/mining.cpp ORs its mask into the template's nVersion (so blocks keep signalling after activation, contrary to ComputeBlockVersion), and the client-support check never fires.
Trigger: getblocktemplate on a regtest node past testdummy activation (height >= ~432): 'rules' loses 'testdummy', 'vbavailable' gains it, and the returned 'version' has bit 28 set again. On mainnet the same would happen to any future softfork after activation, including one whose gbt_optional_rule is false.
Spec violation: BIP 9 on signalling: 'Miners should continue setting the bit in LOCKED_IN phase so uptake is visible' - signalling is supposed to stop at ACTIVE, which is why ComputeBlockVersion only sets the bit for STARTED/LOCKED_IN. Also breaks getblocktemplate's documented 'rules' contract (BIP 9 / BIP 22 'rules: specific block rules that are to be enforced').
Severity if undetected: medium
Why tests miss it: grepped test/functional for vbavailable/vbrequired (no hits at all) and for 'rules' (feature_segwit.py checks the hardcoded '!segwit' entry; mining_basic.py:489 asserts the exact list ['csv','!segwit','taproot'], which passes on master only because testdummy is not ACTIVE at that height, and mutation only ever removes entries there); mining_basic.py's template 'version' assertion is made at height 200, where testdummy is STARTED
Plausibility: Three consecutive cases each doing try_emplace into a differently-named member is exactly the shape that produces a copy-paste slip, and neither map is read by any test.
Equivalence risk: Identical output until some bip9 deployment reaches ACTIVE; for optional rules (testdummy) the only differences are which JSON object the name lands in and a set bit in the template version.
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)mutant-harness operator: state; location: VersionBitsCache::GBTStatus lines 251-253
Imported from mutant-harness 6cd939b.
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.