Skip to content

Testnet4 bitcoin testnet4 setup - #31

Open
jeremy-then wants to merge 11 commits into
masterfrom
testnet4-bitcoin-testnet4-setup
Open

jeremy-then wants to merge 11 commits into
masterfrom
testnet4-bitcoin-testnet4-setup

Conversation

@jeremy-then

@jeremy-then jeremy-then commented Jul 13, 2026 •

Copy link
Copy Markdown

Add Bitcoin testnet4 (BIP-94) network parameters + tooling

Adds support for Bitcoin testnet4 (BIP-94) to org.bitcoinj, mirroring the bitcoinj-thin change and extending the CLI tools. Testnet4 replaces testnet3 with a fresh genesis block and adjusted proof-of-work rules that mitigate the testnet3 "block storm" and time-warp problems.

What's included

  • params/TestNet4Params.java — full network parameters + BIP-94
    difficulty-transition rules in checkDifficultyTransitions.
  • core/NetworkParameters.java — ID_TESTNET4 = "org.bitcoin.testnet4" and
    fromID(...) mapping.
  • Tooling — NetworkEnum.TESTNET4, --net=TESTNET4 handled in
    BuildCheckpoints (emits checkpoints-testnet4.txt) and in WalletTool
    (maps to TestNet4Params / testnet4.chain).
  • params/TestNet4ParamsTest.java + testnet4-headers-141120-143136.tsv
    — validation against real testnet4 headers across the difficulty-transition
    boundary at height 143136.
  • core/build.gradle — version bump to 0.15.6-rsk-6.

Consensus rules (BIP-94) and provenance

All network constants are taken verbatim from Bitcoin Core's CTestNet4Params and verified field-by-field (magic 0x1c163f28, port 48333, genesis nTime 1714777860 / nNonce 393743547 / nBits 0x1d00ffff, genesis hash 00000000da84f2ba…bf043, merkle 7aa0a7ae…7b4e, DNS seeds, prefixes 111/196/239, ext keys 0x043587CF/0x04358394, HRP tb).

Rule implemented BIP-94 change
Retarget anchored to the first block of the closing period (findFirstBlockOfPeriod) Block-storm fix
Timewarp floor: block at a period boundary must be ≥ prev.nTime − 600s (MAX_TIMEWARP_SECONDS) Time-warp mitigation
20-minute minimum-difficulty exception (nBits = 0x1d00ffff) Min-difficulty exception (inherited from testnet3)

Notes

References

Cut a new version for the release that adds Bitcoin testnet4 support.
Add TestNet4Params for Bitcoin testnet4 and wire it into NetworkParameters:

- Register ID_TESTNET4 (org.bitcoin.testnet4) and resolve it in
  NetworkParameters.fromID.
- Add a buildGenesisBlock helper so testnet4's distinct coinbase (message +
  33-byte output) produces the correct merkle root and genesis hash, without
  changing the shared createGenesis path used by mainnet/testnet3/regtest.
- Implement the BIP-94 difficulty rules in checkDifficultyTransitions: keep the
  20-minute minimum-difficulty exception mid-period, and at the retarget enforce
  the time-warp floor and anchor the calculation to the first block of the period
  (not the last), preventing the testnet3 block storm.
Add a TESTNET4 case to NetworkEnum and BuildCheckpoints so the checkpoints file consumed by the RSK bridge can be generated for testnet4.
Validate the BIP-94 difficulty logic against a real testnet4 difficulty period
(heights 141120..143136) replayed from mempool.space. That period ends in a
minimum-difficulty block, the exact case where BIP-94 diverges from testnet3.
Copilot AI review requested due to automatic review settings July 13, 2026 14:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Bitcoin testnet4 (BIP-94) network support to bitcoinj by introducing new network parameters and validation logic, wiring the network into parameter resolution, and extending tooling/tests to recognize and validate the new chain.

Changes:

  • Introduce TestNet4Params with BIP-94 difficulty transition rules and testnet4 genesis construction.
  • Register testnet4 via NetworkParameters.ID_TESTNET4 and NetworkParameters.fromID(...), and extend the checkpoints tool to support --net=TESTNET4.
  • Add comprehensive difficulty-transition replay tests using real testnet4 header fixtures.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tools/src/main/java/org/bitcoinj/tools/NetworkEnum.java Adds TESTNET4 to the CLI network enum.
tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java Supports generating checkpoints for testnet4 via TestNet4Params.
core/src/main/java/org/bitcoinj/params/TestNet4Params.java Implements testnet4 params, genesis setup, and BIP-94 difficulty validation.
core/src/main/java/org/bitcoinj/core/NetworkParameters.java Adds ID_TESTNET4, a reusable buildGenesisBlock(...) helper, and resolves testnet4 via fromID.
core/src/test/java/org/bitcoinj/params/TestNet4ParamsTest.java Validates identity/genesis and replays a real retarget period to verify BIP-94 behavior.
core/build.gradle Bumps core module version to 0.15.6-rsk-6.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/src/main/java/org/bitcoinj/tools/NetworkEnum.java
TESTNET4 was added to the tools NetworkEnum, so --net=TESTNET4 now
parses successfully on WalletTool's --net flag. But WalletTool's switch
over NetworkEnum had no matching case, so any invocation with
--net=TESTNET4 fell through to the default branch and threw
RuntimeException(Unreachable.) right after argument parsing, breaking
the tool for testnet4 across every subcommand.
Map TESTNET4 to TestNet4Params.get() with chain file testnet4.chain,
mirroring the existing cases and the handling already present in
BuildCheckpoints.
Copilot AI review requested due to automatic review settings July 14, 2026 15:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Comment thread core/src/main/java/org/bitcoinj/params/TestNet4Params.java
Comment thread core/src/main/java/org/bitcoinj/params/TestNet4Params.java
…coinj-thin)

Port the same defensive fixes reviewed on bitcoinj-thin, where the
identical code existed here:
- findLastNonMinimumDifficultyBlock: StoredBlock#getPrev returns null when
  the previous block isn't in the store, so the walk-back loop could
  dereference a null cursor and throw NullPointerException on a store
  missing history. Add a null guard to the loop condition and throw
  VerificationException after the loop.
- reduceToDeclaredPrecision: validate the compact-bits (nBits) exponent
  range and reject malformed network values with VerificationException.
Copilot AI review requested due to automatic review settings July 14, 2026 15:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Comment thread core/src/main/java/org/bitcoinj/params/TestNet4Params.java
Copilot AI review requested due to automatic review settings July 14, 2026 17:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Comment thread core/src/test/java/org/bitcoinj/params/TestNet4ParamsTest.java Outdated
Comment thread core/src/test/java/org/bitcoinj/params/TestNet4ParamsTest.java
- Note the TestNet4ParamsTest fixture is '|'-separated despite its .tsv name.
- MapStore.getParams() returns the shared params instance instead of
  calling TestNet4Params.get() directly.
Copilot AI review requested due to automatic review settings July 14, 2026 18:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Comment thread core/src/main/java/org/bitcoinj/params/TestNet4Params.java Outdated
targetBelowMinimumDifficulty -> targetExceedsMaxTarget, so the name
matches the condition (newTarget > maxTarget). No behavior change.
Copilot AI review requested due to automatic review settings July 14, 2026 18:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Comment on lines +310 to +313
case TESTNET4:
params = TestNet4Params.get();
chainFileName = new File("testnet4.chain");
break;
Comment on lines +86 to +89
case TESTNET4:
params = TestNet4Params.get();
suffix = "-testnet4";
break;
The block timespan (previousHeader - firstBlockOfPeriod time) was cast to
int before clamping. Since block times are uint32, the difference can
exceed Integer.MAX_VALUE and overflow, corrupting the timespan and the
computed difficulty target. Do the subtraction and clamp in long, casting
to int only after the value is clamped into the allowed range.
Copilot AI review requested due to automatic review settings July 14, 2026 18:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 16, 2026 17:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Comment thread core/build.gradle
apply plugin: 'eclipse'

version = '0.15.6-rsk-5'
version = '0.15.6-rsk-6-SNAPSHOT'
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