Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Sync BIP30/BIP34 Handling With Bitcoin Core#2467

Merged
Roasbeef merged 5 commits into
btcsuite:masterfrom
starius:bip30bypassfix
Apr 30, 2026
Merged

Sync BIP30/BIP34 Handling With Bitcoin Core#2467
Roasbeef merged 5 commits into
btcsuite:masterfrom
starius:bip30bypassfix

Conversation

@starius
Copy link
Copy Markdown
Contributor

@starius starius commented Dec 25, 2025

Change Description

This PR aligns btcd's consensus logic with Bitcoin Core when deciding when to run the expensive BIP30 duplicate-coinbase check. The changes mirror the behavior introduced in bitcoin/bitcoin#6931 and bitcoin/bitcoin#12204.

Summary

  • Introduce a helper that encapsulates the decision of whether to run the BIP30 check (bip0030CheckNeeded).
  • Record each network’s BIP34 activation hash so we can verify the activation block exists on the current branch before skipping the check.
  • Re-enable BIP30 at height 1_983_702, matching Core’s protection against pre-BIP34 coinbases that serialized future heights.
  • Add unit tests covering the historical exception blocks, the BIP34 activation height, the re-enable height, and alternate-chain scenarios.

Steps to Test

go test ./blockchain

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

Upcoming commits tweak the conditions under which the expensive BIP30
duplicate-coinbase check should run. To unit-test those changes, this
commit moves the decision logic out of BlockChain.checkConnectBlock and
into a dedicated helper, bip0030CheckNeeded. The behaviour is unchanged;
the new helper is covered by tests in bip30_test.go.
Sync the behaviour with Bitcoin Core.

See bitcoin/bitcoin#6931

In Core, the BIP30 flag is cleared only if the previous block's ancestor chain
already contains the BIP34 activation block. For the activation block itself
(height = BIP0034Height), pindex->pprev->GetAncestor(BIP34Height) returns
nullptr, so the flag stays on and BIP30 is still enforced. In other words, Core
enforces BIP30 for the activation block and skips it starting with the following
block.
Mirror BIP34-aware BIP30 skip logic from Bitcoin Core.

PR bitcoin/bitcoin#6931 in Bitcoin Core introduced
an optimization that skips the expensive BIP30 duplicate coinbase check once
BIP34 is active *and* the chain actually contains the recorded activation block.
See the comment in that PR "//Only continue to enforce if we're below BIP34
activation height or the block hash at that height doesn't correspond."

btcd used to drop the check purely based on height. On a fork that lacks the
BIP34 activation block, that difference lets a duplicate coinbase slip through
consensus. This patch ports the missing pieces: we store the activation hash in
chain parameters and only disable BIP30 after we see that block on-chain.
Bitcoin Core PR bitcoin/bitcoin#12204 tightened BIP30
handling: re-enable the check once height 1,983,702 is reached.

This change ports that logic into btcd and adds a regression test.
Set regtest buried heights to match Core: BIP34/65/66 at height 1 and make
CSV/SegWit/Taproot always active. Added regtest coverage for header version
floors, coinbase height enforcement, and deployment state to ensure we now
reject the blocks Core rejects and accept the ones Core accepts.

Updated package fullblocktests to generate BIP34-compliant blocks.

Test helpers now set prev block height to 0 (not the default -1) so generated
blocks start at height 1 and satisfy coinbase height rules.
@starius starius marked this pull request as ready for review December 25, 2025 02:25
@coveralls
Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 20497333340

Details

  • 47 of 52 (90.38%) changed or added relevant lines in 2 files are covered.
  • 179 unchanged lines in 7 files lost coverage.
  • Overall coverage decreased (-0.04%) to 54.923%

Changes Missing Coverage Covered Lines Changed/Added Lines %
blockchain/validate.go 21 22 95.45%
blockchain/fullblocktests/generate.go 26 30 86.67%
Files with Coverage Reduction New Missed Lines %
mempool/mempool.go 1 66.56%
btcutil/gcs/gcs.go 2 81.55%
database/ffldb/blockio.go 4 88.81%
wire/msgaddrv2.go 16 50.0%
wire/netaddressv2.go 20 75.08%
blockchain/validate.go 48 89.13%
rpcclient/infrastructure.go 88 39.75%
Totals Coverage Status
Change from base Build 19121431262: -0.04%
Covered Lines: 31226
Relevant Lines: 56854

💛 - Coveralls

@starius
Copy link
Copy Markdown
Contributor Author

starius commented Dec 25, 2025

Moved regtest sync to a separate PR #2469 since it reduces coverage and is unrelated to other commits.

@saubyk
Copy link
Copy Markdown
Collaborator

saubyk commented Mar 17, 2026

cc: @bhandras for review

@allocz
Copy link
Copy Markdown

allocz commented Apr 10, 2026

Diff looks good. I expect bip54 to be enabled soon, avoiding the return of the expensive bip30 verification.

Nice work.

@saubyk saubyk requested a review from kcalvinalvin April 14, 2026 00:11
@saubyk saubyk requested a review from bhandras April 23, 2026 14:35
Copy link
Copy Markdown
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🐧

@Roasbeef Roasbeef merged commit ac0394f into btcsuite:master Apr 30, 2026
3 checks passed
@starius starius deleted the bip30bypassfix branch May 6, 2026 22:01
starius added a commit to starius/btcd that referenced this pull request May 6, 2026
PR btcsuite#2467 changed regtest to match Core's BIP34/65/66 activation rules, and
the merged stack carries that (commit cd4e542 "regtest: align activations
with Bitcoin Core"). Height-1 regtest blocks now need a BIP34-compliant
coinbase height and a post-BIP66 block version.

The failing tests came from commits added after PR btcsuite#2467 was opened on
December 25, 2025 but before it merged on April 30, 2026:

- c1a4612 ("blockchain: add ProcessBlockHeader")
- f9645f0 ("blockchain: reuse existing header node in maybeAcceptBlock")
- dc6e096 ("netsync: add TestSyncStateMachine for end-to-end IBD sync flow")
- ce09426 ("netsync: add TestStartSyncBlockFallback for block-only sync path")
- 2aae8a6 ("netsync: add TestStartSyncChainCurrent for chain-current noop path")

Because those tests landed later, they kept the old regtest assumptions even
though btcsuite#2467 had already been authored and tested against the older tree.
Once btcsuite#2467 finally merged, these newer tests started building invalid regtest
blocks and headers.

Fix them by setting the genesis tip height to 0 before generating descendants,
using Version 4 in the regtest block/header helpers, and encoding the test
coinbase height with a minimal BIP34 push plus padding for the generic coinbase
script-length rule.
allocz pushed a commit to allocz/btcd that referenced this pull request May 8, 2026
PR btcsuite#2467 changed regtest to match Core's BIP34/65/66 activation rules, and
the merged stack carries that (commit cd4e542 "regtest: align activations
with Bitcoin Core"). Height-1 regtest blocks now need a BIP34-compliant
coinbase height and a post-BIP66 block version.

The failing tests came from commits added after PR btcsuite#2467 was opened on
December 25, 2025 but before it merged on April 30, 2026:

- c1a4612 ("blockchain: add ProcessBlockHeader")
- f9645f0 ("blockchain: reuse existing header node in maybeAcceptBlock")
- dc6e096 ("netsync: add TestSyncStateMachine for end-to-end IBD sync flow")
- ce09426 ("netsync: add TestStartSyncBlockFallback for block-only sync path")
- 2aae8a6 ("netsync: add TestStartSyncChainCurrent for chain-current noop path")

Because those tests landed later, they kept the old regtest assumptions even
though btcsuite#2467 had already been authored and tested against the older tree.
Once btcsuite#2467 finally merged, these newer tests started building invalid regtest
blocks and headers.

Fix them by setting the genesis tip height to 0 before generating descendants,
using Version 4 in the regtest block/header helpers, and encoding the test
coinbase height with a minimal BIP34 push plus padding for the generic coinbase
script-length rule.
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.

5 participants