|
35 | 35 | namespace { |
36 | 36 |
|
37 | 37 | using nmc::coin::aux_merkle_root; |
| 38 | +using nmc::coin::AuxPow; |
38 | 39 |
|
39 | 40 | // Build a uint256 whose first byte is `b` (rest zero) — distinct, legible leaves. |
40 | 41 | static uint256 leaf_of(unsigned char b) |
@@ -100,4 +101,53 @@ TEST(NmcAuxMerkle, IndexTooLargeForBranchThrows) |
100 | 101 | EXPECT_THROW(aux_merkle_root(leaf, {sib}, 2u), std::invalid_argument); |
101 | 102 | } |
102 | 103 |
|
| 104 | + |
| 105 | +// --------------------------------------------------------------------------- |
| 106 | +// P1b: AuxPow::check_proof chain-merkle leg (step 1) wiring. |
| 107 | +// |
| 108 | +// check_proof() now reconstructs the merged-mining merkle root from the aux |
| 109 | +// block hash through chain_merkle_branch/index via aux_merkle_root(). Steps 2 |
| 110 | +// (MM-marker commitment), 3 (parent-coinbase tx-merkle leg) and 4 (parent PoW) |
| 111 | +// are NOT built, so a structurally-consistent walk returns INCOMPLETE — never |
| 112 | +// VALID. A malformed slot index (negative, or wider than the branch depth) |
| 113 | +// returns INVALID. These KATs pin exactly that boundary so the leg can never |
| 114 | +// silently regress into asserting VALID before the rest of the proof exists. |
| 115 | +// --------------------------------------------------------------------------- |
| 116 | + |
| 117 | +TEST(NmcAuxCheckProof, ChainLegStructurallyValidIsIncomplete) |
| 118 | +{ |
| 119 | + AuxPow ap; |
| 120 | + ap.chain_merkle_branch = {leaf_of(0xbe)}; |
| 121 | + ap.chain_merkle_index = 0; |
| 122 | + EXPECT_EQ(ap.check_proof(leaf_of(0x01), /*expected_chain_id=*/1), |
| 123 | + AuxPow::CheckResult::INCOMPLETE); |
| 124 | +} |
| 125 | + |
| 126 | +TEST(NmcAuxCheckProof, EmptyChainBranchIsIncompleteNeverValid) |
| 127 | +{ |
| 128 | + AuxPow ap; // empty branch, index 0 => identity walk, still not provable |
| 129 | + EXPECT_EQ(ap.check_proof(leaf_of(0x07), 1), |
| 130 | + AuxPow::CheckResult::INCOMPLETE); |
| 131 | + EXPECT_NE(ap.check_proof(leaf_of(0x07), 1), |
| 132 | + AuxPow::CheckResult::VALID); |
| 133 | +} |
| 134 | + |
| 135 | +TEST(NmcAuxCheckProof, NegativeChainIndexIsInvalid) |
| 136 | +{ |
| 137 | + AuxPow ap; |
| 138 | + ap.chain_merkle_branch = {leaf_of(0x0a)}; |
| 139 | + ap.chain_merkle_index = -1; |
| 140 | + EXPECT_EQ(ap.check_proof(leaf_of(0x02), 1), |
| 141 | + AuxPow::CheckResult::INVALID); |
| 142 | +} |
| 143 | + |
| 144 | +TEST(NmcAuxCheckProof, ChainIndexTooWideForDepthIsInvalid) |
| 145 | +{ |
| 146 | + AuxPow ap; |
| 147 | + ap.chain_merkle_branch = {leaf_of(0x0a)}; // depth 1 => max index 1 |
| 148 | + ap.chain_merkle_index = 2; |
| 149 | + EXPECT_EQ(ap.check_proof(leaf_of(0x02), 1), |
| 150 | + AuxPow::CheckResult::INVALID); |
| 151 | +} |
| 152 | + |
103 | 153 | } // namespace |
0 commit comments