Skip to content

Fix genesis blocks for testnet, testnet4, signet and regtest - #4

Merged
BTGSCOINDEV merged 1 commit into
BTGSCOINDEV:mainfrom
argfamobile:fix/testnet-genesis
Aug 21, 2026
Merged

BTGSCOINDEV merged 1 commit into
BTGSCOINDEV:mainfrom
argfamobile:fix/testnet-genesis

Conversation

@argfamobile

Copy link
Copy Markdown
Contributor

Problem

-regtest, -testnet and -signet cannot start at all. On a clean datadir the node writes the genesis block and then fails to read it back:

init message: Verifying blocks…
[error] Errors in block header at FlatFilePos(nFile=0, nPos=8) while reading block
[error] A fatal internal error occurred: Failed to read block.
[error] Failed to connect best block (Failed to read block.)

Reproduced with the official btgs-x86_64-linux-gnu.tar.gz release of v30.2.3, and with two independently compiled builds (GCC 12 on Debian 12 and GCC 15 on Ubuntu 26.04), so it is not specific to any toolchain.

Cause

The genesis parameters for the test networks were still Bitcoin's, while BTGS uses its own timestamp message:

"The Times 31/Mar/2026 BTGSG Chancellor on brink of second bailout for banks"

A different message means a different coinbase, a different merkle root and therefore a different block hash. Bitcoin's nonces no longer satisfy the proof of work for these chains. The hashes they actually produce are:

network nBits old nonce resulting hash meets PoW
testnet 0x1d00ffff 414098458 4d7af693712b8ff7... no
signet 0x1e0377ae 52613770 2d63e799bcb90364... no
regtest 0x207fffff 2 f612acbdbffba76f... no

testnet4 did start, but only because it kept Bitcoin's timestamp message and output script verbatim, so its genesis was literally Bitcoin's testnet4 genesis rather than a BTGS one.

The eight hashGenesisBlock and hashMerkleRoot asserts were commented out in these four networks. Those asserts are exactly what would have caught this on the first run. Mainnet has them active, and mainnet is correct. With them disabled the node accepted a genesis block that does not meet its own proof of work, and the failure only surfaced later as a block read error, which points at the wrong part of the code.

Fix

Mined new nonces using the BTGS genesis message, so each chain gets its own genesis block:

network nTime nonce genesis hash
testnet 1296688603 640026520 00000000dec2f478c7277b937818c3ad7515ce9ca7c9a5f8f6345e5c18f78381
testnet4 1714777861 453240970 000000001d07bb1394fd589dbd041c1618cde63ba6d611e7b1f0c82678f58697
signet 1598918400 8705482 000002e46f9760f1d878dab0735f04a592c8d4bcdb6bfcd9c7b321f54e2e8ba7
regtest 1296688602 0 7bb66a7fba8df679c927b239aa09d5f40ce6600eb8aea11b915bb7844517969a

Merkle root for all four: 9349824da96d7c3c2a9e8a5ab54b61e14df2c77788b0b25aaa178545362bebc8

testnet4 now uses the standard CreateGenesisBlock overload with the BTGS message, replacing the inherited Bitcoin message and script.

All eight asserts are re-enabled. If a genesis is ever wrong again, the node will refuse to start instead of starting broken.

Mainnet is not touched. Its genesis, its nonce and its asserts are unchanged.

Verification

Built from this commit and started the node on all five networks:

[mainnet ] OK  0000000d1c5a497963a46c0348cb4346779c52d9e1d7cc8b5efb1be0a4a0f964
[testnet ] OK  00000000dec2f478c7277b937818c3ad7515ce9ca7c9a5f8f6345e5c18f78381
[testnet4] OK  000000001d07bb1394fd589dbd041c1618cde63ba6d611e7b1f0c82678f58697
[signet  ] OK  000002e46f9760f1d878dab0735f04a592c8d4bcdb6bfcd9c7b321f54e2e8ba7
[regtest ] OK  7bb66a7fba8df679c927b239aa09d5f40ce6600eb8aea11b915bb7844517969a

Since the asserts are runtime checks, the fact that all five networks start is itself the proof that the values are correct. A wrong genesis would abort at startup.

Also created a chain from scratch on regtest and mined 101 blocks:

altura inicial : 0
address        : bcrtg1qrd43lrxufurejwssqp27u54pzsvr3tnuulmvmg
tras minar 101 : 101
balance        : 2500000.00000000 BTGS

That is what makes test/functional/ usable. The 204 functional tests in the repo all run on regtest, so none of them can execute today.

Notes

Branched from the v30.2.3 tag as requested. v30.2.3 is an ancestor of main, so this applies cleanly.

Reported and discussed with @Annonone on Discord before opening.

Happy to adjust anything, and glad to test further changes on all networks.

The genesis parameters for all four test networks were still Bitcoins,
while BTGS uses its own timestamp message:

  "The Times 31/Mar/2026 BTGSG Chancellor on brink of second bailout for banks"

A different message means a different coinbase, a different merkle root and
therefore a different block hash, so Bitcoins nonces no longer satisfy the
proof of work for these chains. The node writes the genesis block and then
fails to read it back:

  [error] Errors in block header at FlatFilePos(nFile=0, nPos=8) while reading block
  [error] A fatal internal error occurred: Failed to read block.
  [error] Failed to connect best block (Failed to read block.)

This is why -regtest, -testnet and -signet could not start at all. testnet4
did start, but only because it kept Bitcoins message and script verbatim, so
its genesis was literally Bitcoins testnet4 genesis rather than a BTGS one.

Mined new nonces for the four networks using the BTGS genesis message, so
each chain now has its own genesis:

  testnet    nTime 1296688603  nonce 640026520
  testnet4   nTime 1714777861  nonce 453240970
  signet     nTime 1598918400  nonce 8705482
  regtest    nTime 1296688602  nonce 0

testnet4 now uses the standard CreateGenesisBlock overload with the BTGS
message, replacing the inherited Bitcoin message and script.

Re-enabled the eight hashGenesisBlock and hashMerkleRoot asserts that were
commented out in these four networks. Those asserts are what would have
caught this on the first run: mainnet has them active and mainnet is correct.
With them commented out the node accepted a genesis block that does not meet
its own proof of work, and the failure only surfaced later as a block read
error, which points at the wrong place.

Mainnet is not touched. Its genesis, its nonce and its asserts are unchanged.

Verified by building from this commit and starting the node on all five
networks:

  mainnet   0000000d1c5a497963a46c0348cb4346779c52d9e1d7cc8b5efb1be0a4a0f964
  testnet   00000000dec2f478c7277b937818c3ad7515ce9ca7c9a5f8f6345e5c18f78381
  testnet4  000000001d07bb1394fd589dbd041c1618cde63ba6d611e7b1f0c82678f58697
  signet    000002e46f9760f1d878dab0735f04a592c8d4bcdb6bfcd9c7b321f54e2e8ba7
  regtest   7bb66a7fba8df679c927b239aa09d5f40ce6600eb8aea11b915bb7844517969a

Also mined 101 blocks on regtest and confirmed the coinbase matures, which
means the functional test suite in test/functional/ can run for the first
time.
@BTGSCOINDEV
BTGSCOINDEV merged commit 3553d5a into BTGSCOINDEV:main Aug 21, 2026
1 check passed
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.

2 participants