From df3f6c66799f69e9c4da1d20655dd71e25ad8935 Mon Sep 17 00:00:00 2001 From: frstrtr Date: Fri, 19 Jun 2026 21:19:29 +0000 Subject: [PATCH] nmc(P1 PE 2b-ii): pin NMC P2P network magic SSOT in NMCChainParams Add NMCChainParams::p2p_magic (4-byte pchMessageStart), the frame prefix every parent-NMC P2P message carries. The embedded won-block broadcaster (PE) needs it to talk the NMC wire protocol; a wrong/zero magic makes namecoind drop the peer on EOF before the handshake completes (the failure main_bch.cpp:138 documents for BCH). Values sourced from namecoin-core src/kernel/chainparams.cpp pchMessageStart, NOT from memory: mainnet CMainParams = f9 be b4 fe testnet3 CTestNetParams = fa bf b5 fe (pairs with the testnet3 genesis time=1296688602 pinned in 2b-0) New NmcP1Genesis.P2PMagicPinned KAT asserts both magics + their inequality (net-isolation primitive). Rides the allowlisted nmc_auxpow_wire_test exe -> no build.yml change. SSOT for a follow-on host get_chain_p2p_prefix wire slice (shared-host hunk, operator-tap). Mainnet GENESIS stays TO-CONFIRM pending a mainnet namecoind; magic is a published network constant. Fence: src/impl/nmc/ only. --- src/impl/nmc/coin/header_chain.hpp | 16 ++++++++++++++++ src/impl/nmc/test/auxpow_wire_test.cpp | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) 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