@@ -1522,4 +1522,51 @@ TEST(NmcPFConsensusParams, TestnetRetargetAndMagicPinned)
15221522 EXPECT_EQ (p.p2p_magic , kMagic ); // CTestNetParams pchMessageStart
15231523}
15241524
1525+ // ── AuxPoW chain-id SSOT conformance (PF) ───────────────────────────────────
1526+ //
1527+ // Locks the merge-mining chain id against namecoin-core nAuxpowChainId.
1528+ // chain_id is a BUCKET-1 ISOLATION PRIMITIVE (per-coin namespacing of the
1529+ // parent merged-mining slot): pinned per coin, NEVER standardized away. The
1530+ // verify side (HeaderChain::verify_auxpow_header -> AuxPow::check_proof) reads
1531+ // m_params.aux_chain_id, and the embedded build side (AuxChainEmbedded) casts
1532+ // the SAME field into AuxWork.chain_id. A single drift in the factory default
1533+ // silently breaks the build<->verify slot binding on BOTH sides, while the
1534+ // hand-set fixtures above (which force aux_chain_id = 1) keep passing. These
1535+ // KATs pin the FACTORY OUTPUT, not a hand-set fixture, so factory drift reds.
1536+ //
1537+ // Source: Namecoin Core src/kernel/chainparams.cpp -- nAuxpowChainId = 0x0001
1538+ // on BOTH mainnet and testnet (NOT Dogecoin 0x0062).
1539+
1540+ TEST (NmcAuxChainIdConformance, SSOTConstantMatchesNamecoinCore)
1541+ {
1542+ EXPECT_EQ (nmc::coin::NMC_AUXPOW_CHAIN_ID , 0x0001u );
1543+ EXPECT_NE (nmc::coin::NMC_AUXPOW_CHAIN_ID , 0x0062u ); // != DOGE chain id
1544+ }
1545+
1546+ TEST (NmcAuxChainIdConformance, MainnetFactoryEmitsSSOT)
1547+ {
1548+ NMCChainParams p = NMCChainParams::mainnet ();
1549+ EXPECT_EQ (p.aux_chain_id , static_cast <int32_t >(nmc::coin::NMC_AUXPOW_CHAIN_ID ));
1550+ EXPECT_EQ (p.aux_chain_id , 1 );
1551+ }
1552+
1553+ TEST (NmcAuxChainIdConformance, TestnetFactoryEmitsSSOT)
1554+ {
1555+ // Namecoin uses the SAME aux chain id (0x0001) on testnet as mainnet.
1556+ NMCChainParams p = NMCChainParams::testnet ();
1557+ EXPECT_EQ (p.aux_chain_id , static_cast <int32_t >(nmc::coin::NMC_AUXPOW_CHAIN_ID ));
1558+ EXPECT_EQ (p.aux_chain_id , 1 );
1559+ }
1560+
1561+ TEST (NmcAuxChainIdConformance, BuildVerifySymmetryOnFactoryDefault)
1562+ {
1563+ // Build side casts m_params.aux_chain_id -> uint32_t AuxWork.chain_id;
1564+ // verify side passes m_params.aux_chain_id as expected_chain_id into
1565+ // check_proof. Pin that the factory default is no -1 sentinel and survives
1566+ // the uint32_t cast the build path performs -- both sides agree on 1u.
1567+ NMCChainParams p = NMCChainParams::mainnet ();
1568+ EXPECT_GE (p.aux_chain_id , 0 ); // not the -1 unpinned sentinel
1569+ EXPECT_EQ (static_cast <uint32_t >(p.aux_chain_id ), 1u ); // build-side AuxWork.chain_id
1570+ }
1571+
15251572} // namespace
0 commit comments