diff --git a/src/impl/nmc/coin/header_chain.hpp b/src/impl/nmc/coin/header_chain.hpp index 054877145..ddeb71ec6 100644 --- a/src/impl/nmc/coin/header_chain.hpp +++ b/src/impl/nmc/coin/header_chain.hpp @@ -45,6 +45,7 @@ #include // P1 PC: core::coin::DEFAULT_MAX_TIP_AGE (is_synced) #include +#include #include #include #include @@ -511,6 +512,12 @@ struct NMCChainParams { bool no_retargeting{false}; uint256 pow_limit; uint256 genesis_hash; + // P2P network magic (Namecoin Core pchMessageStart). The 4-byte frame + // prefix every parent-NMC P2P message carries; the embedded won-block + // broadcaster (PE) needs it to talk the NMC wire protocol. SSOT for the + // host get_chain_p2p_prefix table (a follow-on host slice references this). + // Sourced from namecoin-core src/kernel/chainparams.cpp, NOT from memory. + std::array p2p_magic{}; // ── Merge-mining consensus parameters ── // @@ -554,6 +561,11 @@ struct NMCChainParams { p.pow_limit.SetHex("00000000ffff0000000000000000000000000000000000000000000000000000"); // TO-CONFIRM: Namecoin mainnet genesis hash (placeholder = null). p.genesis_hash.SetNull(); + // P2P magic PINNED: namecoin-core kernel/chainparams.cpp CMainParams + // pchMessageStart = { 0xf9, 0xbe, 0xb4, 0xfe }. (Magic is a published + // network constant, distinct from the genesis hash which stays + // TO-CONFIRM pending a mainnet namecoind.) + p.p2p_magic = {{ 0xf9, 0xbe, 0xb4, 0xfe }}; // TO-CONFIRM: activation height + chain id stay unpinned (-1). return p; } @@ -571,6 +583,10 @@ struct NMCChainParams { // (getblockhash 0 / getblockheader, 2026-06-19). block_hash(genesis_header) // re-derives this value (nmc_auxpow_wire_test GenesisTestnet KAT). p.genesis_hash.SetHex("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"); + // P2P magic PINNED: namecoin-core kernel/chainparams.cpp CTestNetParams + // pchMessageStart = { 0xfa, 0xbf, 0xb5, 0xfe } (testnet3 -- matches the + // pinned testnet3 genesis time=1296688602 above; testnet4 differs). + p.p2p_magic = {{ 0xfa, 0xbf, 0xb5, 0xfe }}; return p; } diff --git a/src/impl/nmc/test/auxpow_wire_test.cpp b/src/impl/nmc/test/auxpow_wire_test.cpp index 4c9f397eb..52a23529a 100644 --- a/src/impl/nmc/test/auxpow_wire_test.cpp +++ b/src/impl/nmc/test/auxpow_wire_test.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -283,4 +284,26 @@ TEST(NmcP1Genesis, TestnetHeaderRederivesPinnedHash) EXPECT_EQ(params.aux_chain_id, 1); // Namecoin nAuxpowChainId = 0x0001 } +// --------------------------------------------------------------------------- +// P2P network-magic pin KAT (P1 PE 2b-ii). NMCChainParams::p2p_magic is the +// 4-byte frame prefix the embedded won-block broadcaster (PE) puts on every +// parent-NMC P2P message. Pinned from namecoin-core src/kernel/chainparams.cpp +// (pchMessageStart), NOT from memory: a wrong byte makes namecoind drop the +// peer on EOF (handshake never completes) -- the same failure main_bch.cpp:138 +// documents for a zero/garbage magic. Testnet3 magic must pair with the +// testnet3 genesis pinned above (time=1296688602); testnet4 magic differs. +// --------------------------------------------------------------------------- +TEST(NmcP1Genesis, P2PMagicPinned) +{ + const std::array kMain{{0xf9, 0xbe, 0xb4, 0xfe}}; + const std::array kTest{{0xfa, 0xbf, 0xb5, 0xfe}}; + + EXPECT_EQ(nmc::coin::NMCChainParams::mainnet().p2p_magic, kMain); + EXPECT_EQ(nmc::coin::NMCChainParams::testnet().p2p_magic, kTest); + + // Mainnet and testnet must NOT share a magic (network isolation primitive). + EXPECT_NE(nmc::coin::NMCChainParams::mainnet().p2p_magic, + nmc::coin::NMCChainParams::testnet().p2p_magic); +} + } // namespace