Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions test/test_dash_header_chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,49 @@ TEST(DashDGWv3Kat, CheckPowAcceptsBelowTargetRejectsAbove) {
high_hash.SetHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
EXPECT_FALSE(check_pow(high_hash, 0x1e0ffff0, pow_limit));
}

// ── Real-node KAT: DASH testnet3 DGW-v3 retarget at height 1497944 ──────────
// Live counterpart to the hand-derived synthetic vectors above. The 24 real
// ancestors 1497920..1497943 (genuine bits + timestamps captured from a synced
// testnet3 dashd; verified to contain no min-difficulty / pow-limit resets, so
// the pure DarkGravityWave path applies) must reproduce the bits the node
// itself assigned to block 1497944, namely 0x1e00f256. A divergence here is a
// real consensus drift vs live Dash, not a synthetic-arithmetic quibble.
TEST(DashDGWv3Kat, RealTestnet3Window1497944ReproducesNextBits) {
struct Row { uint32_t height; uint32_t bits; uint32_t time; };
static const Row rows[] = {
{1497920u, 0x1e01279eu, 1781733608u}, {1497921u, 0x1e010524u, 1781733780u},
{1497922u, 0x1e00fa0eu, 1781734122u}, {1497923u, 0x1e010475u, 1781734381u},
{1497924u, 0x1e0101a5u, 1781734502u}, {1497925u, 0x1e01061bu, 1781734507u},
{1497926u, 0x1e00fcd3u, 1781734513u}, {1497927u, 0x1e00f77bu, 1781734560u},
{1497928u, 0x1e00e365u, 1781735022u}, {1497929u, 0x1e010157u, 1781735130u},
{1497930u, 0x1e00fa44u, 1781735136u}, {1497931u, 0x1e00eb8au, 1781735361u},
{1497932u, 0x1e00eda8u, 1781735637u}, {1497933u, 0x1e00fb31u, 1781735760u},
{1497934u, 0x1e00f824u, 1781736070u}, {1497935u, 0x1e00fa74u, 1781736216u},
{1497936u, 0x1e00faccu, 1781736245u}, {1497937u, 0x1e00f8deu, 1781736267u},
{1497938u, 0x1e00f49bu, 1781736600u}, {1497939u, 0x1e01013au, 1781736614u},
{1497940u, 0x1e00fa45u, 1781736710u}, {1497941u, 0x1e00fb8au, 1781736758u},
{1497942u, 0x1e00f3b6u, 1781737051u}, {1497943u, 0x1e00f4c3u, 1781737080u},
};
auto ancestor = [&](uint32_t h) -> std::optional<IndexEntry> {
for (const auto& r : rows) {
if (r.height == h) {
IndexEntry e;
e.height = r.height;
e.header.m_bits = r.bits;
e.header.m_timestamp = r.time;
return e;
}
}
return std::nullopt;
};

// testnet3 params: target_spacing 150 and pow_limit identical to mainnet, so
// the DGW arithmetic is the same; allow_min_difficulty is not consulted by
// the pure dark_gravity_wave() (it gates the validation layer, not the avg).
auto params = make_dash_chain_params_testnet();
uint32_t bits = dark_gravity_wave(ancestor, /*tip_height=*/1497943u, params);
EXPECT_EQ(bits, 0x1e00f256u)
<< "DGW-v3 over the real 1497920..1497943 window must reproduce the "
"node-assigned bits of block 1497944";
}
30 changes: 30 additions & 0 deletions test/test_dash_x11_kat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,33 @@ TEST(DashX11Kat, Deterministic) {
EXPECT_EQ(dash::crypto::hash_x11(header, 80).GetHex(),
dash::crypto::hash_x11(header, 80).GetHex());
}

// ── Real-node KAT: DASH testnet3 block #1497944 ─────────────────────────────
// Captured from a fully-synced testnet3 dashd (getblockheader RPC; blocks==
// headers, initialblockdownload=false). Hashing the real 80-byte header with
// X11 must reproduce the block hash the node reports. Unlike the static mainnet
// genesis above, this pins the pipeline against live-mined consensus data.
TEST(DashX11Kat, Testnet3Block1497944ReproducesBlockHash) {
constexpr uint32_t version = 536870912u;
constexpr uint32_t time = 1781737170u;
constexpr uint32_t bits = 0x1e00f256u;
constexpr uint32_t nonce = 721236u;
const char* prev_hex = "000000dbbc08ee519459b38b02bb7754b455dd00cd74069a1352f08f0dd986db";
const char* merkle_hex = "0464a4ac5f058a742f6aa42b2b3c7489abde7609b529612bcfa5da34b10bdb1b";
const char* expected = "000000b6a4e5ea1a0854ef83f0028dde5b96cdaacc604decd8b064d0cea38234";

uint256 prev_block; prev_block.SetHex(prev_hex);
uint256 merkle_root; merkle_root.SetHex(merkle_hex);

unsigned char header[80];
size_t off = 0;
std::memcpy(header + off, &version, 4); off += 4;
std::memcpy(header + off, prev_block.data(), 32); off += 32;
std::memcpy(header + off, merkle_root.data(), 32); off += 32;
std::memcpy(header + off, &time, 4); off += 4;
std::memcpy(header + off, &bits, 4); off += 4;
std::memcpy(header + off, &nonce, 4); off += 4;

uint256 pow = dash::crypto::hash_x11(header, sizeof(header));
EXPECT_EQ(pow.GetHex(), expected);
}
Loading