Skip to content

dgb: forward merkle-link builder (calculate_merkle_link) for tx-bearing won blocks - #302

Closed
frstrtr wants to merge 1 commit into
masterfrom
dgb/merkle-link-build
Closed

dgb: forward merkle-link builder (calculate_merkle_link) for tx-bearing won blocks#302
frstrtr wants to merge 1 commit into
masterfrom
dgb/merkle-link-build

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 21, 2026

Copy link
Copy Markdown
Owner

What

New coin/merkle_link_build.hppcalculate_merkle_link(), the exact inverse of share_check.hpp check_merkle_link(). Given the block tx hashes it rebuilds the coinbase (index-0) merkle branch using the same double-SHA combine and Bitcoin's duplicate-last-on-odd rule.

Why (the multi-tx won-block gap)

A reconstructed won block recomputes its merkle root from the gentx hash up the share m_merkle_link (reconstruct_won_block.hpp:20-21), while the captured-template txs only populate the block body. So a coinbase-only merkle_link over a multi-tx body roots to the wrong value and the daemon rejects bad-txnmrklroot.

The regtest --regtest-force-won-share seed synthesizes a coinbase-only link, so to drive a tx-bearing won-block re-soak (integrator: prove a real won block carrying mempool txs accepts at node B) its m_merkle_link must be rebuilt over the captured template tx set. check_merkle_link only verifies a branch; nothing built one. This fills that gap.

Scope

Test-only / fenced — src/impl/dgb/ only. No wire / share-format / p2pool-merged-v36 surface change (build-side helper; wire merkle_link semantics unchanged).

Test

KAT round-trips through the production dgb::check_merkle_link (not a re-impl): coinbase-only, even, and odd (duplicate-last) tx counts; every leaf index reproduces the one root; fail-closed on empty/out-of-range. 4/4 green locally.

Follow-up (separate slice): wire TemplateCapture (#300) + this builder into the main_dgb forced-won seed (capture GBT transactions[], rebuild m_merkle_link, swap template_other_txs_fn to the capture provider) and run the live multi-tx dual-arm re-soak.

…ng won blocks

calculate_merkle_link() is the exact inverse of share_check.hpp
check_merkle_link(): given the block tx hashes it rebuilds the
coinbase (index-0) merkle branch, using the same double-SHA combine and
Bitcoin's duplicate-last-on-odd rule.

A reconstructed won block recomputes its merkle ROOT from the gentx hash
up the share m_merkle_link while the captured template txs only populate
the body, so a coinbase-only link over a multi-tx body roots wrong and
the daemon rejects bad-txnmrklroot. This builder lets the regtest
forced-won seed rebuild m_merkle_link over the captured template tx set
so a tx-bearing won block roots correctly -- the prerequisite for the
multi-tx won-block re-soak.

Test-only/fenced (src/impl/dgb only); no wire/share-format change. KAT
round-trips through the PRODUCTION check_merkle_link across coinbase-only,
even, and odd (duplicate-last) tx counts, every leaf index, and
fail-closed on bad input. 4/4 green.
@frstrtr
frstrtr force-pushed the dgb/merkle-link-build branch from 8101359 to 8acb11c Compare June 21, 2026 18:48
frstrtr added a commit that referenced this pull request Jun 21, 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

frstrtr commented Jun 21, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #303 (merged): won-block header merkle_root is recomputed over the actual reconstructed tx vector via build_block_merkle_root, which subsumes the forward calculate_merkle_link approach this PR proposed. No longer needed; closing to keep the queue clean.

@frstrtr frstrtr closed this 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).
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