Skip to content

dgb(#82): expose SSOT gentx bytes for won-block reconstruction - #173

Merged
frstrtr merged 3 commits into
masterfrom
dgb/won-block-gentx-expose
Jun 19, 2026
Merged

dgb(#82): expose SSOT gentx bytes for won-block reconstruction#173
frstrtr merged 3 commits into
masterfrom
dgb/won-block-gentx-expose

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Stacked on #172 (dgb/gentx-coinbase-consume). Part of #82 (won-block reaches network).

What

generate_share_transaction already builds the coinbase via the SSOT assemble_gentx_coinbase (#171, proven byte-for-byte by #172) but returned only the gentx_hash, discarding the bytes. The won-block reconstructor needs the exact non-witness coinbase bytes — it is block tx[0] and its txid is the merkle leaf — not just the hash.

This adds an optional out_gentx (GentxCoinbase*, default nullptr):

  • Zero behavior change for the verification call sites (default arg).
  • Surfaces {bytes, txid} straight from the SSOT for reconstruct_won_block.

Test

New KAT in the existing #172 dgb_gentx_share_path_test (no new target → no build.yml/#143 change):

  • exposed gc.txid == returned gentx_hash; Hash(gc.bytes) == gentx_hash
  • gc.bytes deserialize into the coinbase MutableTransaction assemble_won_block consumes (null outpoint @ 0xffffffff), and re-serialize TX_NO_WITNESS byte-identically.

dgb_gentx_share_path_test: 4/4 PASS, build EXIT=0.

Scope

Single-coin: src/impl/dgb/ only. No shared base / CMake / build.yml touch. p2pool-merged-v36 surface: none.

Next

reconstruct_won_block body proper: other_txs ref-walk (m_transaction_hash_refs via tracker) + the witness-coinbase framing adjudication for segwit other_txs (parallels the BCH legacy-vs-witness lane).

HOLD merge.

frstrtr added 3 commits June 19, 2026 01:42
…coinbase

generate_share_transaction (verification path) and create_local_share
(emission path) each open-coded the coinbase wire layout
(version|vin|vouts|locktime) and the txid double-SHA256. Two byte paths
pinned to the same oracle vector = proven-equivalent, not unified: a
third edit could still diverge them.

Collapse both onto dgb::coin::assemble_gentx_coinbase() (coin/gentx_coinbase.hpp,
the #171 SSOT) so emission == verification == one source. Each call site
now only builds its per-share inputs (coinbase script, optional segwit
witness-commitment script, PPLNS payout outputs, donation, OP_RETURN ref
commitment) and hands them to the assembler; the assembler owns wire
framing + txid. PackStream tx is reconstructed from the SSOT bytes so the
downstream V36 hash_link diagnostics are byte-for-byte unchanged.

No oracle vector regeneration. Single-coin scope: src/impl/dgb/ only.
dgb build EXIT=0; dgb_share_test 5/5; dgb_gentx_coinbase_test 3/3.
…its SSOT framing

Round-trip equivalence KAT (op_return ref_hash is share-derived, cannot pin a
fixed oracle vector): generate_share_transaction(share) txid == verbatim
re-derivation through the SAME assemble_gentx_coinbase SSOT. Proves the #172
collapse behaviorally, not structurally. 3/3 PASS, txid 9e2b78d5. Wired into
ctest + BOTH build.yml allowlists in this commit (#143 NOT_BUILT trap).
generate_share_transaction computes the coinbase via assemble_gentx_coinbase
(the SSOT proven by #172) but returned only the gentx_hash, discarding the
bytes. reconstruct_won_block needs the exact non-witness coinbase bytes -- it
is block tx[0] and its txid is the merkle leaf -- not just the hash.

Add an optional out_gentx (GentxCoinbase*) param, default nullptr: zero change
for the verification callers, surfaces {bytes,txid} for the reconstructor. KAT
proves the exposed bytes hash to the returned gentx_hash and deserialize into
the coinbase MutableTransaction that assemble_won_block frames, round-tripping
byte-identically (non-witness). Single-coin (src/impl/dgb/ only); reuses the
existing #172 dgb_gentx_share_path_test target (no new allowlist entry).
@frstrtr
frstrtr force-pushed the dgb/won-block-gentx-expose branch from 4ab5495 to 7b1f57a Compare June 19, 2026 01:44
frstrtr added a commit that referenced this pull request Jun 19, 2026
…me as_block

Tie the three landed sub-slices into the single composition the dispatch
handler injects as its WonBlockReconstructor:
  resolve_other_tx_hashes (#174) -> assemble_other_txs (#176)
  -> assemble_won_block (#168 framing)

Faithful port of p2pool data.py Share.as_block: produces {bytes, hex} for
broadcast_won_block dual path. Gentx enters as a deserialized
MutableTransaction + txid (the SSOT gentx-bytes -> MutableTransaction unpack,
inverse of #173 exposure, is the next slice). Injected tracker/known_txs
seams keep it unit-testable; out_of_range propagation from each step
preserved (never emit a partial/wrong block).

dgb_reconstruct_won_block_test 5/5 PASS: end-to-end == manual
resolve+assemble+frame (byte-identical), [gentx]++others in ref order,
empty-refs gentx-only, ref-past-chain + unknown-known-tx throw. Wired into
test/CMakeLists.txt + both build.yml --target allowlists (#143 trap).

Per-coin isolation: src/impl/dgb/ only. p2pool-merged-v36 surface: none.
frstrtr added a commit that referenced this pull request Jun 19, 2026
coin/gentx_unpack.hpp: unpack_gentx_coinbase() turns the share SSOT
non-witness gentx bytes (generate_share_transaction out_gentx, #173)
back into the MutableTransaction reconstruct_won_block injects at block
tx index 0. Parses with TX_NO_WITNESS so the coinbase round-trips its
non-witness bytes EXACTLY and the txid (== gentx_hash, consumed by the
merkle_root walk) stays stable -- no witness/serialization drift; throws
std::out_of_range on trailing bytes (malformed gentx).

gentx_unpack_test: 6/6 oracle round-trip (no-segwit + witness-commitment
layouts, byte-exact + txid stable + HasWitness false), coinbase-shape
recovery, inverse-pairing vs assemble_gentx_coinbase, and trailing-byte
throw. Wired into test CMake + both build.yml --target allowlists.

src/impl/dgb/ only; p2pool-merged-v36 surface NONE.
@frstrtr
frstrtr merged commit 4c9d8d3 into master Jun 19, 2026
17 checks passed
frstrtr added a commit that referenced this pull request Jun 19, 2026
dgb(#82): gentx-bytes -> MutableTransaction unpack (inverse of #173)
frstrtr added a commit that referenced this pull request Jun 19, 2026
…(--run)

Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a
boost::asio::io_context plus an explicit graceful shutdown driven from
signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract.

This is the lifecycle every node subsystem (sharechain peer dgb::Node,
embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch
handler hangs off. Standing the spine up first keeps the next increments
(node/Config construction over LevelDB, P2P listen, Stratum, and the
m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding
landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable
rather than landing a large unverified port in one step.

--selftest / bare invocation unchanged (live ShareTracker::score() path).
External digibyted RPC fallback posture preserved.

Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK
(block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr added a commit that referenced this pull request Jun 19, 2026
…(--run)

Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a
boost::asio::io_context plus an explicit graceful shutdown driven from
signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract.

This is the lifecycle every node subsystem (sharechain peer dgb::Node,
embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch
handler hangs off. Standing the spine up first keeps the next increments
(node/Config construction over LevelDB, P2P listen, Stratum, and the
m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding
landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable
rather than landing a large unverified port in one step.

--selftest / bare invocation unchanged (live ShareTracker::score() path).
External digibyted RPC fallback posture preserved.

Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK
(block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr added a commit that referenced this pull request Jun 19, 2026
…(--run)

Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a
boost::asio::io_context plus an explicit graceful shutdown driven from
signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract.

This is the lifecycle every node subsystem (sharechain peer dgb::Node,
embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch
handler hangs off. Standing the spine up first keeps the next increments
(node/Config construction over LevelDB, P2P listen, Stratum, and the
m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding
landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable
rather than landing a large unverified port in one step.

--selftest / bare invocation unchanged (live ShareTracker::score() path).
External digibyted RPC fallback posture preserved.

Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK
(block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr added a commit that referenced this pull request Jun 19, 2026
…(--run)

Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a
boost::asio::io_context plus an explicit graceful shutdown driven from
signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract.

This is the lifecycle every node subsystem (sharechain peer dgb::Node,
embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch
handler hangs off. Standing the spine up first keeps the next increments
(node/Config construction over LevelDB, P2P listen, Stratum, and the
m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding
landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable
rather than landing a large unverified port in one step.

--selftest / bare invocation unchanged (live ShareTracker::score() path).
External digibyted RPC fallback posture preserved.

Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK
(block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr added a commit that referenced this pull request Jun 23, 2026
… nullopt stub)

main_dgb.cpp --run binds tracker().m_on_block_found to the FAITHFUL
make_reconstruct_closure_from_template (#280) in place of the interim
nullopt stub. The three version-agnostic won-block inputs are bound to
the live sharechain tracker:
  - won_share_fields_fn: share.m_min_header + m_merkle_link (#279)
  - gentx_bytes_fn: generate_share_transaction(...).GentxCoinbase.bytes
    (#173 SSOT); v36_active re-derived from the share compile-time
    version inside GST, byte-identical to the verify-path invocation
  - template_other_txs_fn: captured-GBT non-coinbase set (#271), empty
    today (no per-job template retention + unfed embedded mempool =>
    coinbase-only), correct-and-empty, NOT fail-closed

Fires on the compute thread already holding the tracker lock, so the
fns read tracker().chain directly (no read_tracker(), no self-deadlock).
Fail-closed end to end: any builder error -> nullopt (announce + audit;
RPC submitblock fallback still fires). Fenced to main_dgb.cpp; build
EXIT=0; selftest OK. #82 OPEN pending a live UpdateTip won-block test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant