btc(coin): faithful won-block reconstructor closure — reconstruct_won_block (reconstructor slice 5/7) - #839
Merged
Merged
Conversation
frstrtr
force-pushed
the
btc/won-block-reconstruct
branch
from
July 25, 2026 04:48
348382d to
ae347df
Compare
frstrtr
force-pushed
the
btc/won-block-reconstruct
branch
from
July 25, 2026 08:07
ae347df to
4cf5115
Compare
…_block (reconstructor slice 5/7)
Compose the landed sub-slices into the run-loop WonBlockReconstructor the
mirroring p2pool data.py Share.as_block:
* select_won_block_merkle_link — segwit link-selection SSOT
(share_check.hpp:674-692): segwit-activated shares with segwit_data walk
segwit_data.txid_merkle_link, legacy shares walk merkle_link. The framer
(block_assembly.hpp, slice 4) takes an already-resolved MerkleLink, so the
selection lives here in the caller — no new merkle path downstream.
* reconstruct_won_block — select link + assemble_won_block, taking the
captured GBT template (slice 3) as the non-coinbase tx source (NOT the
share tx_hash_refs); version-agnostic, coinbase-only on a capture miss.
* make_reconstruct_closure — the fail-closed run-loop reconstructor: any
unknown share / malformed gentx / body-header merkle mismatch is caught,
logged loudly, and yields std::nullopt (never throws out of the compute
thread, never broadcasts a partial/wrong block; submitblock RPC fallback
still attempts independently).
Seam-first: share-field lookup, gentx regen, and the template-tx snapshot are
injected callables, so the whole closure is unit-testable with no live
ShareTracker / TemplateCapture. main_btc run-loop binding is slice 7.
reconstruct_test.cpp: 12 KATs — link selection (segwit/legacy/no-segwit-data),
body round-trip through the live BlockType codec, segwit-link-is-walked,
mismatch throw, closure fail-closed on malformed gentx + merkle mismatch, and
end-to-end wiring into make_on_block_found (both dual-path arms carry the
byte-identical block). btc_share_test 94/94 green; diff btc-tree-only.
Per-coin isolation: src/impl/btc/ only. p2pool-merged-v36 surface: NONE.
frstrtr
force-pushed
the
btc/won-block-reconstruct
branch
from
July 25, 2026 08:54
4cf5115 to
d1ddef1
Compare
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.
Slice 5/7 — the won-block reconstructor closure
Composes the landed sub-slices into the run-loop
WonBlockReconstructorthe #744 dispatch handler (won_block_dispatch.hpp/make_on_block_found) injects, mirroring p2pooldata.pyShare.as_block.select_won_block_merkle_link— segwit link-selection SSOT (share_check.hpp:674-692): segwit-activated shares withsegwit_datawalksegwit_data.txid_merkle_link; legacy (or segwit-active-but-no-segwit_data) shares walkmerkle_link. The framer (block_assembly.hpp, slice 4) takes an already-resolvedMerkleLink, so the selection lives here in the caller — no new merkle path downstream.reconstruct_won_block— select link +assemble_won_block, taking the captured GBT template (slice 3) as the non-coinbase tx source (NOT the sharetx_hash_refs); version-agnostic, coinbase-only on a capture miss.make_reconstruct_closure— the fail-closed run-loop reconstructor: any unknown share / malformed gentx / body-header merkle mismatch is caught, logged loudly, and yieldsstd::nullopt(never throws out of the compute thread, never broadcasts a partial/wrong block; the submitblock RPC fallback still attempts independently).Seam-first: share-field lookup, gentx regen, and the template-tx snapshot are injected callables → unit-testable with no live ShareTracker / TemplateCapture. The
main_btcrun-loop binding is slice 7.Tests —
reconstruct_test.cpp, 12 KATsLink selection (segwit / legacy / no-segwit-data), body round-trip through the live
BlockTypecodec, segwit-link-is-walked, mismatch throw, closure fail-closed on malformed gentx + merkle mismatch, and end-to-end wiring intomake_on_block_found(both dual-path arms carry the byte-identical block). Verified locally:btc_share_test94/94 green; cross-coin smokes green (dgb 34/34, nmc 4/4); diff btc-tree-only (3 files).Dependency note
Depends on
block_assembly.hpp(slice 4, #838), which is not yet on master. Per the base-off-master convention this PR is cut off master (not stacked), so its CI greens once #838 merges; a one-lineCMakeListsrebase against #838 may be needed then.Per-coin isolation:
src/impl/btc/only. p2pool-merged-v36 surface: NONE.