Skip to content

Commit 27bd1a6

Browse files
authored
Merge pull request #384 from frstrtr/dgb/g1-oracle-byte-parity
dgb(G1): oracle byte-parity KAT — net/consensus constants + isolation primitives
2 parents 5e9f9b5 + b1ee0c3 commit 27bd1a6

3 files changed

Lines changed: 139 additions & 2 deletions

File tree

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
8585
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test \
8686
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
87-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test v37_test \
87+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test v37_test \
8888
-j$(nproc)
8989
9090
- name: Run tests
@@ -216,7 +216,7 @@ jobs:
216216
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
217217
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test \
218218
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
219-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
219+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
220220
v37_test \
221221
-j$(nproc)
222222

src/impl/dgb/test/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,19 @@ if (BUILD_TESTING AND GTest_FOUND)
563563
dgb_coin pool sharechain)
564564
gtest_add_tests(dgb_share_target_genesis_test "" AUTO)
565565

566+
# dgb_g1_oracle_byte_parity_test: FENCED greenlight-gate G1 KAT. Pins the
567+
# assembled make_coin_params() net/consensus constants AND bucket-1
568+
# isolation primitives (PREFIX/IDENTIFIER) against oracle-transcribed
569+
# literals from frstrtr/p2pool-dgb-scrypt (non-circular). MUST also be in
570+
# the build.yml --target allowlist (#143).
571+
add_executable(dgb_g1_oracle_byte_parity_test g1_oracle_byte_parity_test.cpp)
572+
target_link_libraries(dgb_g1_oracle_byte_parity_test PRIVATE
573+
GTest::gtest_main GTest::gtest
574+
core dgb
575+
c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage
576+
dgb_coin pool sharechain)
577+
gtest_add_tests(dgb_g1_oracle_byte_parity_test "" AUTO)
578+
566579
# dgb_pool_msg_wire_test: FENCED conformance KAT for the pool P2P wire-message
567580
# layer (messages.hpp) — command-name parity, scalar LE byte pins, and
568581
# serialize/read-back field equality vs p2pool-merged-v36 message numbering.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// G1 greenlight-gate KAT — DGB net/consensus byte-parity vs the oracle.
2+
//
3+
// FENCED conformance test (no production code touched). This is the test-form
4+
// artifact of greenlight gate G1 (per dgb-greenlight-g0-artifact): it pins the
5+
// fully-assembled dgb::make_coin_params() output — every isolation primitive
6+
// (bucket-1: PREFIX / IDENTIFIER) and every consensus/net constant — against
7+
// values hand-transcribed from the DGB oracle frstrtr/p2pool-dgb-scrypt
8+
// (operator switch-oracle ruling 2026-06-17, Option B):
9+
// networks/digibyte.py — coin params, ports, address versions, MAX_TARGET
10+
// bitcoin/p2p.py:28 — Protocol.VERSION (advertised) = 3501
11+
// bitcoin/networks ... — IDENTIFIER 4B62545B1A631AFE, PREFIX, SHARE_PERIOD
12+
//
13+
// NON-CIRCULAR: the expected side below is literal bytes/ints typed from the
14+
// oracle python source, NOT a second read of the same C++ SUT constant. A drift
15+
// in config_coin.hpp / config_pool.hpp that silently diverges from the oracle
16+
// fails here even though every other dgb test (which sources the same SUT
17+
// constant on both sides) stays green.
18+
//
19+
// 3-bucket posture (operator 2026-06-17): IDENTIFIER + PREFIX are bucket-1
20+
// ISOLATION PRIMITIVES — pinned here as the per-coin/per-instance sharechain
21+
// namespacing boundary; this KAT guards them against accidental
22+
// "standardization", it does NOT propose unifying them.
23+
//
24+
// MUST appear in BOTH the ctest registration (this dir CMakeLists.txt) AND the
25+
// build.yml --target allowlist, or it becomes a #143-style NOT_BUILT sentinel.
26+
27+
#include <impl/dgb/params.hpp>
28+
29+
#include <core/coin_params.hpp>
30+
31+
#include <string>
32+
33+
#include <gtest/gtest.h>
34+
35+
namespace {
36+
37+
// ---- Oracle expected values (frstrtr/p2pool-dgb-scrypt, transcribed) --------
38+
39+
// networks/digibyte.py PARENT + pool block
40+
constexpr char ORACLE_SYMBOL[] = "DGB";
41+
constexpr uint16_t ORACLE_P2P_PORT = 5024; // sharechain P2P
42+
constexpr uint16_t ORACLE_WORKER_PORT = 5025; // Stratum
43+
constexpr uint8_t ORACLE_ADDR_VERSION_MAIN = 30; // 0x1e, "D"
44+
constexpr uint8_t ORACLE_ADDR_P2SH_MAIN = 63; // 0x3f, "S"
45+
constexpr uint8_t ORACLE_ADDR_VERSION_TEST = 126; // 0x7e
46+
constexpr uint32_t ORACLE_SHARE_PERIOD = 15; // s
47+
constexpr uint32_t ORACLE_CHAIN_LENGTH = 2880; // 12h / 15s
48+
constexpr uint32_t ORACLE_SPREAD = 24;
49+
constexpr uint32_t ORACLE_TARGET_LOOKBEHIND = 100;
50+
constexpr uint32_t ORACLE_MIN_PROTO_VERSION = 1700; // digibyte.py NEW_MIN (accept-floor)
51+
constexpr uint32_t ORACLE_ADV_PROTO_VERSION = 3501; // p2p.py:28 Protocol.VERSION
52+
constexpr uint32_t ORACLE_SEGWIT_ACT_VERSION = 35; // digibyte.py:27
53+
constexpr uint64_t ORACLE_DUST_THRESHOLD = 100000; // 0.001 DGB
54+
55+
// IDENTIFIER / PREFIX — bucket-1 isolation primitives, same on both nets.
56+
constexpr char ORACLE_IDENTIFIER_HEX[] = "4b62545b1a631afe";
57+
constexpr char ORACLE_PREFIX_HEX[] = "1c0553f23ebfcffe";
58+
59+
// MAX_TARGET = 2**256 // 2**20 - 1 == 2^236 - 1 (digibyte.py).
60+
// 236 one-bits = 59 'f' nibbles, with the top 20 bits (5 nibbles) zero.
61+
uint256 oracle_max_target() {
62+
uint256 t;
63+
t.SetHex(std::string(5, '0') + std::string(59, 'f')); // 5+59 = 64 nibbles
64+
return t;
65+
}
66+
67+
TEST(G1OracleByteParity, MainnetNetConstants) {
68+
core::CoinParams p = dgb::make_coin_params(/*testnet=*/false);
69+
70+
EXPECT_EQ(p.symbol, ORACLE_SYMBOL);
71+
EXPECT_EQ(p.p2p_port, ORACLE_P2P_PORT);
72+
EXPECT_EQ(p.worker_port, ORACLE_WORKER_PORT);
73+
EXPECT_EQ(p.address_version, ORACLE_ADDR_VERSION_MAIN);
74+
EXPECT_EQ(p.address_p2sh_version, ORACLE_ADDR_P2SH_MAIN);
75+
EXPECT_EQ(p.share_period, ORACLE_SHARE_PERIOD);
76+
EXPECT_EQ(p.chain_length, ORACLE_CHAIN_LENGTH);
77+
EXPECT_EQ(p.real_chain_length, ORACLE_CHAIN_LENGTH);
78+
EXPECT_EQ(p.spread, ORACLE_SPREAD);
79+
EXPECT_EQ(p.target_lookbehind, ORACLE_TARGET_LOOKBEHIND);
80+
EXPECT_EQ(p.minimum_protocol_version, ORACLE_MIN_PROTO_VERSION);
81+
EXPECT_EQ(p.advertised_protocol_version, ORACLE_ADV_PROTO_VERSION);
82+
EXPECT_EQ(p.segwit_activation_version, ORACLE_SEGWIT_ACT_VERSION);
83+
EXPECT_EQ(p.dust_threshold, ORACLE_DUST_THRESHOLD);
84+
}
85+
86+
TEST(G1OracleByteParity, IsolationPrimitivesPrefixIdentifier) {
87+
// bucket-1: never standardized; pinned per-coin on both nets.
88+
core::CoinParams p = dgb::make_coin_params(/*testnet=*/false);
89+
EXPECT_EQ(p.identifier_hex, ORACLE_IDENTIFIER_HEX);
90+
EXPECT_EQ(p.prefix_hex, ORACLE_PREFIX_HEX);
91+
EXPECT_EQ(p.testnet_identifier_hex, ORACLE_IDENTIFIER_HEX);
92+
EXPECT_EQ(p.testnet_prefix_hex, ORACLE_PREFIX_HEX);
93+
}
94+
95+
TEST(G1OracleByteParity, MaxTargetIs2Pow236Minus1) {
96+
core::CoinParams p = dgb::make_coin_params(/*testnet=*/false);
97+
EXPECT_EQ(p.max_target, oracle_max_target());
98+
}
99+
100+
TEST(G1OracleByteParity, TestnetAddressVersionDiverges) {
101+
// Testnet keeps its own address version but SHARES the isolation primitives.
102+
core::CoinParams p = dgb::make_coin_params(/*testnet=*/true);
103+
EXPECT_EQ(p.address_version, ORACLE_ADDR_VERSION_TEST);
104+
EXPECT_EQ(p.identifier_hex, ORACLE_IDENTIFIER_HEX);
105+
EXPECT_EQ(p.prefix_hex, ORACLE_PREFIX_HEX);
106+
}
107+
108+
TEST(G1OracleByteParity, DonationScriptVersionGate) {
109+
// Pre-V36 share -> forrestv P2PK (67B, 0x41 ... 0xac).
110+
auto pre = dgb::PoolConfig::get_donation_script(/*share_version=*/35);
111+
ASSERT_EQ(pre.size(), 67u);
112+
EXPECT_EQ(pre.front(), 0x41); // OP_PUSHBYTES_65
113+
EXPECT_EQ(pre.back(), 0xac); // OP_CHECKSIG
114+
EXPECT_EQ(pre[1], 0x04); // uncompressed pubkey marker
115+
116+
// V36+ share -> combined P2SH 1-of-2 (23B, 0xa9 0x14 <20B> 0x87).
117+
auto v36 = dgb::PoolConfig::get_donation_script(/*share_version=*/36);
118+
ASSERT_EQ(v36.size(), 23u);
119+
EXPECT_EQ(v36[0], 0xa9); // OP_HASH160
120+
EXPECT_EQ(v36[1], 0x14); // push 20
121+
EXPECT_EQ(v36.back(), 0x87); // OP_EQUAL
122+
}
123+
124+
} // namespace

0 commit comments

Comments
 (0)