dgb(#82): wire captured-template txs into won-block reconstruct - #303
Merged
Conversation
Replace the interim coinbase-only template_other_txs_fn stub in the #82 forced-won live seam with the production capture->bridge path: - declare a run-loop-scoped dgb::coin::TemplateCapture (#300/#271) that outlives every tracker callback the provider() is installed into - feed it through make_template_other_txs_fn (#299) as the reconstruct closure template_other_txs_fn, so a won block replays the EXACT non-coinbase set the share committed to (merkle-consistent) instead of reconstructing coinbase-only - seed_forced_from_gbt captures the node-B GBT transactions[] keyed by the forced share hash; coinbasevalue already includes those fees so the regenerated gentx subsidy stays balanced A capture MISS still decodes to an empty set -> a valid coinbase-only block (never fail-closed). Per-coin: src/impl/dgb + main_dgb only.
…ector The tx-bearing reconstruct path (reconstruct_won_block_from_template) sources its body from the captured GBT template, but assemble_won_block derived the header merkle_root by walking the share merkle_link (check_merkle_link). That link only spans the txs it was built over, so a coinbase-only link with a funded tx in the body emitted a header root for the coinbase-only set -> daemon rejects bad-txnmrklroot (the #82 funded multi-tx soak FAIL on both arms). Recompute the root over [gentx_hash] ++ each other-tx txid via a canonical BuildMerkleRoot (build_block_merkle_root), set before serialize so the nonce-grind seam grinds the final header. Coinbase-only is unchanged (root == gentx_hash). +1 regression KAT; corrected Test 4 which had enshrined the buggy coinbase-only root with 2 other_txs. 8/8 green.
Fail-closed regtest soak proving a won block carrying a non-coinbase funded legacy tx is reconstructed (#300/#302/#303) and ACCEPTED by a peer down BOTH arms (P2P primary + submitblock isolated). Asserts NTX>=2 and funded-txid presence per arm via getrawmempool/getblock; die() aborts on any miss (no getrawtransaction-without-txindex false-green path).
This was referenced Jun 21, 2026
frstrtr
added a commit
that referenced
this pull request
Jun 23, 2026
Fail-closed regtest soak proving a won block carrying a non-coinbase funded legacy tx is reconstructed (#300/#302/#303) and ACCEPTED by a peer down BOTH arms (P2P primary + submitblock isolated). Asserts NTX>=2 and funded-txid presence per arm via getrawmempool/getblock; die() aborts on any miss (no getrawtransaction-without-txindex false-green path).
frstrtr
added a commit
that referenced
this pull request
Jun 23, 2026
dgb(#82): wire captured-template txs into won-block reconstruct
frstrtr
added a commit
that referenced
this pull request
Jun 23, 2026
The CoinbaseFirstThenRefOrder test asserted the won-block header merkle_root equals gentx_hash for the empty-merkle_link case. That held under the old reconstruct_block_header merkle_link walk, but b91face (#303 bad-txnmrklroot fix) correctly recomputes the header root over the ACTUAL block tx vector ([gentx_hash] ++ other-tx txids) so header and body stay consistent for tx-bearing won blocks. With 2 other_txs the root is no longer gentx_hash, so the stale assertion failed on master. Re-pin the assertion to the production invariant via the same build_block_merkle_root + compute_txid SSOT the assembler uses, so the test now guards header/body merkle consistency instead of the obsolete empty-walk identity. Test-only; no behavior change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Final #82 step: the forced-won live seam now reconstructs a tx-bearing won block instead of coinbase-only.
Wires the #299 bridge + #300 capture store into the reconstruct closure in
src/c2pool/main_dgb.cpp(+22/-4):template_capture.hpp(dgb: per-job template-retention seam — captured_template_txs_fn provider (#271) #300/dgb(#82): reconstruct won block from captured GBT template, not share refs #271) +template_other_txs.hpp(dgb: template-txs producer bridge (tx-inclusion slice — decode GBT transactions[] into won-block other_txs) #299)dgb::coin::TemplateCapture(outlives all tracker callbacks; declared beforeioc.run())template_other_txs_fnstub withmake_template_other_txs_fn(template_capture.provider())seed_forced_from_gbtcaptures the node-B GBTtransactions[]keyed by the forced share hash, so the reconstructor replays the EXACT non-coinbase set the share committed to (merkle-consistent; coinbasevalue already includes those fees -> subsidy balanced)Why
make_reconstruct_closure_from_templatepreviously got an emptytemplate_other_txs_fn(documented interim coinbase-only). #299 (bridge) + #300 (capture store) are now on master, so the won block can carry the template txs.Safety
src/impl/dgb+main_dgbonly; no p2pool-merged-v36 surface.Verification
c2pool-dgbgreen (BUILD_EXIT=0).Base 6d3dbf6. Operator-tap; not self-merging.