nmc(P1c): AuxPow::check_proof parent-coinbase tx-merkle leg (step 3) + witness-stripped txid KAT - #181
Merged
frstrtr merged 1 commit intoJun 19, 2026
Conversation
…p 3) + witness-stripped txid KAT Adds nmc::coin::parent_coinbase_txid() (Hash over TX_NO_WITNESS serialization, byte-identical to btc compute_txid() but NMC-local per the coin fence) and wires AuxPow::check_proof step 3: reconstruct the parent block tx-merkle-root from the witness-stripped coinbase txid through parent_coinbase_branch/index via aux_merkle_root(). When a parent header is present the reconstructed root MUST equal parent_header.m_merkle_root, else INVALID; malformed legs (negative index, index wider than branch depth) are INVALID. Steps 2 (MM-marker commitment) and 4 (parent PoW) remain unbuilt, so a structurally-consistent proof still returns INCOMPLETE, never VALID -- NMC MUST NOT block-validate off this leaf. The load-bearing KAT asserts the exact byte serialization: the txid is hashed over the LEGACY (no-witness) layout -- txid, NOT wtxid -- re-derived field-by- field without SerializeTransaction's witness/marker path, and is shown to differ from the wtxid for a coinbase carrying the BIP141 reserved value. Plus 4 check_proof boundary KATs (match=>INCOMPLETE, mismatch/negative/too-wide=> INVALID). nmc_auxpow_merkle_test 14/14 PASS exit 0. NMC-local, btc tree READ-ONLY, test target name unchanged (CI allowlist untouched).
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.
Stacked PR — review order P1a (#178) -> P1b (#180) -> P1c (this). Base is the P1b branch so this diff is P1c-only; each leg is independently revertable.
What
Third leg of
AuxPow::check_proof(): the parent-coinbase tx-merkle proof (step 3 of 4).nmc::coin::parent_coinbase_txid()—Hash(pack(TX_NO_WITNESS(tx))), byte-identical to the btc tree'scompute_txid()(mempool.hpp) but NMC-local per the coin fence (onlynmc::coinserializer +core::Hash; no btc include).check_proofstep 3: reconstruct the parent block tx-merkle-root from the witness-stripped coinbase txid throughparent_coinbase_branch/parent_coinbase_indexviaaux_merkle_root(). When a parent header is present the reconstructed root MUST equalparent_header.m_merkle_root, else INVALID. Negative/too-wide index => INVALID.Still INCOMPLETE-never-VALID
Steps 2 (MM-marker commitment + chain_id/slot binding) and 4 (parent PoW vs target, btc tree READ-ONLY) are unbuilt. A structurally-consistent proof returns INCOMPLETE — NMC MUST NOT block-validate off this leaf. No leaf can block-validate until all four legs land, so this carries no merge risk.
Tests —
nmc_auxpow_merkle_test14/14 PASS exit 0 (was 9/9)SerializeTransaction's witness/marker path (catches a stray marker/flag), and shown to differ from the wtxid for a coinbase carrying the BIP141 reserved value.check_proofboundary KATs: match=>INCOMPLETE, mismatch/negative/too-wide=>INVALID.Fences
NMC-local (
src/impl/nmc/only), btc tree READ-ONLY, GPG-signed, zero-attribution, test target name unchanged (CI--targetallowlist untouched). I do not self-merge.Next: P1c-step2 (coinbase MM-marker scan + chain_id pin), then step 4 (parent PoW).