validation: require BIP110 revalidation after late upgrade - #1
Conversation
|
This looks like AI slop to me, because whether blocks are marked as invalid or not when switching to a BIP-110 node doesn't matter since this is a softfork, and the longest chain will prevail. If the entire network is on a chain that is the longest, it will eventually not matter whether a shorter chain is marked valid or not. Asymptotically and over time, that branch will never win. It doesn't matter if it's "marked invalid". There are many other things that need to be cleaned up after the activation of BIP-110 (and were discussed, like the readiness of the wallet in the nodes), beyond some meaningless historical blocks nonsense like this. I don't know if I'm missing something, but this PR does look like a desperate move to discredit BIP-110 with AI slop. |
|
Fair points on two counts: with current signaling this is unlikely to bite in anger any time soon, and yes, there are bigger activation-cleanup items. I don't think that makes the invariant meaningless, though. "Longest chain wins" is more precisely "most-work chain among the chains a node considers valid." Invalidity is disqualifying. A node never follows a heavier chain that contains a block it rejects, regardless of work. So a persistent split is by definition a validity disagreement, and most-work can't resolve one: it's the thing being disagreed about. Two nodes that both report RDTS enforced but hold different validity views of the same history are split. The cleaner way to see it: this PR is the SegWit safeguard transposed. Why is path-independent validity worth enforcing for SegWit but not for RDTS? The failure that's specific to this bug isn't the general UASF-minority split, as that happens regardless. It's that two nodes both configured to enforce RDTS end up disagreeing with each other purely because of upgrade order. A node that syncs from genesis under enforcement rejects the retained block and cannot reproduce the accept verdict a late-upgraded node reached, so it can't follow what the late-upgraded node treats as valid history. Same rules, same version, different chains. Fail-closed-then-reindex is what stops a late upgrade from silently reaching that state in the first place. Note this is orthogonal to whether BIP110 should activate; the property protects any RDTS node from a path-dependent split regardless of one's view on the proposal. The functional test reproduces all three violation classes (oversized output, 257-byte push, missing mandatory signal) and shows recovery stops at the last valid ancestor. |
|
@TheQuantumPhysicist this is a real issue though it appears to be jokingly presented. Prior softforks like segwit correctly handled this case and even pretty basic testing should have exposed it. It's an important case (at least in the hypothetical case that anything about 110 was important) because the reason to switch to enforcing software is because you're currently accepting the "wrong" chain. If all you care about is being on the most work chain regardless of of it having 110 invalid blocks then you shouldn't be running 110 software at all. (Which is, IMO, prudent!). The point of running 110 software is to only accept a 110 valid chain but the 110 implementation can fail to achieve this goal. |
|
https://x.com/GrassFedBitcoin/status/2078532917819748802 Just in the interest of not rehashing the same points. |
Summary
Persist phase-specific BIP110/RDTS validation provenance in the block index and refuse to load a chainstate containing applicable blocks that were not connected with the required BIP110 enforcement phase enabled.
This prevents a node from:
The branch is based directly on
f41f01e1e6de7025d52a865bef97f2a67277f0f3, the current29.x-knotscommit in this fork.Root cause
BIP110 mandatory-signaling, output-size, and script rules run from
ConnectBlock(), but persistedBLOCK_VALID_SCRIPTSdoes not identify which consensus configuration was active when the chainstate was created. Normal startup trusts the saved UTXO tip and validity flags, and the default verification level does not reconnect blocks.A datadir advanced by a non-enforcing client could therefore be reopened by an enforcing client without replaying the historical blocks through BIP110 validation.
The provenance must also distinguish rule phases. A block validated under ACTIVE transaction/script rules does not prove mandatory signaling was checked, and vice versa, if deployment parameters later place the same height in a different phase.
Changes
BLOCK_OPT_REDUCED_DATA_ACTIVEfor active BIP110 transaction/script validation.BLOCK_OPT_REDUCED_DATA_SIGNALfor mandatory-signaling validation.fJustCheckblock connection; speculative checks do not drive the provenance train.-reindex-chainstate.bitcoindelement while leaving Valgrind and any other prefabricated wrapper train concentrically attached.Operator impact
An enforcement upgrade remains transparent when no BIP110 rule has yet applied or when all applicable blocks were connected by an enforcing client under the required phase.
If provenance is missing, startup fails closed:
On unpruned nodes, rebuilding the chainstate reconnects blocks under the current rules and stops at the last valid ancestor if an incompatible block exists. Pruned nodes require a full
-reindexwhen the necessary block data has been removed.Validation
versionbits_testsvalidation_chainstate_testsvalidation_chainstatemanager_teststxvalidationcache_testsfeature_rdts.pyfeature_reduced_data_temporary_deployment.pyfeature_reduced_data_utxo_height.pyfeature_presegwit_node_upgrade.pyfeature_assumeutxo.pyruff check test/functional/feature_bip110_late_upgrade_chainstate.pygit diff --checkAll listed checks passed.
Scope
This draft is intentionally confined to the DathonPwn fork. It does not open or modify any pull request, issue, branch, or discussion in
bitcoinknots/bitcoin.