|
| 1 | +// G1 difficulty/vardiff parity KAT — DASH sharechain target byte-parity vs the |
| 2 | +// DASH oracle frstrtr/p2pool-dash (networks/dash.py). |
| 3 | +// |
| 4 | +// FENCED conformance test (no production code touched). Test-form artifact of |
| 5 | +// greenlight gate G1 for the DASH difficulty/vardiff surface, mirroring the |
| 6 | +// dgb/bch g1_oracle_byte_parity KATs but scoped to the target math the DASH |
| 7 | +// migration plan calls out as independently-landable byte-parity groundwork |
| 8 | +// (integrator 2026-07-04: proceed on the G1 difficulty/vardiff parity KAT ahead |
| 9 | +// of the operator GO on the consensus-bearing flip). |
| 10 | +// |
| 11 | +// NON-CIRCULAR posture: the difficulty-target and coin-level (net.PARENT) |
| 12 | +// expected values below are typed from the oracle python source |
| 13 | +// (p2pool/dash/networks/dash.py), NOT re-read from the C++ SUT constant. A drift |
| 14 | +// in config_pool.hpp / params.hpp that silently diverges from the oracle fails |
| 15 | +// here even though sibling dash tests (which source the same SUT constant on both |
| 16 | +// sides) stay green. |
| 17 | +// |
| 18 | +// SCOPE LINE: the p2pool *sharechain* namespacing constants (IDENTIFIER/PREFIX) |
| 19 | +// are c2pool-chosen bucket-1 isolation primitives, ABSENT from the oracle PARENT. |
| 20 | +// They are pinned in IsolationPrimitivesRegressionGuard as a pure drift guard and |
| 21 | +// are explicitly NOT asserted as oracle-conformance. |
| 22 | +// |
| 23 | +// MUST appear in BOTH the ctest registration (test/CMakeLists.txt) AND the |
| 24 | +// build.yml --target allowlist, or it becomes a #143-style NOT_BUILT sentinel. |
| 25 | + |
| 26 | +#include <impl/dash/params.hpp> |
| 27 | +#include <impl/dash/config_pool.hpp> |
| 28 | + |
| 29 | +#include <core/coin_params.hpp> |
| 30 | + |
| 31 | +#include <gtest/gtest.h> |
| 32 | + |
| 33 | +namespace { |
| 34 | + |
| 35 | +// Oracle networks/dash.py:31 _DIFF1_TARGET = 0xFFFF * 2**208 (standard bdiff |
| 36 | +// difficulty-1 target). 0xFFFF left-shifted 208 bits, big-endian 256-bit: |
| 37 | +// 8 hex zeros + "ffff" + 52 hex zeros. Derived from the oracle FORMULA, not the |
| 38 | +// SUT literal, so a hand-edit of config_pool.hpp max_target() fails this pin. |
| 39 | +uint256 oracle_diff1_target() |
| 40 | +{ |
| 41 | + uint256 t; |
| 42 | + t.SetHex("00000000ffff0000000000000000000000000000000000000000000000000000"); |
| 43 | + return t; |
| 44 | +} |
| 45 | + |
| 46 | +// max_target parity: the sharechain SSOT max_target() AND the plumbed CoinParams |
| 47 | +// field both equal the oracle bdiff-1 target. |
| 48 | +TEST(DashG1DifficultyParity, MaxTargetIsBdiff1_OracleDash) |
| 49 | +{ |
| 50 | + EXPECT_EQ(dash::SharechainConfig::max_target(), oracle_diff1_target()); |
| 51 | + core::CoinParams p = dash::make_coin_params(/*testnet=*/false); |
| 52 | + EXPECT_EQ(p.max_target, oracle_diff1_target()); |
| 53 | +} |
| 54 | + |
| 55 | +// SANE_TARGET_RANGE = (_DIFF1_TARGET//10000, _DIFF1_TARGET) (oracle dash.py:33). |
| 56 | +// Non-circular structural pins: easiest sane == max_target (oracle SANE[1]), |
| 57 | +// hardest sane is non-zero and strictly tighter than the easiest. |
| 58 | +TEST(DashG1DifficultyParity, SaneTargetRangeMatchesOracle) |
| 59 | +{ |
| 60 | + EXPECT_EQ(dash::SharechainConfig::sane_target_max(), dash::SharechainConfig::max_target()); |
| 61 | + EXPECT_NE(dash::SharechainConfig::sane_target_min(), uint256()); |
| 62 | + EXPECT_NE(dash::SharechainConfig::sane_target_min(), dash::SharechainConfig::max_target()); |
| 63 | +} |
| 64 | + |
| 65 | +// Coin-level net.PARENT parity (oracle networks/dash.py mainnet). |
| 66 | +TEST(DashG1DifficultyParity, CoinLevelParentParity) |
| 67 | +{ |
| 68 | + core::CoinParams p = dash::make_coin_params(/*testnet=*/false); |
| 69 | + EXPECT_EQ(p.symbol, "DASH"); // dash.py:22 SYMBOL |
| 70 | + EXPECT_EQ(p.block_period, 150u); // dash.py:21 BLOCK_PERIOD |
| 71 | + EXPECT_EQ(p.address_version, 76u); // dash.py:12 ADDRESS_VERSION (X...) |
| 72 | + EXPECT_EQ(p.address_p2sh_version, 16u); // dash.py:13 SCRIPT_ADDRESS_VERSION (7...) |
| 73 | + EXPECT_EQ(p.dust_threshold, 100000u); // dash.py DUST_THRESHOLD = 0.001e8 |
| 74 | +} |
| 75 | + |
| 76 | +// Testnet address divergence (oracle networks/dash_testnet.py), isolation |
| 77 | +// primitives shared — but this KAT only asserts the address versions here. |
| 78 | +TEST(DashG1DifficultyParity, TestnetAddressDiverges) |
| 79 | +{ |
| 80 | + core::CoinParams p = dash::make_coin_params(/*testnet=*/true); |
| 81 | + EXPECT_EQ(p.address_version, 140u); // testnet PUBKEY_ADDRESS (y...) |
| 82 | + EXPECT_EQ(p.address_p2sh_version, 19u); // testnet SCRIPT_ADDRESS |
| 83 | +} |
| 84 | + |
| 85 | +// Bucket-1 isolation-primitive REGRESSION GUARD — NOT oracle-conformance. |
| 86 | +// IDENTIFIER/PREFIX are c2pool-chosen sharechain namespacing (absent from the |
| 87 | +// oracle PARENT); pinned purely to catch silent namespace drift. |
| 88 | +TEST(DashG1DifficultyParity, IsolationPrimitivesRegressionGuard) |
| 89 | +{ |
| 90 | + EXPECT_EQ(dash::SharechainConfig::IDENTIFIER_HEX, "7242ef345e1bed6b"); |
| 91 | + EXPECT_EQ(dash::SharechainConfig::PREFIX_HEX, "3b3e1286f446b891"); |
| 92 | +} |
| 93 | + |
| 94 | +} // namespace |
0 commit comments