Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/impl/dgb/coin/won_share_inputs.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once
// ---------------------------------------------------------------------------
// dgb::coin::won_share_inputs -- the SHARE-SIDE half of the #82 faithful
// won-block reconstruct closure (the closure the run-loop installs as
// ShareTracker::m_on_block_found, today an interim nullopt stub in
// main_dgb.cpp). reconstruct_won_block_from_template (reconstruct_won_block.hpp)
// needs five inputs to frame a broadcastable block:
//
// { small_header, merkle_link, gentx, gentx_hash, template_other_txs }
//
// Two of them the won share ALREADY CARRIES verbatim, version-agnostically:
//
// small_header = share.m_min_header (coin::SmallBlockHeaderType)
// merkle_link = share.m_merkle_link (::dgb::MerkleLink)
//
// This seam pulls exactly those two. It touches no PoW, coinbase commitment,
// share format, or PPLNS math, so the p2pool-merged-v36 surface is NONE -- it
// is a pure read of already-validated share_info fields.
//
// The remaining three inputs land as their own slices and bind in the run-loop
// once they arrive:
// * gentx + gentx_hash -- the inverse of the generate_share_transaction
// out_gentx SSOT exposure (#173): GentxCoinbase{bytes,txid} -> a
// MutableTransaction (the next reconstruct brick);
// * template_other_txs -- the captured-GBT template-retention seam (#271:
// the won block's non-coinbase set is the current_work snapshot the miner
// was handed, NOT the share's tx_hash_refs), empty today, fills as the
// embedded mempool tx-selection lands.
//
// Duck-typed on the share so this header stays OFF share.hpp's
// tracker/base_uint translation unit (the #143 limited-TU build trap) -- any
// type exposing m_min_header (SmallBlockHeaderType) and m_merkle_link
// (::dgb::MerkleLink) binds; in the run-loop, the live dgb::Share.
//
// Per-coin isolation: src/impl/dgb/ only.
// ---------------------------------------------------------------------------

#include "block_assembly.hpp" // coin::SmallBlockHeaderType (re-exported)
#include "../share_types.hpp" // ::dgb::MerkleLink

namespace dgb
{
namespace coin
{

// The two reconstruct inputs a won share carries verbatim.
struct WonShareInputs
{
SmallBlockHeaderType small_header; // <- share.m_min_header
::dgb::MerkleLink merkle_link; // <- share.m_merkle_link
};

// Extract them. Templated on the share to keep this off share.hpp's heavy TU;
// binds to dgb::Share in the run-loop.
template <class ShareT>
inline WonShareInputs won_share_inputs(const ShareT& share)
{
return WonShareInputs{ share.m_min_header, share.m_merkle_link };
}

} // namespace coin
} // namespace dgb
76 changes: 76 additions & 0 deletions src/impl/dgb/test/reconstruct_won_block_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <util/strencodings.h>

#include "../coin/reconstruct_won_block.hpp"
#include "../coin/won_share_inputs.hpp"

using dgb::coin::reconstruct_won_block;
using dgb::coin::reconstruct_won_block_from_template;
Expand All @@ -41,6 +42,8 @@ using dgb::coin::BlockType;
using dgb::coin::SmallBlockHeaderType;
using dgb::coin::MutableTransaction;
using dgb::TxHashRefs;
using dgb::coin::won_share_inputs;
using dgb::coin::WonShareInputs;

namespace {

Expand Down Expand Up @@ -314,4 +317,77 @@ TEST(DgbReconstructWonBlock, EmptyTemplateGentxOnly)
EXPECT_EQ(got.hex, HexStr(sp));
}


// --- Test 7: won_share_inputs extracts the two share-carried inputs verbatim --
// The share-side half of the faithful reconstruct closure: a won share carries
// small_header (m_min_header) + merkle_link (m_merkle_link) verbatim. The seam
// is a pure read -- no field is transformed, reordered, or dropped.
TEST(DgbReconstructWonBlock, WonShareInputsExtractsHeaderAndMerkleLink)
{
// Minimal duck-typed stand-in for dgb::Share (keeps this TU off share.hpp's
// tracker/base_uint TU, per won_share_inputs.hpp's #143 note). Exposes the
// two members won_share_inputs reads by name.
struct FakeShare {
SmallBlockHeaderType m_min_header;
::dgb::MerkleLink m_merkle_link;
};

FakeShare s;
s.m_min_header = make_small_header();
s.m_merkle_link.m_branch = { H("b0"), H("b1") };
s.m_merkle_link.m_index = 0;

WonShareInputs got = won_share_inputs(s);

EXPECT_EQ(got.small_header.m_version, s.m_min_header.m_version);
EXPECT_EQ(got.small_header.m_previous_block, s.m_min_header.m_previous_block);
EXPECT_EQ(got.small_header.m_timestamp, s.m_min_header.m_timestamp);
EXPECT_EQ(got.small_header.m_bits, s.m_min_header.m_bits);
EXPECT_EQ(got.small_header.m_nonce, s.m_min_header.m_nonce);
ASSERT_EQ(got.merkle_link.m_branch.size(), 2u);
EXPECT_EQ(got.merkle_link.m_branch[0], H("b0"));
EXPECT_EQ(got.merkle_link.m_branch[1], H("b1"));
EXPECT_EQ(got.merkle_link.m_index, 0u);
}

// --- Test 8: won_share_inputs feeds reconstruct_won_block_from_template -------
// End-to-end seam check: the extracted {small_header, merkle_link} drive a block
// byte-identical to passing those same fields directly. Proves the share-side
// seam is a faithful pass-through into the won-block framing path -- the run-loop
// closure may source small_header/merkle_link via won_share_inputs(share) with
// no change to the reconstructed block.
TEST(DgbReconstructWonBlock, WonShareInputsDrivesTemplateReconstructIdentically)
{
struct FakeShare {
SmallBlockHeaderType m_min_header;
::dgb::MerkleLink m_merkle_link;
};

FakeShare s;
s.m_min_header = make_small_header();
// Non-empty link so the merkle-root math actually consumes it.
s.m_merkle_link.m_branch = { H("b0") };
s.m_merkle_link.m_index = 0;

auto gentx = make_gentx();
auto gh = fixed_gentx_hash();
std::vector<MutableTransaction> template_txs = { make_tx(11), make_tx(22) };

WonShareInputs in = won_share_inputs(s);

auto via_seam = reconstruct_won_block_from_template(
in.small_header, in.merkle_link, gentx, gh, template_txs);
auto direct = reconstruct_won_block_from_template(
s.m_min_header, s.m_merkle_link, gentx, gh, template_txs);

EXPECT_EQ(via_seam.bytes, direct.bytes);
EXPECT_EQ(via_seam.hex, direct.hex);

PackStream ps(via_seam.bytes);
BlockType blk;
ps >> blk;
ASSERT_EQ(blk.m_txs.size(), 3u); // gentx + 2 template txs
EXPECT_EQ(blk.m_txs[0].vin[0].prevout.index, 0xffffffffu);
}
} // namespace

Loading