Skip to content

Commit d5df40d

Browse files
committed
dgb: delegate redistribute PPLNS-window guard onto get_height_and_last SSOT
Rewire refresh_pplns_cache's inline window guard in redistribute.hpp onto the get_height_and_last_endpoints.hpp SSOT (PR #414): depth = std::min(height, real_chain_length()) -> dgb::pplns_window_depth(...) if (depth < 1) return; -> if (!dgb::pplns_window_active(depth)) return; Byte-identical: pplns_window_depth is std::min and pplns_window_active is depth>=1, so !active == depth<1. No reward-distribution value change. Proof: dgb_redistribute_delegate_ghal_test re-derives the verbatim inline std::min/(depth<1) directly (non-circular) and asserts the SSOT call reproduces it across a height matrix straddling negative/0/1/RCL+-1, both nets. 3/3 green; prod dgb_redistribute_test 8/8 unchanged. FENCED dgb/ only. Target in CMake + both build.yml allowlist arms.
1 parent f3a67ae commit d5df40d

4 files changed

Lines changed: 92 additions & 4 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 nmc_mempool_name_test nmc_block_broadcast_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 dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_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 dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_get_height_and_last_endpoints_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 dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_get_height_and_last_endpoints_test dgb_redistribute_delegate_ghal_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 nmc_mempool_name_test nmc_block_broadcast_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 dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_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 dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress dgb_get_height_and_last_endpoints_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 dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress dgb_get_height_and_last_endpoints_test dgb_redistribute_delegate_ghal_test \
220220
v37_test \
221221
-j$(nproc)
222222

src/impl/dgb/redistribute.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "config_pool.hpp"
2323
#include "share_tracker.hpp"
2424
#include "share_check.hpp"
25+
#include "coin/get_height_and_last_endpoints.hpp"
2526

2627
#include <core/log.hpp>
2728
#include <core/target_utils.hpp>
@@ -450,8 +451,8 @@ class Redistributor
450451
return;
451452

452453
auto [height, last] = tracker.chain.get_height_and_last(best);
453-
int32_t depth = std::min(height, static_cast<int32_t>(PoolConfig::real_chain_length()));
454-
if (depth < 1)
454+
int32_t depth = dgb::pplns_window_depth(height, static_cast<int32_t>(PoolConfig::real_chain_length()));
455+
if (!dgb::pplns_window_active(depth))
455456
return;
456457

457458
struct AccumEntry { std::vector<unsigned char> script; uint160 hash; uint8_t type; uint64_t weight; };

src/impl/dgb/test/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,18 @@ if (BUILD_TESTING AND GTest_FOUND)
763763
core
764764
c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage)
765765
gtest_add_tests(dgb_get_height_and_last_endpoints_test "" AUTO)
766+
767+
# dgb_redistribute_delegate_ghal_test: FENCED, additive byte-identity proof
768+
# that redistribute.hpp's PPLNS-window guard was rewired onto the SSOT
769+
# coin/get_height_and_last_endpoints.hpp with NO value change. Non-circular:
770+
# re-derives the inline std::min/(depth<1) directly. MUST also be in the
771+
# build.yml --target allowlist (#143 NOT_BUILT trap).
772+
add_executable(dgb_redistribute_delegate_ghal_test redistribute_delegate_ghal_test.cpp)
773+
target_link_libraries(dgb_redistribute_delegate_ghal_test PRIVATE
774+
GTest::gtest_main GTest::gtest
775+
core
776+
c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage)
777+
gtest_add_tests(dgb_redistribute_delegate_ghal_test "" AUTO)
766778
# dgb_pool_efficiency_test: FENCED, additive KAT pinning the pool
767779
# EFFICIENCY / REAL-HASHRATE diagnostics arithmetic in pool_efficiency.hpp vs
768780
# the p2pool main.py status-loop oracle (stale_prop = (orphan+doa)/total;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// dgb redistribute -> get_height_and_last SSOT byte-identity DELEGATION KAT.
2+
//
3+
// FENCED, additive. Pins the runtime rewire of redistribute.hpp:454-455
4+
// (refresh_pplns_cache PPLNS-window guard) onto the SSOT free functions in
5+
// coin/get_height_and_last_endpoints.hpp. The SSOT itself is proven against the
6+
// p2pool-dgb-scrypt oracle by dgb_get_height_and_last_endpoints_test; this slice
7+
// proves only that swapping the inline expression for the SSOT call changed
8+
// NOTHING -- i.e. the rewire is value-identical, no reward-distribution drift.
9+
//
10+
// PRE-delegation inline (verbatim, from git history of redistribute.hpp):
11+
// int32_t depth = std::min(height, static_cast<int32_t>(real_chain_length()));
12+
// if (depth < 1) return; // early-out: window inactive
13+
// POST-delegation (current redistribute.hpp:454-455):
14+
// int32_t depth = dgb::pplns_window_depth(height, real_chain_length());
15+
// if (!dgb::pplns_window_active(depth)) return;
16+
//
17+
// NON-CIRCULAR: the "expected" side below recomputes std::min(...)/(depth < 1)
18+
// directly from the operands -- it does NOT call the SSOT under test. We then
19+
// assert the SSOT call reproduces that inline result across a height matrix that
20+
// straddles every boundary (negative, 0, 1, REAL_CHAIN_LENGTH-1/=/+1).
21+
// MUST appear in BOTH this dir CMakeLists.txt AND the build.yml --target
22+
// allowlist, or it becomes a #143 NOT_BUILT sentinel.
23+
24+
#include <impl/dgb/coin/get_height_and_last_endpoints.hpp>
25+
26+
#include <gtest/gtest.h>
27+
#include <algorithm>
28+
#include <cstdint>
29+
30+
using namespace dgb;
31+
32+
static constexpr int32_t CL_MAIN = 2880; // REAL_CHAIN_LENGTH mainnet
33+
static constexpr int32_t CL_TEST = 400; // REAL_CHAIN_LENGTH testnet
34+
35+
// The verbatim pre-delegation inline expression, re-implemented here so the
36+
// expectation is independent of the code under test.
37+
static int32_t inline_depth(int32_t height, int32_t rcl) {
38+
return std::min(height, static_cast<int32_t>(rcl));
39+
}
40+
static bool inline_early_return(int32_t depth) {
41+
return depth < 1;
42+
}
43+
44+
static void check_one(int32_t height, int32_t rcl) {
45+
const int32_t want_depth = inline_depth(height, rcl);
46+
const bool want_ret = inline_early_return(want_depth);
47+
48+
const int32_t got_depth = pplns_window_depth(height, rcl);
49+
const bool got_ret = !pplns_window_active(got_depth);
50+
51+
EXPECT_EQ(got_depth, want_depth)
52+
<< "depth diverged at height=" << height << " rcl=" << rcl;
53+
EXPECT_EQ(got_ret, want_ret)
54+
<< "early-return diverged at height=" << height << " rcl=" << rcl;
55+
}
56+
57+
TEST(DgbRedistributeDelegateGhal, DepthMatchesInlineMainnet) {
58+
for (int32_t h : {-5, -1, 0, 1, 2, 10, 1440, CL_MAIN - 1, CL_MAIN, CL_MAIN + 1, 100000})
59+
check_one(h, CL_MAIN);
60+
}
61+
62+
TEST(DgbRedistributeDelegateGhal, DepthMatchesInlineTestnet) {
63+
for (int32_t h : {-5, -1, 0, 1, 2, 10, 200, CL_TEST - 1, CL_TEST, CL_TEST + 1, 100000})
64+
check_one(h, CL_TEST);
65+
}
66+
67+
// Boundary spot-checks pinned to absolute values (no SSOT call on the expected
68+
// side) -- the window is INACTIVE iff clamped depth < 1, ACTIVE from height 1 up.
69+
TEST(DgbRedistributeDelegateGhal, ActivationBoundaryAbsolute) {
70+
EXPECT_TRUE (!pplns_window_active(pplns_window_depth(0, CL_MAIN))); // depth 0 -> inactive
71+
EXPECT_FALSE(!pplns_window_active(pplns_window_depth(1, CL_MAIN))); // depth 1 -> active
72+
EXPECT_FALSE(!pplns_window_active(pplns_window_depth(CL_MAIN, CL_MAIN))); // clamped, active
73+
EXPECT_TRUE (!pplns_window_active(pplns_window_depth(-3, CL_MAIN))); // negative -> inactive
74+
EXPECT_EQ(pplns_window_depth(CL_MAIN + 50, CL_MAIN), CL_MAIN); // clamp to RCL
75+
}

0 commit comments

Comments
 (0)