Skip to content

Commit 2f252e4

Browse files
authored
Merge pull request #294 from frstrtr/dgb/run-loop-mint-bind
dgb: bind AutoRatchet {mint,vote} selector to the share-mint path (Phase B)
2 parents c55c250 + 431b5cb commit 2f252e4

2 files changed

Lines changed: 112 additions & 0 deletions

File tree

src/impl/dgb/run_loop_mint.hpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
// run_loop_mint.hpp — DGB Phase B pool/share: the live create_local_share()
4+
// caller that the AutoRatchet {mint, vote} selector feeds.
5+
//
6+
// auto_ratchet_wire.hpp resolves the {share_version_to_mint,
7+
// desired_version_to_vote} pair (oracle baseline 35, target 36). Until now that
8+
// pair was computed only in tests; the share-mint path still defaulted
9+
// create_local_share()'s trailing version arguments to a hardcoded 36/36, which
10+
// would make a freshly-started node skip ahead of the network and mint V36
11+
// shares the older DGB sharechain cannot accept.
12+
//
13+
// This seam closes that gap: it is the ONE place the run-loop asks the ratchet
14+
// for the version pair and stamps it onto the share it is about to create. It
15+
// adds NO new policy — get_share_version() already owns the work-weighted gate
16+
// (#249/#289). The create step is injected (CreateFn) rather than called
17+
// directly so this glue stays free of the ~30-argument create_local_share()
18+
// surface: the run-loop binds every other field, this helper only chooses, and
19+
// forwards, the version pair. Fenced, header-only, non-consensus glue over the
20+
// already-tap-reviewed selector.
21+
22+
#include <cstdint>
23+
#include <utility>
24+
25+
#include "auto_ratchet_wire.hpp" // dgb_select_mint_versions, AutoRatchet
26+
#include <core/uint256.hpp> // uint256 (also via auto_ratchet_wire)
27+
28+
namespace dgb
29+
{
30+
31+
// Ask the ratchet for {mint, vote}, then hand them to the caller-supplied
32+
// create step (which binds them to create_local_share's trailing
33+
// share_version / desired_version arguments). Returns the create step's result
34+
// verbatim — typically the new share hash. The chosen versions are NEVER a
35+
// hardcoded constant: a VOTING node mints DGB_BASE_VERSION (35) while voting
36+
// DGB_TARGET_VERSION (36), and follows the state machine thereafter.
37+
//
38+
// CreateFn signature: R(int64_t share_version, uint64_t desired_version).
39+
template <class CreateFn>
40+
inline auto mint_local_share_with_ratchet(
41+
AutoRatchet& ratchet,
42+
ShareTracker& tracker,
43+
const uint256& best_share_hash,
44+
CreateFn&& create_with_versions)
45+
-> decltype(create_with_versions(int64_t{0}, uint64_t{0}))
46+
{
47+
auto [mint, vote] = dgb_select_mint_versions(ratchet, tracker, best_share_hash);
48+
return std::forward<CreateFn>(create_with_versions)(
49+
mint, static_cast<uint64_t>(vote));
50+
}
51+
52+
} // namespace dgb

src/impl/dgb/test/share_test.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <impl/dgb/coin/rpc_conf.hpp> // #82 external-daemon RPC creds (digibyte.conf)
2323
#include <impl/dgb/auto_ratchet.hpp> // Phase B: mint-side share-version ratchet
2424
#include <impl/dgb/auto_ratchet_wire.hpp> // Phase B: production wire-in (base_version=35)
25+
#include <impl/dgb/run_loop_mint.hpp> // Phase B: run-loop {mint,vote} binding
2526
#include <unistd.h> // getpid (AutoRatchet KAT temp state file)
2627

2728
#include <cstdio>
@@ -465,3 +466,62 @@ TEST(DGB_share_test, AutoRatchetWireBootstrapMints35Votes36)
465466
EXPECT_EQ(vote, 36); // always vote target
466467
EXPECT_EQ(ar.state(), dgb::RatchetState::VOTING);
467468
}
469+
470+
// ---------------------------------------------------------------------------
471+
// Run-loop mint binding (run_loop_mint.hpp) — Phase B pool/share.
472+
// Proves the live create_local_share() caller stamps the version pair the
473+
// AutoRatchet selector returns, NOT a hardcoded 36/36. A bootstrap (VOTING,
474+
// empty tracker) node must mint the DGB baseline 35 while voting 36.
475+
// ---------------------------------------------------------------------------
476+
TEST(DGB_share_test, RunLoopMintBindsRatchetVersionsNotHardcoded)
477+
{
478+
auto ar = dgb::make_dgb_ratchet();
479+
dgb::ShareTracker tracker;
480+
481+
int64_t seen_share_version = -1;
482+
uint64_t seen_desired_version = 0;
483+
uint256 sentinel; sentinel.SetHex(
484+
"00000000000000000000000000000000000000000000000000000000deadbeef");
485+
486+
// Inject a spy create-step: capture the version pair the helper forwards,
487+
// return a sentinel hash so we can also confirm pass-through.
488+
uint256 got = dgb::mint_local_share_with_ratchet(
489+
ar, tracker, uint256{},
490+
[&](int64_t sv, uint64_t dv) -> uint256 {
491+
seen_share_version = sv;
492+
seen_desired_version = dv;
493+
return sentinel;
494+
});
495+
496+
EXPECT_EQ(seen_share_version, 35); // ratchet baseline (oracle), NOT 36
497+
EXPECT_EQ(seen_desired_version, 36u); // always vote target
498+
EXPECT_NE(seen_share_version, seen_desired_version); // 35 != 36: both fields
499+
// independently threaded
500+
EXPECT_EQ(got, sentinel); // result returned verbatim
501+
EXPECT_EQ(ar.state(), dgb::RatchetState::VOTING);
502+
}
503+
504+
// The helper must not consult/alter the ratchet beyond get_share_version — a
505+
// second call on the same VOTING state yields the same pair (idempotent stamp).
506+
TEST(DGB_share_test, RunLoopMintStampIsStableWhileVoting)
507+
{
508+
auto ar = dgb::make_dgb_ratchet();
509+
dgb::ShareTracker tracker;
510+
511+
auto stamp = [&]() {
512+
std::pair<int64_t, uint64_t> p{0, 0};
513+
dgb::mint_local_share_with_ratchet(
514+
ar, tracker, uint256{},
515+
[&](int64_t sv, uint64_t dv) -> uint256 {
516+
p = {sv, dv};
517+
return uint256{};
518+
});
519+
return p;
520+
};
521+
522+
auto a = stamp();
523+
auto b = stamp();
524+
EXPECT_EQ(a, b);
525+
EXPECT_EQ(a.first, 35);
526+
EXPECT_EQ(a.second, 36u);
527+
}

0 commit comments

Comments
 (0)