Skip to content

Commit cd2fb11

Browse files
authored
dgb(test): pin LIVE make_coin_params subsidy_func binding (#334)
The era-boundary tests trust kSubsidyFunc, a hand-written duplicate of params.hpp p.subsidy_func. They pin the schedule math but are blind to a regression in the actual production wiring: if make_coin_params() shipped subsidy_func unbound (work source logs subsidy_func=UNSET, embedded coinbasevalue silently degrades to the external-GBT-only path) or bound it to the wrong function, every existing test would still pass off its private copy. Add DgbCoinParams.SubsidyFuncBoundToOracleScheduleInProduction: pull the real make_coin_params(false).subsidy_func, assert it is bound, and that it reproduces the oracle schedule at every reward-era boundary. Fenced test-only (src/impl/dgb/test/), no consensus-value change; extends an existing CI target so no allowlist/drift-guard change. Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
1 parent 02180c5 commit cd2fb11

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

src/impl/dgb/test/work_source_test.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <impl/dgb/coin/mempool.hpp>
1919
#include <impl/dgb/coin/connection_coinbase.hpp> // build_connection_coinbase_from_pplns (SSOT under test)
2020
#include <impl/dgb/config_coin.hpp> // dgb::CoinParams::subsidy (oracle SSOT)
21+
#include <impl/dgb/params.hpp> // dgb::make_coin_params -- the LIVE production binding
2122

2223
#include <core/pow.hpp> // core::SubsidyFunc
2324

@@ -460,6 +461,28 @@ TEST(DgbWorkSource, CoinbaseValueHonorsGbtVerbatim)
460461
}
461462

462463

464+
// Production-binding guard. The era-boundary tests above trust kSubsidyFunc, a
465+
// hand-written DUPLICATE of params.hpp p.subsidy_func: they pin the schedule
466+
// math but are blind to a regression in the ACTUAL wiring. If make_coin_params()
467+
// shipped subsidy_func unbound (the work source then logs subsidy_func=UNSET and
468+
// the embedded coinbasevalue silently falls through to the GBT-only path) or
469+
// bound it to the wrong function, every test above would still pass off its
470+
// private copy. Pin the LIVE production binding directly.
471+
TEST(DgbCoinParams, SubsidyFuncBoundToOracleScheduleInProduction)
472+
{
473+
const core::CoinParams p = dgb::make_coin_params(/*testnet=*/false);
474+
ASSERT_TRUE(static_cast<bool>(p.subsidy_func))
475+
<< "make_coin_params shipped subsidy_func UNSET -- embedded coinbasevalue "
476+
"would silently degrade to the external-GBT-only path";
477+
for (const auto& v : kEraBoundaries) {
478+
EXPECT_EQ(p.subsidy_func(v.height), v.subsidy)
479+
<< "production subsidy_func diverged from oracle subsidy at " << v.era;
480+
EXPECT_EQ(p.subsidy_func(v.height), kSubsidyFunc(v.height))
481+
<< "production binding diverged from the schedule under test at " << v.era;
482+
}
483+
}
484+
485+
463486
// previousblockhash: emitted as GBT-conventional big-endian display hex ONLY
464487
// when the HeaderChain carries a real tip hash (tip_hash() accessor). With a
465488
// known tip block_hash, the template surfaces it MSB-limb-first; bits stays

0 commit comments

Comments
 (0)