Repository navigation
consensus: catch a BIP30 duplicate inside one confirm batch - #1059
Conversation
The BIP30 check looked up earlier creates of a txid in the store, which only sees connected blocks. An earlier block of the same write batch is not connected yet, so a duplicate coinbase one block later in the same batch was accepted. Core rejects it. Structural validation now remembers each checked block's txids and spendable outputs for the rest of the batch, and a later duplicate with an output not yet spent in the batch is rejected through the same rule. The mainnet repeat exceptions and BIP34 skips still run first. Only reachable below BIP34, for example regtest with -testactivationheight=bip34@N. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Damn. I'm gonna dig deep on this, could sworn grok and I had covered this one before. |
|
Verified again against real Bitcoin Core 31.1 on regtest with |
|
gonna have grok do a full audit of our consensus rules and tests around batches. The last 2 actual consensus bugs we've fixed have been things that were correct 1 block at a time but not in batches. bleh. |
|
I found one more. Opening PR 😬 |
There was a problem hiding this comment.
Summary
The batch map closes the real hole: a txid created by an earlier block in the same confirm write is checked before the store lookup, which cannot see those creates yet. The rule matches Core ConnectBlock — HaveCoin before this block's spends, unspendable outputs are not coins, BIP34-ancestry and the two mainnet repeats still skip, and a fully spent prior is allowed. pending_spent on this path is the structural set, filled only after the check, and begin_batch clears the maps on every write, so this block cannot hide a coin and a failed batch cannot poison the next one.
Issue counts by severity
- bugs: 0
- suggestions: 0
- nits: 0
Summary
Two blocks with the same coinbase txid in one confirm batch were both accepted. The BIP30 lookup only sees connected blocks, and the first block of the batch is not connected yet. Core rejects the second block.
This can't really happen on any live network anymore: BIP34 makes every coinbase unique, and mainnet's only pre-BIP34 duplicates are the two grandfathered blocks. It's only reachable on regtest with
-testactivationheight=bip34@N. The risk is small, but it's a Core mismatch and the fix is small, so we might as well have it.Evidence
bip30_duplicate_coinbase_in_one_batchfails: the batch returnsOkfor the duplicate.After: it passes, and the same blocks sent in two batches are still rejected (control case).
Merge Danger
Door: two-way
Blast Radius: consensus. Only a real duplicate txid can match, which needs BIP34 off.
🤖 Generated with Claude Code