Skip to content

Commit b3d6afc

Browse files
authored
dgb: won_share_inputs seam — share-side half of the #82 faithful reconstruct closure (#279)
The won-block reconstruct closure the run-loop installs as ShareTracker::m_on_block_found is today an interim nullopt stub. The faithful path (reconstruct_won_block_from_template) needs five inputs; two of them the won share carries verbatim and version-agnostically: small_header (m_min_header) and merkle_link (m_merkle_link). Add dgb::coin::won_share_inputs(share) -> {small_header, merkle_link}: a pure read of already-validated share_info fields (no PoW / coinbase commitment / share format / PPLNS touched; p2pool-merged-v36 surface NONE). Duck-typed on the share to stay off share.hpp tracker/base_uint TU (the limited-TU build trap). Binds to the live dgb::Share in the run-loop once the remaining inputs (gentx/gentx_hash inverse-of-out_gentx, template_other_txs retention) land. +2 KATs into dgb_reconstruct_won_block_test (existing target, no allowlist churn): verbatim extraction, and seam-output drives a byte-identical block to passing the fields directly. 9/9 PASS. Fenced to src/impl/dgb/. Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
1 parent 7e0a0a5 commit b3d6afc

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#pragma once
2+
// ---------------------------------------------------------------------------
3+
// dgb::coin::won_share_inputs -- the SHARE-SIDE half of the #82 faithful
4+
// won-block reconstruct closure (the closure the run-loop installs as
5+
// ShareTracker::m_on_block_found, today an interim nullopt stub in
6+
// main_dgb.cpp). reconstruct_won_block_from_template (reconstruct_won_block.hpp)
7+
// needs five inputs to frame a broadcastable block:
8+
//
9+
// { small_header, merkle_link, gentx, gentx_hash, template_other_txs }
10+
//
11+
// Two of them the won share ALREADY CARRIES verbatim, version-agnostically:
12+
//
13+
// small_header = share.m_min_header (coin::SmallBlockHeaderType)
14+
// merkle_link = share.m_merkle_link (::dgb::MerkleLink)
15+
//
16+
// This seam pulls exactly those two. It touches no PoW, coinbase commitment,
17+
// share format, or PPLNS math, so the p2pool-merged-v36 surface is NONE -- it
18+
// is a pure read of already-validated share_info fields.
19+
//
20+
// The remaining three inputs land as their own slices and bind in the run-loop
21+
// once they arrive:
22+
// * gentx + gentx_hash -- the inverse of the generate_share_transaction
23+
// out_gentx SSOT exposure (#173): GentxCoinbase{bytes,txid} -> a
24+
// MutableTransaction (the next reconstruct brick);
25+
// * template_other_txs -- the captured-GBT template-retention seam (#271:
26+
// the won block's non-coinbase set is the current_work snapshot the miner
27+
// was handed, NOT the share's tx_hash_refs), empty today, fills as the
28+
// embedded mempool tx-selection lands.
29+
//
30+
// Duck-typed on the share so this header stays OFF share.hpp's
31+
// tracker/base_uint translation unit (the #143 limited-TU build trap) -- any
32+
// type exposing m_min_header (SmallBlockHeaderType) and m_merkle_link
33+
// (::dgb::MerkleLink) binds; in the run-loop, the live dgb::Share.
34+
//
35+
// Per-coin isolation: src/impl/dgb/ only.
36+
// ---------------------------------------------------------------------------
37+
38+
#include "block_assembly.hpp" // coin::SmallBlockHeaderType (re-exported)
39+
#include "../share_types.hpp" // ::dgb::MerkleLink
40+
41+
namespace dgb
42+
{
43+
namespace coin
44+
{
45+
46+
// The two reconstruct inputs a won share carries verbatim.
47+
struct WonShareInputs
48+
{
49+
SmallBlockHeaderType small_header; // <- share.m_min_header
50+
::dgb::MerkleLink merkle_link; // <- share.m_merkle_link
51+
};
52+
53+
// Extract them. Templated on the share to keep this off share.hpp's heavy TU;
54+
// binds to dgb::Share in the run-loop.
55+
template <class ShareT>
56+
inline WonShareInputs won_share_inputs(const ShareT& share)
57+
{
58+
return WonShareInputs{ share.m_min_header, share.m_merkle_link };
59+
}
60+
61+
} // namespace coin
62+
} // namespace dgb

src/impl/dgb/test/reconstruct_won_block_test.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <util/strencodings.h>
3131

3232
#include "../coin/reconstruct_won_block.hpp"
33+
#include "../coin/won_share_inputs.hpp"
3334

3435
using dgb::coin::reconstruct_won_block;
3536
using dgb::coin::reconstruct_won_block_from_template;
@@ -41,6 +42,8 @@ using dgb::coin::BlockType;
4142
using dgb::coin::SmallBlockHeaderType;
4243
using dgb::coin::MutableTransaction;
4344
using dgb::TxHashRefs;
45+
using dgb::coin::won_share_inputs;
46+
using dgb::coin::WonShareInputs;
4447

4548
namespace {
4649

@@ -314,4 +317,77 @@ TEST(DgbReconstructWonBlock, EmptyTemplateGentxOnly)
314317
EXPECT_EQ(got.hex, HexStr(sp));
315318
}
316319

320+
321+
// --- Test 7: won_share_inputs extracts the two share-carried inputs verbatim --
322+
// The share-side half of the faithful reconstruct closure: a won share carries
323+
// small_header (m_min_header) + merkle_link (m_merkle_link) verbatim. The seam
324+
// is a pure read -- no field is transformed, reordered, or dropped.
325+
TEST(DgbReconstructWonBlock, WonShareInputsExtractsHeaderAndMerkleLink)
326+
{
327+
// Minimal duck-typed stand-in for dgb::Share (keeps this TU off share.hpp's
328+
// tracker/base_uint TU, per won_share_inputs.hpp's #143 note). Exposes the
329+
// two members won_share_inputs reads by name.
330+
struct FakeShare {
331+
SmallBlockHeaderType m_min_header;
332+
::dgb::MerkleLink m_merkle_link;
333+
};
334+
335+
FakeShare s;
336+
s.m_min_header = make_small_header();
337+
s.m_merkle_link.m_branch = { H("b0"), H("b1") };
338+
s.m_merkle_link.m_index = 0;
339+
340+
WonShareInputs got = won_share_inputs(s);
341+
342+
EXPECT_EQ(got.small_header.m_version, s.m_min_header.m_version);
343+
EXPECT_EQ(got.small_header.m_previous_block, s.m_min_header.m_previous_block);
344+
EXPECT_EQ(got.small_header.m_timestamp, s.m_min_header.m_timestamp);
345+
EXPECT_EQ(got.small_header.m_bits, s.m_min_header.m_bits);
346+
EXPECT_EQ(got.small_header.m_nonce, s.m_min_header.m_nonce);
347+
ASSERT_EQ(got.merkle_link.m_branch.size(), 2u);
348+
EXPECT_EQ(got.merkle_link.m_branch[0], H("b0"));
349+
EXPECT_EQ(got.merkle_link.m_branch[1], H("b1"));
350+
EXPECT_EQ(got.merkle_link.m_index, 0u);
351+
}
352+
353+
// --- Test 8: won_share_inputs feeds reconstruct_won_block_from_template -------
354+
// End-to-end seam check: the extracted {small_header, merkle_link} drive a block
355+
// byte-identical to passing those same fields directly. Proves the share-side
356+
// seam is a faithful pass-through into the won-block framing path -- the run-loop
357+
// closure may source small_header/merkle_link via won_share_inputs(share) with
358+
// no change to the reconstructed block.
359+
TEST(DgbReconstructWonBlock, WonShareInputsDrivesTemplateReconstructIdentically)
360+
{
361+
struct FakeShare {
362+
SmallBlockHeaderType m_min_header;
363+
::dgb::MerkleLink m_merkle_link;
364+
};
365+
366+
FakeShare s;
367+
s.m_min_header = make_small_header();
368+
// Non-empty link so the merkle-root math actually consumes it.
369+
s.m_merkle_link.m_branch = { H("b0") };
370+
s.m_merkle_link.m_index = 0;
371+
372+
auto gentx = make_gentx();
373+
auto gh = fixed_gentx_hash();
374+
std::vector<MutableTransaction> template_txs = { make_tx(11), make_tx(22) };
375+
376+
WonShareInputs in = won_share_inputs(s);
377+
378+
auto via_seam = reconstruct_won_block_from_template(
379+
in.small_header, in.merkle_link, gentx, gh, template_txs);
380+
auto direct = reconstruct_won_block_from_template(
381+
s.m_min_header, s.m_merkle_link, gentx, gh, template_txs);
382+
383+
EXPECT_EQ(via_seam.bytes, direct.bytes);
384+
EXPECT_EQ(via_seam.hex, direct.hex);
385+
386+
PackStream ps(via_seam.bytes);
387+
BlockType blk;
388+
ps >> blk;
389+
ASSERT_EQ(blk.m_txs.size(), 3u); // gentx + 2 template txs
390+
EXPECT_EQ(blk.m_txs[0].vin[0].prevout.index, 0xffffffffu);
391+
}
317392
} // namespace
393+

0 commit comments

Comments
 (0)