Skip to content

Commit 5db1801

Browse files
authored
nmc(PF): pin mainnet_genesis_header() 80-byte seed from synced namecoind (#262)
Retire the deferred mainnet genesis-header seed. Fields pinned against a live SYNCED mainnet namecoind (getblockhash 0 / getblockheader <hash> false; .140 PID 5860, blocks=830010, IBD=false; 2026-06-20): version=1 time=1303000001 bits=0x1c007fff nonce=0xa21ea192 merkleroot=41c62dbd..cb0d SHA256d(header) == 000000000062b72c..c770 (mainnet genesis hash), verified locally and by the new MainnetHeaderRederivesPinnedHash KAT. The KAT asserts against the external literal hash (daemon truth), not params.genesis_hash, so it holds regardless of merge order with the mainnet genesis_hash pin (#261). Fenced to src/impl/nmc/; rides the allowlisted nmc_auxpow_wire_test exe, no build.yml touch. Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
1 parent c33ccab commit 5db1801

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/impl/nmc/coin/header_chain.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,27 @@ struct NMCChainParams {
624624
g.m_nonce = 384568319;
625625
return g;
626626
}
627+
628+
/// Namecoin MAINNET genesis header (the 80-byte parent the HeaderChain seeds
629+
/// at height 0). Fields PINNED against a live SYNCED mainnet namecoind
630+
/// (getblockhash 0 / getblockheader <hash> false, .140 PID 5860,
631+
/// blocks=830010 IBD=false, 2026-06-20):
632+
/// version=1 time=1303000001 bits=0x1c007fff nonce=0xa21ea192
633+
/// merkleroot=41c62dbd9068c89a449525e3cd5ac61b20ece28c3c38b3f35b2161f0e6d3cb0d
634+
/// SHA256d(header) == 000000000062b72c..c770 == mainnet genesis_hash
635+
/// (verified locally + by the MainnetHeaderRederivesPinnedHash KAT). This
636+
/// retires the deferred mainnet_genesis_header() seed; the expected hash is
637+
/// external daemon truth, not self-derived from the header fields.
638+
static BlockHeaderType mainnet_genesis_header() {
639+
BlockHeaderType g;
640+
g.m_previous_block.SetNull();
641+
g.m_version = 1;
642+
g.m_merkle_root.SetHex("41c62dbd9068c89a449525e3cd5ac61b20ece28c3c38b3f35b2161f0e6d3cb0d");
643+
g.m_timestamp = 1303000001;
644+
g.m_bits = 0x1c007fff;
645+
g.m_nonce = 0xa21ea192; // 2719621522
646+
return g;
647+
}
627648
};
628649

629650
// ─── Index Entry ─────────────────────────────────────────────────────────────

src/impl/nmc/test/auxpow_wire_test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,36 @@ TEST(NmcP1Genesis, TestnetHeaderRederivesPinnedHash)
284284
EXPECT_EQ(params.aux_chain_id, 1); // Namecoin nAuxpowChainId = 0x0001
285285
}
286286

287+
// ---------------------------------------------------------------------------
288+
// MAINNET genesis pin KAT (P1 PF, retires the deferred mainnet seed).
289+
// NMCChainParams::mainnet_genesis_header() is the 80-byte parent the embedded
290+
// HeaderChain seeds at height 0. Its SHA256d MUST reproduce the Namecoin
291+
// mainnet genesis hash pinned against a live SYNCED mainnet namecoind
292+
// (getblockhash 0 / getblockheader <hash> false; .140 PID 5860, blocks=830010,
293+
// IBD=false; 2026-06-20). The expected hash is asserted as an external literal,
294+
// NOT params.genesis_hash, so the guard holds regardless of merge order with
295+
// the mainnet genesis_hash pin (#261). A wrong field (endianness, bits, nonce,
296+
// merkleroot) makes the re-derived hash diverge from daemon truth.
297+
// ---------------------------------------------------------------------------
298+
TEST(NmcP1Genesis, MainnetHeaderRederivesPinnedHash)
299+
{
300+
const auto g = nmc::coin::NMCChainParams::mainnet_genesis_header();
301+
302+
EXPECT_TRUE(g.m_previous_block.IsNull());
303+
EXPECT_EQ(g.m_version, 1);
304+
EXPECT_EQ(g.m_timestamp, 1303000001u);
305+
EXPECT_EQ(g.m_bits, 0x1c007fffu);
306+
EXPECT_EQ(g.m_nonce, 0xa21ea192u);
307+
308+
uint256 expect;
309+
expect.SetHex("000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770");
310+
EXPECT_EQ(nmc::coin::block_hash(g), expect);
311+
312+
// Mainnet and testnet genesis headers must NOT collide (network isolation).
313+
EXPECT_NE(nmc::coin::block_hash(g),
314+
nmc::coin::block_hash(nmc::coin::NMCChainParams::testnet_genesis_header()));
315+
}
316+
287317
// ---------------------------------------------------------------------------
288318
// P2P network-magic pin KAT (P1 PE 2b-ii). NMCChainParams::p2p_magic is the
289319
// 4-byte frame prefix the embedded won-block broadcaster (PE) puts on every

0 commit comments

Comments
 (0)