A position piece. It argues one side — that this particular rule is premature and that cheaper,
nLockTime-preserving alternatives exist — and backs the empirical claims against the historical
record and recent mainnet data.
BIP54 ("Consensus Cleanup") bundles four soft-fork fixes. Three are uncontroversial — the timewarp
fix, the 64-byte-transaction ban, and a per-transaction sigop limit. The fourth is contested: it
requires every coinbase transaction's nLockTime to equal block_height − 1 (with
nSequence ≠ 0xffffffff, so the locktime is actually enforced). This is the case for leaving that
fourth rule out for now.
The problem this rule solves is (1) ~53 years away (the first collision with coins at stake is
~2079), (2) already mitigated by deployed software,
(3) not a credible attack even in principle, and (4) solvable later by cheaper rules that don't
permanently consume the coinbase nLockTime. Spending a scarce consensus change now to burn
nLockTime is therefore premature.
BIP34 (height in the coinbase scriptSig, active since block 227,931 in 2013) already makes every modern coinbase unique. The only residual collisions are with pre-BIP34 coinbases. The first one that can occur at all is at block 1,983,702 (~2046), where Core already resumes BIP30 — but its target coinbase is itself long since spent, so even then there is nothing to overwrite. The first collision whose target still holds unspent coins is ~2079 — about 53 years away, roughly three times Bitcoin's entire existence to date (the network is not yet 20 years old; the genesis block was mined in January 2009).
And it is already handled: Bitcoin Core resumes BIP30 duplicate-txid checking unconditionally from
that height (src/validation.cpp, BIP34_IMPLIES_BIP30_LIMIT = 1983702). That is an enforced consensus
rule today, implemented everywhere that follows Bitcoin consensus. Nothing is broken; nothing is
unhandled. The fix merely deletes a check — it does not patch a hole.
Proof-of-work makes it nearly impossible. To forge a duplicate txid, the attacker's coinbase must be byte-identical to the ancient one — so the coinbase is frozen and contributes zero nonce space. Only the 80-byte header can roll: the 32-bit nonce, plus version-rolling (~2¹⁶) and ntime (~2¹³) ≈ 2⁶¹ ≈ 2×10¹⁸ hashes. A valid block needs ≈ 5×10²³ hashes, so the odds of mining that specific block with a frozen coinbase are ≈ 1 in 200,000 at today's difficulty — and far worse by 2046. The only escape is to roll an extranonce in a second transaction, which standard mining stacks (Stratum V1 and any likely successor) cannot do; it requires bespoke gear.
And the block subsidy makes it economically self-defeating. A byte-identical duplicate must reproduce the ancient coinbase's outputs exactly — including their total value. The soonest target, block 164,384 (Jan 2012), paid a 170 BTC coinbase (50 BTC subsidy plus a famous ~120 BTC accidental fee); the other candidates paid ~50 BTC. But a coinbase at height 1,983,702 may pay at most the subsidy — about 0.098 BTC by then — plus fees. Reproducing a 50–170 BTC coinbase would therefore require tens to ~170 BTC of fees in that single block, all of it paid to the original 2012 addresses — the attacker gains nothing and forfeits everything. The subsidy schedule alone turns the "attack" into an expensive donation.
Stateless ("utreexo") validators verify every spend with an inclusion proof against the accumulator — but a coinbase spends nothing, so it carries no proof. A validator therefore can't verify that a coinbase's outputs don't already exist as unspent UTXOs — that would need proof-of-absence (non-membership), a whole new category of proof the Merkle-forest accumulator doesn't support. Making coinbase txids unique by construction is the clean fix: the validator never has to run that check. (Whether stateless validation strictly needs this in consensus, versus extra proof machinery, is debatable — but either way the guarantee is cheap.)
And any structural distinguisher provides it without touching nLockTime. Two obvious ones, found in
under an hour — better, non-obvious ones almost certainly exist:
- (a) Require a small marker the ancient coinbases can't have — e.g. an extra zero-value, unspendable output. Pre-BIP34 coinbases don't carry one, so a modern coinbase can never byte-match an ancient one. It need only apply to non-segwit blocks, since segwit coinbases already carry a distinguishing witness commitment.
- (b) Require coinbase scriptSig above a small floor from the collision height onward. Every
collision-capable coinbase with coins still at stake has a scriptSig of ≤ 16 bytes, so
> 16suffices;≥ 53covers even the already-spent ones too (verified below). Either way a modern coinbase can't byte-match a short ancient one.
(Note: this deliberately does not propose "just require a witness commitment at those heights." Mandating one could interfere with miners pre-computing the next empty block, so it's avoided.)
The set of collision-capable coinbases is finite and historical. Taking the canonical enumeration from
Bitcoin Core PR #12204 (the same analysis that set BIP34_IMPLIES_BIP30_LIMIT) — all 15 pre-BIP34
coinbases whose "indicated height" exceeds their block height — and measuring each coinbase's scriptSig:
| block | indicated height | ≈ collision date | scriptSig bytes | coinbase outputs |
|---|---|---|---|---|
| 209,920 | 209,921 | ~2012 (past) | 32 | spent |
| 176,684 | 490,897 | ~2017 (past) | 4 | spent |
| 164,384 | 1,983,702 | ~2046 | 8 | spent |
| 169,895 | 3,708,179 | ~2079 | 9 | spent |
| 170,307 | 3,709,183 | ~2079 | 9 | spent |
| 171,896 | 3,712,990 | ~2079 | 9 | spent |
| 172,069 | 3,713,413 | ~2079 | 8 | partial — 0.0006 BTC unspent |
| 172,357 | 3,714,082 | ~2079 | 9 | partial — 0.004 BTC unspent |
| 172,428 | 3,714,265 | ~2079 | 9 | spent |
| 183,669 | 3,761,471 | ~2080 | 4 | spent |
| 196,988 | 4,275,806 | ~2090 | 16 | partial — 47.5 BTC unspent |
| 174,151 | 5,208,854 | ~2107 | 52 | spent |
| 201,577 | 5,327,833 | ~2109 | 16 | partial — 45.6 BTC unspent |
| 206,039 | 7,299,941 | ~2147 | 10 | spent |
| 206,354 | 7,299,941 | ~2147 | 10 | spent |
Two of the indicated heights are already in the past — 209,921 (2012, when BIP30 was actively
enforced) and 490,897 (2017, mined with a different coinbase) — both passed without incident; everything
else is decades out. A fully-spent coinbase can't trigger a BIP30 violation (there's nothing to overwrite), and 11 of
the 15 are fully spent — including both the soonest collision (block 164,384, ~2046) and the longest
scriptSig (block 174,151, 52 bytes, ~2107). So the only BIP30-relevant coinbases are the four
partial rows, and their scriptSigs top out at just 16 bytes — the rule could be as loose as
len(coinbase scriptSig) > 16 and still cover every coinbase that could do harm (the soonest at
~2079 with 0.0006 BTC; the two sizable ones, ~46–47 BTC, at ~2090 and ~2109; §2's subsidy argument blocks
those regardless).
Going all the way to ≥ 53 — covering the spent 52-byte outlier too, which doesn't even collide
until ~2107 — buys only one extra thing:
avoiding a duplicate txid of an already-spent coinbase. That is not a consensus problem (Bitcoin
already contains duplicate txids, from the two 2010 BIP30 pairs) and is in any case vanishingly unlikely.
The threshold is effectively a free parameter anywhere from ~17 to 53; the fix works at any of them. The cost is negligible: coinbase scriptSigs today are already mostly well over
53 bytes (median ~93), and the scriptSig is where the extranonce lives — so a minimum just guarantees
more usable rolling room, and miners have decades to ensure they meet it.
nLockTime is the most hash-efficient extranonce slot in the whole block: it's the last field
serialized, so it can be rolled by re-running only the final SHA-256 compression against a cached
midstate — valuable for low-latency rolling on ASICs/MCUs. Committing block height there removes that
option for every miner, permanently. And the benefit unique to the nLockTime approach — reading
the height back without parsing Script — is a convenience, not a requirement.
Note too that BIP54 constrains two coinbase fields — nLockTime and nSequence. Leaving both
unpinned keeps any future cleanup simpler (see the timing note below).
This is the deepest reason to leave nLockTime alone, and it takes a few steps.
Today the mining ASIC is deliberately "dumb." There is a division of labor: a separate controller — nowadays an FPGA on the mining board, because a general-purpose CPU already can't keep pace — builds the coinbase, computes the merkle root, and feeds the chip finished 80-byte headers; the chip just grinds the 32-bit header nonce billions of times per second. It knows nothing about the coinbase, the transactions, or the block height. That ignorance is a feature — it keeps block construction in the miner's own hardware, not the hash chips. (That this job already needs an FPGA rather than a CPU is itself a sign of the pressure described next.)
As ASICs get faster, the extranonce must move into the chip. The ~4-billion header-nonce space is
exhausted in a fraction of a second, so the controller must keep feeding fresh, extranonce-rolled work —
and eventually can't keep up. The foreseen fix is to let the ASIC roll the extranonce itself, in
silicon. To do that cheaply the extranonce wants to sit at the very end of the coinbase, where
SHA-256's cached midstate means rolling it re-hashes almost nothing — i.e. exactly in nLockTime. A free
nLockTime also lets the chip touch only those last bytes while leaving the rest of the coinbase fixed.
BIP54 takes that slot, with two consequences. First, the in-chip extranonce gets shoved into a dummy
OP_RETURN near the end of the tx — a hack — or it disturbs more of the coinbase and so threatens
split generation rewards (pools paying many miners directly through multiple coinbase outputs, rather
than custodying the reward and paying out later). Second, and worse: because nLockTime must now equal
height − 1 and is the last field, any in-chip rolling at the end of the tx forces the chip to emit the
correct height — so the ASIC must become height-aware. Today it isn't.
A height-aware ASIC is a timebomb. Once the block height is baked into the silicon, a manufacturer —
or a state coercing one — can program the chips to stop mining after a chosen height or date: a
supply-chain kill switch that could brick a large share of global hashrate at a pre-set moment. And once
nLockTime = height − 1 is consensus, it can't be undone without a hardfork. (The risk isn't wholly
new — the chip already rolls the header timestamp, so it already has a partial clock — but BIP54 deepens
it and couples it to coinbase construction.)
So the asymmetry runs against acting now. The uniqueness fix is a soft fork that can be deployed
closer to the deadline at leisure. Burning nLockTime (and nSequence) is the move that's hard to walk
back: if the extranonce/timebomb pressure materializes, undoing a nLockTime = height − 1 rule would
itself take a hardfork — far harder than the soft fork we're deferring. Better not to spend two
coinbase fields now for a non-urgent problem a later soft fork can fix.
- "Do it once now, inside the already-coordinated cleanup fork, to avoid a second soft fork." — The
uniqueness fix is itself a small soft fork, deployable closer to the deadline; a second soft fork
is cheap. Permanently pinning two coinbase fields today for a non-urgent, non-attack problem is the
expensive option — and walking back a mistaken
nLockTimeburn would need a hardfork. - "Stateless validation wants a hard invariant, not a probabilistic (PoW) assumption." — Agreed — which
is exactly why the §3 alternatives give a hard structural invariant too. They simply provide it
without touching
nLockTime. - "A positive height commitment is cleaner than a negative distinguisher." — Perhaps, but "cleaner" is
not "necessary." None of the concrete benefits requires the commitment to live in
nLockTime.
There is no clock forcing this decision now. The problem is remote, already mitigated, not practically
exploitable (proof-of-work and the subsidy schedule both block it), and the only lasting motivation
(stateless validation) is satisfied by cheaper, narrower rules — at least one verified against the
complete historical record and costing essentially nothing in practice. If two obviously-better fixes
turn up in under an hour, better ones will turn up with deliberate design. Solve it later, with the
smallest rule that does the job — and don't burn nLockTime.
- BIP 54 text & discussion: bitcoin/bips#1800 · https://bips.dev/54/
- BIP 30 / BIP 34: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki · https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
- Core analysis that set
BIP34_IMPLIES_BIP30_LIMIT: bitcoin/bitcoin#12204 - Enumeration of collision-capable coinbases (jnewbery): https://gist.github.com/jnewbery/df0a98f3d2fea52e487001bf2b9ef1fd
- Core enforcement code:
bitcoin/src/validation.cpp(searchBIP34_IMPLIES_BIP30_LIMIT) - Coinbase data fetched from the blockstream.info and mempool.space public REST APIs.
I don't think this case is compelling.
First of all, the piece is getting the motivation for the BIP 54 coinbase rule wrong. The attack you suggest is already prevented by the BIP 30 check. As BIP 54 states, the motivation is precisely to not have to re-enable the BIP 30 check:
So the "real deadline" is not ~53 years out, but 20. This means we still have a bunch of time, but changing Bitcoin's consensus rules is a long and tedious process (for good reasons). Therefore it's good to be prepared well in advance to avoid rushing potentially less well-considered changes closer to the deadline. (I understand this is contrary to the author's own endeavours --i believe we just have an irreconcilable view of what is good for Bitcoin.)
Now, there is an infinite number of possible mitigations: any rule that forces future coinbase transactions to differ from all past ones would technically prevent a duplicate. But some mitigations are preferable to others. The first mitigation suggested in section 3 of this post was considered early on when work on the Consensus Cleanup resumed. Using
nLockTimewas later preferred because it is a less roundabout fix that also has the side-benefit of making the block height available from the coinbase transaction without parsing Script, and enables timelock enforcement that makes reasoning about validity easier. The second mitigation suggested in section 3 is a spectacularly bad way to design a consensus rule, even by the author's standards.Again, all of this was already discussed repeatedly on development mailing lists (1, 2) and in the rationale section of the BIP, which this post fails to engage with:
Finally, the "ASIC timebomb" section is where the author's LLM really loses it. The separate FGPA was needed to optimize covert ASICBoost, which not only we should not make protocol decisions to accommodate, but has also been superseded nowadays by overt ASICBoost, which rolls headers' nVersion field. The following reasoning is (flawed in other ways and) based on the erroneous assumption that the hashing chip only has 32 bits of space to grind. In practice modern miners use another 16 bits in the nVersion field (as per BIP 320), and sometimes even another 7 bits in nTime. BIP 323 reserves 24 bits of grinding spaces in nVersion, making it so the hashing chip can try 72 quadrillions values before requiring the controller to send in a new header. This means the single hashing chip would need to reach a hashrate of 72 PH/s to even exhaust the searching space in a whole second.
This section then goes from confused to ludicrous, when it suggests that making ASICs aware of the block height (which they are already through the controller, which must respect BIP 34 in crafting the coinbase transaction) would somehow facilitate State coercion of Bitcoin miners.
To conclude, the BIP 54 coinbase change is not an urgent, existential fix to Bitcoin. Nobody, to my knowledge, ever claimed it was. But from a low time preference perspective, it is nonetheless a net-positive one: at the short term cost of having to update mining pool software we get the long term benefit of never having to re-enable unnecessary overhead in block validation, as well as precluding alternative full node designs. And it makes sense to include it as part of a bundle of similar long term fixes, under BIP 54. In the future, please take Bitcoin consensus protocol discussions to open development forums, rather than in a Github gist, or on the social media account of the promoter of a contentious fork who blocks any dissenting voice.