MCPcopy Create free account
hub / github.com/ElementsProject/elements / BOOST_AUTO_TEST_CASE

Function BOOST_AUTO_TEST_CASE

src/test/merkle_tests.cpp:182–249  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

180}
181
182BOOST_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);

Callers

nothing calls this directly

Calls 15

InsecureRandRangeFunction · 0.85
ctzFunction · 0.85
BlockMerkleRootFunction · 0.85
BlockBuildMerkleTreeFunction · 0.85
BlockMerkleBranchFunction · 0.85
BlockGetMerkleBranchFunction · 0.85
ComputeMerkleRootFunction · 0.85
BlockWitnessMerkleRootFunction · 0.85
uint256SFunction · 0.85
ComputeFastMerkleRootFunction · 0.85
MakeTransactionRefFunction · 0.50

Tested by

no test coverage detected