mirror of
https://github.com/bitcoin/bips.git
synced 2026-06-01 17:15:27 +00:00
The rationale was duplicating some of the motivation. The motivation had a sentence that read weird. While rephrasing the sentence, take the opportunity to link to the now-proposed Utreexo BIP. Also remove a duplicate link reference.
254 lines
18 KiB
Markdown
254 lines
18 KiB
Markdown
```
|
||
BIP: 54
|
||
Layer: Consensus (soft fork)
|
||
Title: Consensus Cleanup
|
||
Authors: Antoine Poinsot <mail@antoinep.com>
|
||
Matt Corallo <bips@bluematt.me>
|
||
Status: Draft
|
||
Type: Specification
|
||
Assigned: 2025-04-11
|
||
License: CC0-1.0
|
||
```
|
||
|
||
## Abstract
|
||
|
||
This document proposes new consensus rules in order to fix the timewarp attack, reduce the worst
|
||
case block validation time, prevent Merkle tree weaknesses, and avoid duplicate transactions without
|
||
[bip-0030][BIP30] validation.
|
||
|
||
## Motivation
|
||
|
||
This proposal addresses a number of long-standing vulnerabilities and weaknesses in the Bitcoin
|
||
protocol. Bundling these fixes together amortizes the fixed cost of deploying a Bitcoin soft fork.
|
||
|
||
The [timewarp bug][SE timewarp] makes it possible for a majority-hashrate attacker to arbitrarily
|
||
lower mining difficulty, and therefore arbitrarily increase the block rate. In the worst case, an
|
||
attacker can bring down the difficulty to its minimum within 38 days of starting the attack. Besides
|
||
empowering a 51% attacker, the presence of this bug makes it harder to reason about miners'
|
||
incentives. Accelerating the block rate allows an attacker to steal block subsidy from future
|
||
miners and increases available block space. It may be in the interest of short-sighted users and
|
||
miners to exploit this vulnerability to materially increase the block rate without fatally hurting
|
||
the network.
|
||
|
||
Specially crafted blocks may be expensive to process, [taking up to][Delving worst block] several
|
||
minutes to validate even on high-end devices, and up to a few hours on lower-end devices. Long block
|
||
validation times are a nuisance to users, increasing the cost to independently fully validate the
|
||
consensus rules. In addition they can be used by miners to attack their competition, creating
|
||
perverse incentives, centralization pressures and leading to reduced network security.
|
||
|
||
In computing a block's Merkle root, a transaction with exactly 64 bytes of non-witness data can be
|
||
interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it
|
||
possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not
|
||
part of a block, by pretending a 64-byte block transaction is actually an inner node[^9]. Invalidating
|
||
64-byte transactions addresses this vulnerability without requiring users of SPV verifiers, or
|
||
any other user of Merkle proofs, to rely on one of the available workarounds[^13] or even to know one is
|
||
necessary in the first place.
|
||
|
||
Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until
|
||
block height 1,983,702[^0]. Resuming [bip-0030][BIP30] validation would unnecessarily increase block
|
||
validation overhead and preclude alternative full node designs (such as [bip-0182][BIP182] Utreexo).
|
||
Enforcing that new coinbase transactions are different from the early [bip-0034][BIP34] violations
|
||
makes it possible to get rid of [bip-0030][BIP30] validation forever.
|
||
|
||
## Specification
|
||
|
||
For all blocks after activation the following new rules apply.
|
||
|
||
Given a block at height `N`:
|
||
- if `N % 2016` is equal to 0, the timestamp of the block must be set to a value higher than or
|
||
equal to the value of the timestamp of block at height `N-1` minus 7200 (T<sub>N</sub> ≥
|
||
T<sub>N−1</sub> − 7200);
|
||
- if `N % 2016` is equal to 2015, the timestamp of the block must be set to a value higher than
|
||
or equal to the value of the timestamp of the block at height `N-2015` (T<sub>N</sub> ≥
|
||
T<sub>N−2015</sub>).
|
||
|
||
A limit is set on the number of signature operations present in the scripts used to validate a
|
||
transaction. It applies to all transactions in the block except the coinbase transaction[^1]. For
|
||
each input in the transaction, count the number of `CHECKSIG` and `CHECKMULTISIG` in the input
|
||
scriptSig and previous output's scriptPubKey, including the P2SH redeemScript. If the total summed
|
||
over all transaction inputs is strictly higher than 2500, the transaction is invalid. The accounting is the
|
||
same as for [bip-0016][BIP16 specs], evaluating the scriptSig, scriptPubKey, and P2SH redeemScript
|
||
separately:
|
||
|
||
1. `CHECKSIG` and `CHECKSIGVERIFY` count as 1 signature operation, whether or not they are evaluated.
|
||
2. `CHECKMULTISIG` and `CHECKMULTISIGVERIFY` immediately preceded by `OP_1` through `OP_16` are counted as 1 to 16 signature operations, whether or not they are evaluated.
|
||
3. All other `CHECKMULTISIG` and `CHECKMULTISIGVERIFY` are counted as 20 signature operations, whether or not they are evaluated.
|
||
|
||
Transactions whose witness-stripped serialized size is exactly 64 bytes are invalid.
|
||
|
||
The coinbase transaction's `nLockTime` field must be set to the height of the block minus 1[^2]
|
||
and its `nSequence` field must not be equal to 0xffffffff.
|
||
|
||
## Rationale
|
||
|
||
The restrictions on the timestamp of the first and last blocks of a difficulty adjustment period fix
|
||
the timewarp and Murch–Zawy vulnerabilities[^3]. The latter poses mostly theoretical concerns but is
|
||
extremely low risk to fix: the duration of an adjustment period has never been, and should never be,
|
||
negative. The former is fixed by preventing the timestamp of the first block of a difficulty period
|
||
from being lower than the previous block's, with a two-hour grace period. A [previous
|
||
proposal][BIP-XXXX] to fix the timewarp attack used a ten-minute grace period instead, and this
|
||
approach has been adopted for [testnet4][BIP94 timewarp]. Out of an abundance of caution and because it only trivially worsens the
|
||
block rate increase under attack, a two-hour grace period is used here[^4].
|
||
|
||
Disabling some Script operations and functionalities was [previously proposed][BIP-XXXX] to reduce
|
||
the worst case block validation time but was met with resistance due to confiscation concerns[^5]. A
|
||
delicate balance needs to be struck between minimizing the confiscation risks of a mitigation, even
|
||
if merely theoretical, and bounding the costs one could impose on all other users of the system. To
|
||
that end, limiting potentially executed signature operations targets the exact harmful behaviour while
|
||
preserving maximal flexibility in Script usage.
|
||
Such a limit reduces the worst case block validation time by a factor of 40 and drastically
|
||
increases the preparation cost of an attack, making it uneconomical for a miner[^6]. The maximum of
|
||
2500 was chosen as the tightest value that did not make any non-pathological standard transaction
|
||
invalid[^7].
|
||
|
||
64-byte transactions can only contain a scriptPubKey that lets anyone spend the funds, or one that
|
||
burns them. They have also been non-standard since 2019 and never been used since 2016. Several
|
||
alternatives to invalidating them were previously proposed. Some believe the improvements for users
|
||
of Merkle proofs are too marginal to be worth introducing a discontinuity in the set of valid
|
||
witness-stripped transaction sizes. Others have suggested instead committing to the Merkle
|
||
tree depth in the header's version field[^8], which would make one workaround for a known
|
||
vulnerability easier to deploy. The authors believe it is preferable to address the root cause by
|
||
invalidating 64-byte transactions, fixing the vulnerability without Merkle proof users having to
|
||
rely on any workaround or even know one is necessary in the first place. See [this post][64 bytes
|
||
debate] for an attempt at summarizing the arguments for both sides of this debate.
|
||
|
||
The `nLockTime` field of transactions is a natural place to store a block height and is currently
|
||
unused in coinbase transactions. Using it to enforce that new coinbase transactions differ from
|
||
early [bip-0034][BIP34] violations also allows applications to recover the block height without
|
||
having to parse Script. Leveraging the existing timelock mechanism makes the check self-contained:
|
||
the same coinbase transaction cannot have been valid in a previous block[^11]. This simplifies both
|
||
reasoning and client implementation, since the [bip-0030][BIP30] check can be skipped entirely past
|
||
Consensus Cleanup activation, regardless of the [bip-0034][BIP34] activation status[^12].
|
||
|
||
## Backward compatibility
|
||
|
||
This proposal only tightens the block validation rules: there is no block that is valid under the
|
||
rules proposed in this BIP but not under the existing Bitcoin consensus rules. As a consequence
|
||
these changes are backward-compatible with non-upgraded node software. That said, the authors
|
||
strongly encourage node operators to upgrade in order to fully validate all consensus rules.
|
||
|
||
## Miner forward compatibility
|
||
|
||
Bitcoin Core version [29.0][Core 29.0] and later will not generate a block template that violates
|
||
the timestamp restrictions introduced in this BIP. Although it would be extremely unlikely due to
|
||
the grace period used in this proposal, miners should use the `curtime` or `mintime` field from the
|
||
`getblocktemplate` result for their block's timestamp to make sure they always create blocks valid
|
||
according to this proposal. Note this is not a new requirement: using a timestamp lower than the
|
||
`mintime` field from the `getblocktemplate` result already leads to creating an invalid block.
|
||
|
||
Bitcoin Core version [30.0][Core 30.0] and later will not generate a block template including a
|
||
transaction that violates the signature operations limit introduced in this BIP.
|
||
|
||
Bitcoin Core version [0.16.1][Core 0.16.1] and later will neither relay nor create block templates
|
||
that include transactions whose witness-stripped serialized size is exactly 64 bytes.
|
||
|
||
The coinbase transaction is usually crafted by mining pool software. To the best of the authors'
|
||
knowledge, there does not exist an open source reference broadly in use today for such software.
|
||
We encourage mining pools to update their software to craft coinbase transactions that are
|
||
forward-compatible with the changes proposed in this BIP.
|
||
|
||
## Reference implementation
|
||
|
||
An implementation of BIP54 for Bitcoin Core is available [here][inquisition-implem].
|
||
|
||
## Test vectors
|
||
|
||
Documented test vectors are available [here](./bip-0054/test_vectors/) for all mitigations
|
||
introduced in this BIP.
|
||
|
||
## Acknowledgements
|
||
|
||
This document builds upon an [earlier proposal][BIP-XXXX] by Matt Corallo.
|
||
|
||
The authors would like to thank everyone involved in researching the most appropriate mitigation for
|
||
each of these bugs. We would like to thank in particular Anthony Towns and Sjors Provoost for their
|
||
direct contributions to this proposal, as well as @0xb10c and Brian Groll for providing the authors
|
||
with data to analyze the proposed mitigations. Thanks to Chris Stewart for digging up historical
|
||
violations to the new transaction size rule, which are partially reused in this BIP's test vectors.
|
||
|
||
## Copyright
|
||
|
||
This document is licensed under the Creative Commons CC0 1.0 Universal license.
|
||
|
||
|
||
[^0]: Block 1,983,702 is the earliest future block which could contain a duplicate coinbase
|
||
transaction while still respecting [bip-0034][BIP34]. See [this post][Delving duplicable] for a list
|
||
of all such future blocks.
|
||
[^1]: Technically this limit *cannot* apply to a coinbase transaction as the size of its sole
|
||
input's scriptSig is limited.
|
||
[^2]: The locktime validation, which is also performed for coinbase transactions, enforces that the
|
||
nLockTime value is the last block at which a transaction is invalid, not the first one at which it
|
||
is valid.
|
||
[^3]: The timewarp attack is described [here][SE timewarp] and the Murch–Zawy attack [here][Delving
|
||
Murch-Zawy].
|
||
[^4]: The testnet4 difficulty exception pushed blocks' timestamps in the future when abused,
|
||
revealing how some broken pool software may produce blocks that don't respect a 10 minutes grace
|
||
period. Some [raised concerns][Sjors grace period] similarly broken software might be used on
|
||
mainnet. Using a grace period of 2 hours instead of 10 minutes only reduces the expected block
|
||
interval time under attack by ~2.2 seconds. See [this post][grace period debate summary] for more.
|
||
[^5]: The argument is about someone having a timelocked presigned transaction using some of those
|
||
features in its output script. The transaction cannot be mined before activation. Such outputs would
|
||
not be covered by an amnesty for old UTxOs. See for instance [here][O'Connor OP_CODESEPARATOR] and
|
||
[here][O'Connor sighash type] for discussions on this topic.
|
||
[^6]: It is important to reduce the worst case block validation time as well as the ratio of
|
||
validation time imposed over preparation cost. The former is to limit the damages an externally
|
||
motivated attacker can do. The latter is to disincentivize miners slowing down their competition by
|
||
mining expensive blocks. See [this thread][ML thread validation time] for more.
|
||
[^7]: A non-pathological transaction would have a public key per signature operation and at least
|
||
one signature per input. Per standardness a single P2SH input may not have more than 15 signature
|
||
operations. Even by using 1-of-15 `CHECKMULTISIG`s a transaction would bump against the maximum
|
||
standard transaction size before running into the newly introduced limit. To run against the newly
|
||
introduced limit but not the transaction size a transaction would need to spend P2SH inputs with a
|
||
redeem script similar to `CHECKSIG DROP CHECKSIG DROP ...`. This type of redeem script serves no
|
||
purpose beyond increasing its validation cost, which is exactly what this proposal aims to mitigate.
|
||
[^8]: By Sergio Demian Lerner in a [blog post][Sergio post].
|
||
[^9]: Conversely, pretending that the inner nodes on one level of the tree are the actual block
|
||
transactions is another source of complexity for full node implementations, which previously
|
||
resulted in consensus bugs. For instance, Bitcoin Core versions between 0.13.0 and 0.13.2
|
||
implemented caching that made it vulnerable to this attack. See [this writeup][Suhas Merkle] by
|
||
Suhas Daftuar for a detailed explanation. Invalidating 64-byte transactions may avoid this risk, but
|
||
the issue is largely orthogonal to this proposal: it is fundamentally about caching validation
|
||
status for malleable blocks.
|
||
[^11]: Technically it could be argued a duplicate could in principle always be possible before block
|
||
31,001 when `nLockTime` enforcement [was originally soft-forked][Harding nLockTime]. But treating
|
||
coinbase transactions as not having duplicate past Consensus Cleanup activation would be consistent
|
||
for any implementation which enforces `nLockTime` from the genesis block, which is the behaviour
|
||
notably of Bitcoin Core but also of all other implementations the authors are aware of.
|
||
[^12]: For instance Bitcoin Core only disables [bip-0030][BIP30] validation for a specific chain
|
||
where [bip-0034][BIP34] violations have been manually inspected (see [here][Core validation.cpp
|
||
BIP34]). Without the guarantee given by enforcing the timelock on coinbase transactions, this would
|
||
have to be perpetuated for the Consensus Cleanup.
|
||
[^13]: The authors are aware of three workarounds for SPV verifiers. The first is to request a
|
||
Merkle proof for the coinbase transaction in addition to the transaction of interest, to infer the
|
||
depth of the Merkle tree. The second is to reject Merkle proofs in which any inner node is also a
|
||
valid serialisation of a Bitcoin transaction. More details about these are available [here][Sergio
|
||
post]. A third workaround is to change the Merkle proof structure by requiring inner nodes to be
|
||
provided as the single-SHA256 of their preimage, instead of the double-SHA256. See [here][Sergio
|
||
MERKLEBLOCK] for a full description.
|
||
|
||
[Delving worst block]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/93
|
||
[BIP30]: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
|
||
[BIP182]: https://github.com/bitcoin/bips/pull/1923
|
||
[BIP-XXXX]: https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki
|
||
[BIP34]: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
|
||
[BIP16 specs]: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#specification
|
||
[SE timewarp]: https://bitcoin.stackexchange.com/questions/75831/what-is-time-warp-attack-and-how-does-it-work-in-general/75834#75834
|
||
[Delving Murch-Zawy]: https://delvingbitcoin.org/t/zawy-s-alternating-timestamp-attack/1062#variant-on-zawys-attack-2
|
||
[BIP94 timewarp]: https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki#time-warp-fix
|
||
[Sjors grace period]: https://delvingbitcoin.org/t/timewarp-attack-600-second-grace-period/1326
|
||
[grace period debate summary]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/66
|
||
[O'Connor OP_CODESEPARATOR]: https://gnusha.org/pi/bitcoindev/CAMZUoKneArC+YZ36YFwxNTKsDtJhEz5P2cosXKxJS8Rf_3Nyuw@mail.gmail.com
|
||
[O'Connor sighash type]: https://gnusha.org/pi/bitcoindev/CAMZUoK=1kgZLR1YZ+cJgzwmEOwrABYFs=2Ri=xGX=BCr+w=VQw@mail.gmail.com
|
||
[ML thread validation time]: https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com
|
||
[Suhas Merkle]: https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com
|
||
[Sergio post]: https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design
|
||
[Sergio MERKLEBLOCK]: https://bitslog.com/2018/08/21/simple-change-to-the-bitcoin-merkleblock-command-to-protect-from-leaf-node-weakness-in-transaction-merkle-tree/
|
||
[64 bytes debate]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41
|
||
[Harding nLockTime]: https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core
|
||
[Delving duplicable]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4
|
||
[Core 0.16.1]: https://bitcoincore.org/en/releases/0.16.1
|
||
[Core 29.0]: https://bitcoincore.org/en/releases/29.0
|
||
[inquisition-implem]: https://github.com/darosior/bitcoin/tree/2509_inquisition_consensus_cleanup
|
||
[Core 30.0]: https://bitcoincore.org/en/releases/30.0
|
||
[Core validation.cpp BIP34]: https://github.com/bitcoin/bitcoin/blob/390e7d61bd531505bb3d13f38316c282b85ed1dd/src/validation.cpp#L2401-L2459
|