Skip to content

31.x: Implement BIP 54 (Consensus Cleanup) without mainnet activation - #9

Open
darosior wants to merge 26 commits into
31.xfrom
bip54_on_31
Open

31.x: Implement BIP 54 (Consensus Cleanup) without mainnet activation#9
darosior wants to merge 26 commits into
31.xfrom
bip54_on_31

Conversation

@darosior

@darosior darosior commented Jul 6, 2026

Copy link
Copy Markdown
Owner

This is a backport of #8 for version 31.

It's based on a backport of the preparatory PRs bitcoin#35333, bitcoin#35335 and bitcoin#35338.

darosior and others added 26 commits July 2, 2026 17:15
This encapsulates the soft fork configuration logic as set by the `-testactivationheight` (for
buried deployments) and `-vbparams` (for version bits deployments) options which for the moment
are regtest-only, in order to make them available on other networks as well in the next commit.

Can be reviewed using git's `--color-moved` option with `--color-moved-ws=allow-indentation-change`.
…orks

This allows unit tests to set `-testactivationheight` and `-vbparams` on
all networks instead of exclusively on regtest. Those are kept
test-network-only when used as startup parameters.
For consistency with the overloads introduced in the previous commit,
and because there is already a few places where they are useful.
Some functional tests were still hardcoding parameters. Using the
constant allows to change the rules in a single place if necessary.
Prior commits are preparatory work. Following commits is the implementation of BIP54.
BIP54 counts sigops differently from existing sigops-based checks. Since
we are overloading the sigops term, make clear the constant refers to
BIP54-sigops, not other kinds of pre-existing sigops.

-BEGIN VERIFY SCRIPT-
sed -i 's/MAX_TX_LEGACY_SIGOPS/MAX_TX_BIP54_SIGOPS/g' $(git grep -l MAX_TX_LEGACY_SIGOPS src/)
-END VERIFY SCRIPT-
Move the function that checks whether a transaction respects the BIP54 sigops rule to the
consensus folder (along with the accompanying constant), as it will be made consensus-critical
in the next commit. Can be reviewed with git's --color-moved option.
When BIP54 is active, enforce that block transactions do not violate the BIP54 limit on the
number of legacy sigops present in Scripts that get executed during block validation.
In Taproot the signature commits to the list of spent outputs.
Test the newly introduced limit with various combinations of inputs and outputs types,
historical transactions, and exercise some implementation-specific edge cases. Record
each test case and optionally write them to disk as JSON to generate the BIP test vectors.
The fuzz target was specifically crafted to support seeding it with the BIP54 test vectors
generated by the unit test in the previous commit.
We are going to introduce the timewarp fix for mainnet with a greater grace period. Rename
the MAX_TIMEWARP value for testnet to differentiate them.

-BEGIN VERIFY SCRIPT-

for f in $(git grep -l MAX_TIMEWARP); do sed -i "s/MAX_TIMEWARP/MAX_TIMEWARP_TESTNET4/g" "$f"; done

-END VERIFY SCRIPT-
Documentation about the test vectors, including about their structure and content, as well as
reproduction instructions, is available here: https://github.com/bitcoin/bips/tree/master/bip-0054/test_vectors
…k height

When BIP 54 is active, coinbase transactions must have their nLockTime field set to the block height
minus 1 (since it encodes the last height at which the transaction is invalid), and their nSequence
field may be anything but the maximum value (which indicates "final", bypassing timelock
validation).
Documentation about the test vectors' structure and content, as well as instructions for generating
them is available at https://github.com/bitcoin/bips/tree/master/bip-0054/test_vectors .
… vectors)

This adds tests exercising the bounds of the checks on the invalid transaction size, for various
types of transactions (legacy, Segwit, bytes in input/output to get to 64 bytes) as well as
sanity checking against some known historical violations.

Thanks to Chris Stewart for digging up the historical violations to this rule.
It's not a standardness limit anymore, it was made consensus.

Thanks to Anthony Towns for the scripted diff script.

-BEGIN VERIFY SCRIPT-
sed -i 's/MAX_STD_LEGACY_SIGOPS/MAX_TX_BIP54_SIGOPS/g' $(git grep -l MAX_STD_LEGACY_SIGOPS)
sed -i 's/signature operations in validating a transaction./signature operations in a single transaction, per BIP54./' test/functional/test_framework/script_util.py
-END VERIFY SCRIPT-

Co-Authored-by: Anthony Towns <aj@erisian.com.au>
The previously introduced unit tests extensively test the specific implementation of each
mitigation. This functional test complements them by end-to-end testing all mitigations.
For the added timestamp constraints, it mimicks how they would get exploited (by implementing pseudo
timewarp and Murch-Zawy attacks) and demonstrates those exploits are not possible anymore after
BIP54 activates.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants