Version-based soft-fork signaling stops working at block 2,000,000 — IsSuperMajority reads the raw nVersion, chain ID and all #40
Labels
No labels
do-not-open-till-X-Day
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
SubGeniusFinance/dobbscoin-source#40
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while verifying the AuxPoW fork on regtest (see
qa/auxpow-smoke/, commit47cb4fcc). Not a live bug — a mechanism that breaks on a known date.The facts
CBlockIndex::IsSuperMajority(src/main.cpp:2846) counts a block as signalingsupport with a raw comparison:
From
HARDFORK_AUXPOW_MAIN(block 2,000,000) every block carries the chain ID inthe high half of the version field. Measured on regtest past the fork: blocks are
0x00b00003= 11,534,339 (or0x00b00103when merge-mined).CPureBlockHeader::GetBaseVersion()exists for exactly this problem — it returnsnVersion % VERSION_AUXPOW, i.e. 3 — and it is never called anywhere insrc/. Every block-version comparison inmain.cpp(lines 1799, 2716, 2724,2745) uses the raw field.
So from block 2,000,000:
IsSuperMajority(2, …)IsSuperMajority(3, …)IsSuperMajority(4, …)IsSuperMajority(9, …)Every post-fork block counts as signaling support for every version, forever.
Why this is not a bug today
Nothing currently deploys above v3. BIP34 (v2) and BIP66 (v3) are long since
active and their gates stay true, so their behaviour is unchanged. The
reject-outdated checks at 2716 and 2724 become unreachable post-fork, but the
chain-ID rule already rejects anything that would have tripped them.
There is no BIP9 / versionbits in this tree.
IsSuperMajorityis the onlysoft-fork deployment mechanism we have.
Why it matters anyway
The next version-gated soft fork would activate spuriously and immediately at
block 2,000,000, with no miner having signaled anything.
That is not hypothetical. BIP65 / CHECKLOCKTIMEVERIFY — issue #34, the thing
atomic swaps need — is deployed exactly this way, as
IsSuperMajority(4, …).Written the obvious way, copying the BIP66 line above it, it would be dead code
before 2M and unconditionally live after it.
Two ways out, and the cheap one is probably right
sidesteps
IsSuperMajorityentirely, needs no signaling, and is what theAuxPoW, LWMA-3 and emergency-difficulty forks in this tree already do. It costs
nothing and can happen any time.
GetBaseVersion(). Correct, and makesthe dead accessor do its job. But it changes when soft forks activate, so it is
consensus-affecting — which means it wants to land at or before block
2,000,000, while the upgrade audience is still people who care. After that it
is a request foreign merge-miners can decline.
Option 1 alone is enough to unblock #34. Option 2 is about whether we ever want
version signaling to work again, and if we do, it is on the 2M clock with #36.
No decision proposed here. Filing because the deadline is real and was not
written down.