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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:
core_test sharechain_test share_test btc_share_test \
test_threading test_weights \
test_header_chain test_mempool test_template_builder \
test_doge_chain test_compact_blocks test_dash_x11_kat test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly \
test_doge_chain test_compact_blocks test_dash_x11_kat test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity \
test_multiaddress_pplns test_pplns_stress \
test_hash_link test_decay_pplns \
test_pplns_consensus \
Expand Down Expand Up @@ -252,7 +252,7 @@ jobs:
test_threading test_weights \
test_header_chain test_mempool test_template_builder \
test_doge_chain test_compact_blocks test_dash_x11_kat \
test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly \
test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity \
test_hash_link test_decay_pplns \
test_pplns_consensus \
test_v36_script_sorting test_v36_cross_impl_refhash \
Expand Down
14 changes: 14 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,20 @@ if (BUILD_TESTING AND GTest_FOUND)
target_link_libraries(test_dash_stratum_binding PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39)
gtest_add_tests(test_dash_stratum_binding "" AUTO)

# DASH G1 difficulty / vardiff PARITY KAT: share-diff floor byte-exactness +
# per-share min_work (target_to_average_attempts) oracle pin. Header-only over
# core/target_utils + config_pool; pure, socket-free. Mirrors the work_target
# link set.
add_executable(test_dash_difficulty_parity test_dash_difficulty_parity.cpp)
target_link_libraries(test_dash_difficulty_parity PRIVATE
GTest::gtest_main GTest::gtest
dash_x11 core
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
)
target_link_libraries(test_dash_difficulty_parity PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39)
gtest_add_tests(test_dash_difficulty_parity "" AUTO)

# share_init_verify gentx hash_link byte-parity vs oracle (coinbase_payload
# VarStr prefix). Header-only over the dash_x11 + core link set; mirrors the
# test_dash_conformance link set.
Expand Down
110 changes: 110 additions & 0 deletions test/test_dash_difficulty_parity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// DASH G1 difficulty / vardiff PARITY KAT.
//
// Pins the DASH sharechain difficulty floor and its per-share work accounting
// to oracle-EXACT arithmetic from frstrtr/p2pool-dash (networks/dash.py +
// bitcoin/data.py). Two independent surfaces:
//
// 1. dash::SharechainConfig::max_target() — the share-diff floor (easiest allowed
// share target). Byte-exact to the oracle _DIFF1_TARGET (mainnet) and the
// 2**256//2**20-1 testnet floor.
// 2. chain::target_to_average_attempts(target) == 2**256 // (target+1) — the
// per-share MINIMUM work that ShareIndex accumulates from m_max_bits
// (share_chain.hpp:228). This is the quantity that drives cumulative-work
// / APS retarget parity across the chain.
//
// Every expected value is derived INDEPENDENTLY from the oracle integer formula
// (see the derive comment on each vector), NOT read back from the SUT — a true
// byte-parity pin, not a tautology. The cross-coin APS-over-chain accumulation
// is already pinned LTC-instantiated in test_compute_share_target.cpp; this KAT
// pins the DASH-specific config floor + the min_work-per-share derivation those
// oracle numbers differ on (p2pool-dash, not p2pool-ltc).
//
// Pure / socket-free / node-free: no VM200/201 dashd, no live sharechain.
// Runs on every Linux x86_64 ctest.

#include <gtest/gtest.h>

#include <core/target_utils.hpp>
#include <core/uint256.hpp>
#include <impl/dash/config_pool.hpp>

namespace {
uint288 U288(const char* h) { uint288 t; t.SetHex(h); return t; }
} // namespace

// ── 1. share-diff floor byte-exactness (networks/dash.py SHARE_MAX_TARGET) ──

// mainnet floor == 0xFFFF * 2**208 (standard bdiff difficulty-1 target).
TEST(DashDifficultyParity, MainnetMaxTargetFloorExact)
{
dash::SharechainConfig::is_testnet = false;
EXPECT_EQ(dash::SharechainConfig::max_target().GetHex(),
"00000000ffff0000000000000000000000000000000000000000000000000000");
}

// testnet floor == 2**256 // 2**20 - 1. Derive (python3):
// "%064x" % (2**256 // 2**20 - 1)
TEST(DashDifficultyParity, TestnetMaxTargetFloorExact)
{
dash::SharechainConfig::is_testnet = true;
EXPECT_EQ(dash::SharechainConfig::max_target().GetHex(),
"00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
dash::SharechainConfig::is_testnet = false;
}

// ── 2. per-share min_work = target_to_average_attempts(floor) ───────────────
//
// ShareIndex(share).min_work = target_to_average_attempts(bits_to_target(
// m_max_bits)) (share_chain.hpp:228). At the difficulty floor that reduces
// to target_to_average_attempts(max_target()).

// mainnet: attempts = 2**256 // (0xFFFF*2**208 + 1). Derive (python3):
// (2**256)//(0xFFFF*(2**208)+1) == 4295032833 == 0x100010001
TEST(DashDifficultyParity, MainnetPerShareMinWorkExact)
{
dash::SharechainConfig::is_testnet = false;
uint288 attempts = chain::target_to_average_attempts(dash::SharechainConfig::max_target());
EXPECT_EQ(attempts.GetHex(), U288("100010001").GetHex());
EXPECT_TRUE(attempts == static_cast<uint64_t>(4295032833ULL));
}

// testnet: attempts = 2**256 // (2**256//2**20). Derive (python3):
// (2**256)//((2**256//2**20-1)+1) == 1048576 == 2**20 == 0x100000
TEST(DashDifficultyParity, TestnetPerShareMinWorkExact)
{
dash::SharechainConfig::is_testnet = true;
uint288 attempts = chain::target_to_average_attempts(dash::SharechainConfig::max_target());
EXPECT_EQ(attempts.GetHex(), U288("100000").GetHex());
EXPECT_TRUE(attempts == static_cast<uint64_t>(1048576ULL));
dash::SharechainConfig::is_testnet = false;
}

// ── 3. ShareIndex min_work accumulation identity (dash floor) ───────────────
//
// Over N equal-floor shares the accumulated min_work == per_share * N, the same
// identity DeltaCache maintains (test_compute_share_target DeltaCacheAfterPruning,
// LTC). Pinned here with DASH-floor numbers so a config-floor regression is
// caught in the DASH lane directly.
TEST(DashDifficultyParity, MainnetMinWorkAccumulationIdentity)
{
dash::SharechainConfig::is_testnet = false;
uint288 per_share = chain::target_to_average_attempts(dash::SharechainConfig::max_target());
// N=199 (default real_chain window sample). Derive (python3):
// 4295032833 * 199 == 854711533767
uint288 acc = per_share * static_cast<uint64_t>(199);
EXPECT_TRUE(acc == static_cast<uint64_t>(854711533767ULL));
}

// ── 4. floor bits roundtrip (m_max_bits <-> floor target) ───────────────────
//
// ShareIndex derives min_work from m_max_bits via bits_to_target; the floor
// must survive the compact encode/decode used to carry it on the wire.
TEST(DashDifficultyParity, MainnetFloorBitsRoundtrip)
{
dash::SharechainConfig::is_testnet = false;
uint256 floor = dash::SharechainConfig::max_target();
uint32_t bits = chain::target_to_bits_upper_bound(floor);
uint256 decoded = chain::bits_to_target(bits);
EXPECT_EQ(decoded, floor); // exact roundtrip at the standard floor
EXPECT_EQ(bits >> 24, 0x1du); // 0xFFFF*2**208 -> exponent 0x1d (29 bytes)
}
Loading