From 431b5cbec0caca92d4af367be9490559c2752744 Mon Sep 17 00:00:00 2001 From: frstrtr Date: Sun, 21 Jun 2026 10:48:40 +0000 Subject: [PATCH] dgb: bind AutoRatchet {mint,vote} selector to the share-mint path Phase B pool/share. run_loop_mint.hpp::mint_local_share_with_ratchet is the live create_local_share() caller seam: it asks dgb_select_mint_versions for the {share_version, desired_version} pair and forwards it to an injected create step, replacing the previously hardcoded 36/36 default. A bootstrap VOTING node now mints the DGB baseline 35 while voting 36, so it cannot skip ahead of the older DGB sharechain. No new policy: get_share_version owns the work-weighted gate. Header-only, injected create step keeps it off the ~30-arg create surface. +2 KAT in dgb_share_test (24/24): version pair threaded not hardcoded (35!=36 proves both fields independent), result returned verbatim, stamp stable while VOTING. --- src/impl/dgb/run_loop_mint.hpp | 52 +++++++++++++++++++++++++++ src/impl/dgb/test/share_test.cpp | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/impl/dgb/run_loop_mint.hpp diff --git a/src/impl/dgb/run_loop_mint.hpp b/src/impl/dgb/run_loop_mint.hpp new file mode 100644 index 000000000..45dd03b7f --- /dev/null +++ b/src/impl/dgb/run_loop_mint.hpp @@ -0,0 +1,52 @@ +#pragma once + +// run_loop_mint.hpp — DGB Phase B pool/share: the live create_local_share() +// caller that the AutoRatchet {mint, vote} selector feeds. +// +// auto_ratchet_wire.hpp resolves the {share_version_to_mint, +// desired_version_to_vote} pair (oracle baseline 35, target 36). Until now that +// pair was computed only in tests; the share-mint path still defaulted +// create_local_share()'s trailing version arguments to a hardcoded 36/36, which +// would make a freshly-started node skip ahead of the network and mint V36 +// shares the older DGB sharechain cannot accept. +// +// This seam closes that gap: it is the ONE place the run-loop asks the ratchet +// for the version pair and stamps it onto the share it is about to create. It +// adds NO new policy — get_share_version() already owns the work-weighted gate +// (#249/#289). The create step is injected (CreateFn) rather than called +// directly so this glue stays free of the ~30-argument create_local_share() +// surface: the run-loop binds every other field, this helper only chooses, and +// forwards, the version pair. Fenced, header-only, non-consensus glue over the +// already-tap-reviewed selector. + +#include +#include + +#include "auto_ratchet_wire.hpp" // dgb_select_mint_versions, AutoRatchet +#include // uint256 (also via auto_ratchet_wire) + +namespace dgb +{ + +// Ask the ratchet for {mint, vote}, then hand them to the caller-supplied +// create step (which binds them to create_local_share's trailing +// share_version / desired_version arguments). Returns the create step's result +// verbatim — typically the new share hash. The chosen versions are NEVER a +// hardcoded constant: a VOTING node mints DGB_BASE_VERSION (35) while voting +// DGB_TARGET_VERSION (36), and follows the state machine thereafter. +// +// CreateFn signature: R(int64_t share_version, uint64_t desired_version). +template +inline auto mint_local_share_with_ratchet( + AutoRatchet& ratchet, + ShareTracker& tracker, + const uint256& best_share_hash, + CreateFn&& create_with_versions) + -> decltype(create_with_versions(int64_t{0}, uint64_t{0})) +{ + auto [mint, vote] = dgb_select_mint_versions(ratchet, tracker, best_share_hash); + return std::forward(create_with_versions)( + mint, static_cast(vote)); +} + +} // namespace dgb diff --git a/src/impl/dgb/test/share_test.cpp b/src/impl/dgb/test/share_test.cpp index 4073bffbf..fbae6ccb2 100644 --- a/src/impl/dgb/test/share_test.cpp +++ b/src/impl/dgb/test/share_test.cpp @@ -22,6 +22,7 @@ #include // #82 external-daemon RPC creds (digibyte.conf) #include // Phase B: mint-side share-version ratchet #include // Phase B: production wire-in (base_version=35) +#include // Phase B: run-loop {mint,vote} binding #include // getpid (AutoRatchet KAT temp state file) #include @@ -465,3 +466,62 @@ TEST(DGB_share_test, AutoRatchetWireBootstrapMints35Votes36) EXPECT_EQ(vote, 36); // always vote target EXPECT_EQ(ar.state(), dgb::RatchetState::VOTING); } + +// --------------------------------------------------------------------------- +// Run-loop mint binding (run_loop_mint.hpp) — Phase B pool/share. +// Proves the live create_local_share() caller stamps the version pair the +// AutoRatchet selector returns, NOT a hardcoded 36/36. A bootstrap (VOTING, +// empty tracker) node must mint the DGB baseline 35 while voting 36. +// --------------------------------------------------------------------------- +TEST(DGB_share_test, RunLoopMintBindsRatchetVersionsNotHardcoded) +{ + auto ar = dgb::make_dgb_ratchet(); + dgb::ShareTracker tracker; + + int64_t seen_share_version = -1; + uint64_t seen_desired_version = 0; + uint256 sentinel; sentinel.SetHex( + "00000000000000000000000000000000000000000000000000000000deadbeef"); + + // Inject a spy create-step: capture the version pair the helper forwards, + // return a sentinel hash so we can also confirm pass-through. + uint256 got = dgb::mint_local_share_with_ratchet( + ar, tracker, uint256{}, + [&](int64_t sv, uint64_t dv) -> uint256 { + seen_share_version = sv; + seen_desired_version = dv; + return sentinel; + }); + + EXPECT_EQ(seen_share_version, 35); // ratchet baseline (oracle), NOT 36 + EXPECT_EQ(seen_desired_version, 36u); // always vote target + EXPECT_NE(seen_share_version, seen_desired_version); // 35 != 36: both fields + // independently threaded + EXPECT_EQ(got, sentinel); // result returned verbatim + EXPECT_EQ(ar.state(), dgb::RatchetState::VOTING); +} + +// The helper must not consult/alter the ratchet beyond get_share_version — a +// second call on the same VOTING state yields the same pair (idempotent stamp). +TEST(DGB_share_test, RunLoopMintStampIsStableWhileVoting) +{ + auto ar = dgb::make_dgb_ratchet(); + dgb::ShareTracker tracker; + + auto stamp = [&]() { + std::pair p{0, 0}; + dgb::mint_local_share_with_ratchet( + ar, tracker, uint256{}, + [&](int64_t sv, uint64_t dv) -> uint256 { + p = {sv, dv}; + return uint256{}; + }); + return p; + }; + + auto a = stamp(); + auto b = stamp(); + EXPECT_EQ(a, b); + EXPECT_EQ(a.first, 35); + EXPECT_EQ(a.second, 36u); +}