Skip to content

Commit 29a0ce8

Browse files
committed
dgb: M3 chain-identity genesis SSOT + standalone regression guard
Factor the DigiByte genesis hashes NodeRPC::check() probes out of rpc.cpp into the rpc_request.hpp SSOT (DGB_GENESIS_MAIN/TEST + dgb_genesis_hash() selector), mirroring how the daemon-version floor was made SSOT+guarded. rpc.cpp now consumes them; the genesis hashes are a bucket-1 isolation primitive (coin-identity, KEEP per-coin v36/v37, never standardized) -- pinned here only so a standalone TU can guard them. Add test/genesis_check_test.cpp (7 cases): canonical mainnet/testnet hashes, main != test (no copy/paste), 64-hex shape, and the IS_TESTNET selector NodeRPC::check() relies on. Links only the pure SSOT header + gtest -- no boost::beast transport, builds standalone (7/7 PASS). CMake/OBJECT-lib registration of this test deferred to the post-#145 base with the rest of the transport wiring.
1 parent fc2ec32 commit 29a0ce8

3 files changed

Lines changed: 95 additions & 10 deletions

File tree

src/impl/dgb/coin/rpc.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,10 @@ namespace dgb
1212
namespace coin
1313
{
1414

15-
// DGB chain-identity probe: the DigiByte genesis hash (DigiByte Core v8.26.2
16-
// kernel/chainparams.cpp). A real digibyted answers getblockheader(genesis);
17-
// a wrong-coin daemon does not. mainnet/testnet selected by IS_TESTNET.
18-
static const char* DGB_GENESIS_MAIN =
19-
"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496";
20-
static const char* DGB_GENESIS_TEST =
21-
"308ea0711d5763be2995670dd9ca9872753561285a84da1d58be58acaa822252";
22-
23-
// DGB_MIN_DAEMON_VERSION / make_gbt_request: see impl/dgb/coin/rpc_request.hpp (oracle SSOT).
15+
// DGB chain-identity genesis hashes, DGB_MIN_DAEMON_VERSION and
16+
// make_gbt_request: see impl/dgb/coin/rpc_request.hpp (oracle/identity SSOT).
17+
// check() probes getblockheader(dgb_genesis_hash(IS_TESTNET)) to confirm the
18+
// daemon is a real digibyted on the selected network.
2419

2520
NodeRPC::NodeRPC(io::io_context* context, dgb::interfaces::Node* coin, bool testnet)
2621
: m_context(context), IS_TESTNET(testnet), m_resolver(*context), m_stream(*context),
@@ -205,7 +200,7 @@ nlohmann::json NodeRPC::CallAPIMethod(const std::string& method, const jsonrpccx
205200

206201
bool NodeRPC::check()
207202
{
208-
uint256 genesis = uint256S(IS_TESTNET ? DGB_GENESIS_TEST : DGB_GENESIS_MAIN);
203+
uint256 genesis = uint256S(dgb_genesis_hash(IS_TESTNET));
209204
bool has_block = check_blockheader(genesis);
210205
bool is_main_chain = getblockchaininfo()["chain"].get<std::string>() == "main";
211206
nlohmann::json blockchaininfo;

src/impl/dgb/coin/rpc_request.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ inline nlohmann::json make_gbt_request(const std::vector<std::string>& rules)
4949
return nlohmann::json::object({{"rules", rules}, {"algo", "scrypt"}});
5050
}
5151

52+
// DGB chain-identity genesis hashes (DigiByte Core kernel/chainparams.cpp).
53+
// NodeRPC::check() probes getblockheader(genesis) to confirm it is talking to
54+
// a real digibyted (a wrong-coin daemon does not answer). These are a bucket-1
55+
// ISOLATION PRIMITIVE -- KEEP per-coin in v36 AND v37, never standardize; they
56+
// are pinned in this SSOT only so a standalone TU can guard against accidental
57+
// drift WITHOUT linking the boost::beast transport.
58+
inline constexpr const char* DGB_GENESIS_MAIN =
59+
"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496";
60+
inline constexpr const char* DGB_GENESIS_TEST =
61+
"308ea0711d5763be2995670dd9ca9872753561285a84da1d58be58acaa822252";
62+
63+
// The genesis hash NodeRPC::check() probes for the selected network.
64+
inline const char* dgb_genesis_hash(bool testnet)
65+
{
66+
return testnet ? DGB_GENESIS_TEST : DGB_GENESIS_MAIN;
67+
}
68+
5269
} // namespace coin
5370

5471
} // namespace dgb
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// ---------------------------------------------------------------------------
2+
// dgb M3 chain-identity (genesis) regression guard.
3+
//
4+
// Pins the DigiByte genesis hashes that NodeRPC::check() probes via
5+
// getblockheader(dgb_genesis_hash(IS_TESTNET)) to confirm the external
6+
// digibyted is a real DigiByte node on the selected network. These are a
7+
// bucket-1 ISOLATION PRIMITIVE -- coin-identity, KEEP per-coin in v36 AND
8+
// v37, never standardized -- so this guard locks them against accidental
9+
// drift (a copy/paste from another coin, or main<->test swap) BEFORE the
10+
// deferred transport wiring lands post-#145 and rpc.cpp finally CI-links.
11+
//
12+
// Links ONLY the pure SSOT header (rpc_request.hpp) + gtest -- no
13+
// boost::beast/jsonrpccxx transport, so it builds standalone without
14+
// entering the dgb OBJECT lib.
15+
// ---------------------------------------------------------------------------
16+
17+
#include <cstring>
18+
19+
#include <gtest/gtest.h>
20+
21+
#include <impl/dgb/coin/rpc_request.hpp>
22+
23+
using namespace dgb::coin;
24+
25+
// Canonical values from DigiByte Core kernel/chainparams.cpp. Independent
26+
// literals so the test fails loudly if the SSOT constant is ever edited.
27+
static const char* CANON_MAIN =
28+
"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496";
29+
static const char* CANON_TEST =
30+
"308ea0711d5763be2995670dd9ca9872753561285a84da1d58be58acaa822252";
31+
32+
TEST(DgbGenesis, MainnetHashIsCanonical)
33+
{
34+
EXPECT_STREQ(DGB_GENESIS_MAIN, CANON_MAIN);
35+
}
36+
37+
TEST(DgbGenesis, TestnetHashIsCanonical)
38+
{
39+
EXPECT_STREQ(DGB_GENESIS_TEST, CANON_TEST);
40+
}
41+
42+
TEST(DgbGenesis, MainAndTestDiffer)
43+
{
44+
// Guards against a copy/paste that would make both networks probe the
45+
// same hash -- a wrong-coin daemon could then pass the testnet check.
46+
EXPECT_STRNE(DGB_GENESIS_MAIN, DGB_GENESIS_TEST);
47+
}
48+
49+
TEST(DgbGenesis, HashesAre64HexChars)
50+
{
51+
EXPECT_EQ(std::strlen(DGB_GENESIS_MAIN), 64u);
52+
EXPECT_EQ(std::strlen(DGB_GENESIS_TEST), 64u);
53+
for (const char* h : {DGB_GENESIS_MAIN, DGB_GENESIS_TEST})
54+
for (const char* c = h; *c; ++c)
55+
EXPECT_TRUE(std::isxdigit(static_cast<unsigned char>(*c))) << "non-hex in " << h;
56+
}
57+
58+
// --- Network selector NodeRPC::check() relies on ---------------------------
59+
60+
TEST(DgbGenesis, SelectorPicksMainnet)
61+
{
62+
EXPECT_STREQ(dgb_genesis_hash(false), DGB_GENESIS_MAIN);
63+
}
64+
65+
TEST(DgbGenesis, SelectorPicksTestnet)
66+
{
67+
EXPECT_STREQ(dgb_genesis_hash(true), DGB_GENESIS_TEST);
68+
}
69+
70+
TEST(DgbGenesis, SelectorBranchesDiffer)
71+
{
72+
EXPECT_STRNE(dgb_genesis_hash(true), dgb_genesis_hash(false));
73+
}

0 commit comments

Comments
 (0)