|
| 1 | +#pragma once |
| 2 | +// run_loop_mint.hpp — DGB Phase B: worker->mint adapter SSOT. |
| 3 | +// |
| 4 | +// This is the consumer adapter that DGBWorkSource::MintShareFn binds to in |
| 5 | +// main_dgb.cpp (work_source.hpp:197 "binds this to mint_local_share_with_ratchet |
| 6 | +// (run_loop_mint.hpp) -> create_local_share"). When mining_submit classifies a |
| 7 | +// submission as ShareAccept (Scrypt PoW meets the SHARE target but NOT the full |
| 8 | +// block target), try_mint_share() invokes this with the assembled MintShareInputs. |
| 9 | +// It: |
| 10 | +// 1. parses the 80-byte reconstructed block header into a SmallBlockHeaderType, |
| 11 | +// 2. asks the live AutoRatchet for the {mint, vote} version pair via |
| 12 | +// dgb_select_mint_versions (anchored at the current sharechain tip = the |
| 13 | +// new share's parent), and |
| 14 | +// 3. inserts the share into the tracker via create_local_share, returning the |
| 15 | +// minted share hash (NULL uint256 on a malformed header / fail-closed). |
| 16 | +// |
| 17 | +// History: this helper was authored under #294 and lost from master in the |
| 18 | +// #292/#293/#294 stacked squash-merge (no #294 merge commit reaches master; the |
| 19 | +// underlying primitives dgb_select_mint_versions + create_local_share survive). |
| 20 | +// Re-landed here to its documented contract against master's create_local_share |
| 21 | +// signature, which is authoritative. |
| 22 | +// |
| 23 | +// PURE adapter: the helper takes references and performs ONE tracker insertion. |
| 24 | +// Thread-safety of that insertion is the CALLER's concern — main_dgb binds this |
| 25 | +// on the Stratum-submission thread and is responsible for the tracker lock. |
| 26 | +// |
| 27 | +// Duck-typed on the inputs (InputsT) so this header does NOT pull the stratum |
| 28 | +// work_source TU in: any struct exposing { header_bytes, coinbase_bytes, subsidy, |
| 29 | +// prev_share, merkle_branches, payout_script, segwit_active } binds — in |
| 30 | +// production that is DGBWorkSource::MintShareInputs. |
| 31 | + |
| 32 | +#include <optional> |
| 33 | +#include <vector> |
| 34 | + |
| 35 | +#include <core/pack.hpp> // PackStream, operator>> |
| 36 | +#include <core/pack_types.hpp> // BaseScript |
| 37 | +#include <core/uint256.hpp> |
| 38 | + |
| 39 | +#include <impl/dgb/coin/block.hpp> // SmallBlockHeaderType, BlockHeaderType |
| 40 | +#include <impl/dgb/share_check.hpp> // create_local_share, MergedAddressEntry, StaleInfo, uint128 |
| 41 | +#include <impl/dgb/auto_ratchet_wire.hpp> // dgb_select_mint_versions, AutoRatchet |
| 42 | + |
| 43 | +namespace dgb { |
| 44 | + |
| 45 | +// Parse a canonical 80-byte block header (fixed 4-byte version + merkle_root) |
| 46 | +// into the SmallBlockHeaderType (version|prev|time|bits|nonce) create_local_share |
| 47 | +// consumes. Returns nullopt on a short/malformed buffer (fail-closed). Pure. |
| 48 | +inline std::optional<coin::SmallBlockHeaderType> |
| 49 | +parse_min_header_80(const std::vector<unsigned char>& header_bytes) |
| 50 | +{ |
| 51 | + if (header_bytes.size() < 80) |
| 52 | + return std::nullopt; |
| 53 | + try { |
| 54 | + PackStream ps(header_bytes); |
| 55 | + coin::BlockHeaderType full; |
| 56 | + ps >> full; |
| 57 | + // SmallBlockHeaderType is the base subobject of BlockHeaderType; slicing |
| 58 | + // off m_merkle_root yields exactly the small-header fields. |
| 59 | + return static_cast<coin::SmallBlockHeaderType&>(full); |
| 60 | + } catch (const std::exception&) { |
| 61 | + return std::nullopt; // truncated / unserialize failure -> fail-closed |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +// The worker->mint adapter. Returns the minted share hash, or NULL uint256 if |
| 66 | +// the header is malformed (fail-closed; the caller logs a no-record outcome). |
| 67 | +template <typename TrackerT, typename InputsT> |
| 68 | +inline uint256 mint_local_share_with_ratchet( |
| 69 | + const InputsT& in, |
| 70 | + TrackerT& tracker, |
| 71 | + const core::CoinParams& params, |
| 72 | + AutoRatchet& ratchet, |
| 73 | + uint16_t donation = 50) |
| 74 | +{ |
| 75 | + auto min_header = parse_min_header_80(in.header_bytes); |
| 76 | + if (!min_header) |
| 77 | + return uint256(); // fail-closed: malformed 80-byte header |
| 78 | + |
| 79 | + BaseScript coinbase(in.coinbase_bytes); |
| 80 | + |
| 81 | + // The new share's parent is the current sharechain tip carried by the |
| 82 | + // submission; the ratchet decides which {mint, vote} version pair to stamp. |
| 83 | + const uint256 best_share = in.prev_share; |
| 84 | + auto [mint_version, vote_version] = |
| 85 | + dgb_select_mint_versions(ratchet, tracker, best_share); |
| 86 | + |
| 87 | + return create_local_share( |
| 88 | + tracker, params, *min_header, coinbase, in.subsidy, in.prev_share, |
| 89 | + in.merkle_branches, in.payout_script, |
| 90 | + donation, |
| 91 | + std::vector<MergedAddressEntry>{}, // merged_addrs (DOGE aux: none in Scrypt-only) |
| 92 | + StaleInfo::none, // stale_info |
| 93 | + in.segwit_active, // segwit_active |
| 94 | + std::string{}, // witness_commitment_hex |
| 95 | + std::vector<unsigned char>{}, // message_data |
| 96 | + std::vector<unsigned char>{}, // actual_coinbase_bytes |
| 97 | + uint256(), // witness_root |
| 98 | + 0u, // override_max_bits |
| 99 | + 0u, // override_bits |
| 100 | + 0u, // frozen_absheight |
| 101 | + uint128(), // frozen_abswork |
| 102 | + uint256(), // frozen_far_share_hash |
| 103 | + 0u, // frozen_timestamp |
| 104 | + uint256(), // frozen_merged_payout_hash |
| 105 | + false, // has_frozen |
| 106 | + std::vector<uint256>{}, // frozen_merkle_branches |
| 107 | + uint256(), // frozen_witness_root |
| 108 | + std::vector<unsigned char>{}, // frozen_merged_coinbase_info |
| 109 | + static_cast<int64_t>(mint_version), // share_version (ratchet-selected) |
| 110 | + static_cast<uint64_t>(vote_version)); // desired_version (always target) |
| 111 | +} |
| 112 | + |
| 113 | +} // namespace dgb |
0 commit comments