| 180 | } |
| 181 | |
| 182 | BOOST_AUTO_TEST_CASE(merkle_test) |
| 183 | { |
| 184 | for (int i = 0; i < 32; i++) { |
| 185 | // Try 32 block sizes: all sizes from 0 to 16 inclusive, and then 15 random sizes. |
| 186 | int ntx = (i <= 16) ? i : 17 + (InsecureRandRange(4000)); |
| 187 | // Try up to 3 mutations. |
| 188 | for (int mutate = 0; mutate <= 3; mutate++) { |
| 189 | int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0; // The last how many transactions to duplicate first. |
| 190 | if (duplicate1 >= ntx) break; // Duplication of the entire tree results in a different root (it adds a level). |
| 191 | int ntx1 = ntx + duplicate1; // The resulting number of transactions after the first duplication. |
| 192 | int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation. |
| 193 | if (duplicate2 >= ntx1) break; |
| 194 | int ntx2 = ntx1 + duplicate2; |
| 195 | int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the third mutation. |
| 196 | if (duplicate3 >= ntx2) break; |
| 197 | int ntx3 = ntx2 + duplicate3; |
| 198 | // Build a block with ntx different transactions. |
| 199 | CBlock block; |
| 200 | block.vtx.resize(ntx); |
| 201 | for (int j = 0; j < ntx; j++) { |
| 202 | CMutableTransaction mtx; |
| 203 | mtx.nLockTime = j; |
| 204 | block.vtx[j] = MakeTransactionRef(std::move(mtx)); |
| 205 | } |
| 206 | // Compute the root of the block before mutating it. |
| 207 | bool unmutatedMutated = false; |
| 208 | uint256 unmutatedRoot = BlockMerkleRoot(block, &unmutatedMutated); |
| 209 | BOOST_CHECK(unmutatedMutated == false); |
| 210 | // Optionally mutate by duplicating the last transactions, resulting in the same merkle root. |
| 211 | block.vtx.resize(ntx3); |
| 212 | for (int j = 0; j < duplicate1; j++) { |
| 213 | block.vtx[ntx + j] = block.vtx[ntx + j - duplicate1]; |
| 214 | } |
| 215 | for (int j = 0; j < duplicate2; j++) { |
| 216 | block.vtx[ntx1 + j] = block.vtx[ntx1 + j - duplicate2]; |
| 217 | } |
| 218 | for (int j = 0; j < duplicate3; j++) { |
| 219 | block.vtx[ntx2 + j] = block.vtx[ntx2 + j - duplicate3]; |
| 220 | } |
| 221 | // Compute the merkle root and merkle tree using the old mechanism. |
| 222 | bool oldMutated = false; |
| 223 | std::vector<uint256> merkleTree; |
| 224 | uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree); |
| 225 | // Compute the merkle root using the new mechanism. |
| 226 | bool newMutated = false; |
| 227 | uint256 newRoot = BlockMerkleRoot(block, &newMutated); |
| 228 | BOOST_CHECK(oldRoot == newRoot); |
| 229 | BOOST_CHECK(newRoot == unmutatedRoot); |
| 230 | BOOST_CHECK((newRoot == uint256()) == (ntx == 0)); |
| 231 | BOOST_CHECK(oldMutated == newMutated); |
| 232 | BOOST_CHECK(newMutated == !!mutate); |
| 233 | // If no mutation was done (once for every ntx value), try up to 16 branches. |
| 234 | if (mutate == 0) { |
| 235 | for (int loop = 0; loop < std::min(ntx, 16); loop++) { |
| 236 | // If ntx <= 16, try all branches. Otherwise, try 16 random ones. |
| 237 | int mtx = loop; |
| 238 | if (ntx > 16) { |
| 239 | mtx = InsecureRandRange(ntx); |
nothing calls this directly
no test coverage detected