Bitcoin Core  31.0.0
P2P Digital Currency
merkle_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2015-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <consensus/merkle.h>
6 #include <test/util/common.h>
7 #include <test/util/random.h>
9 
10 #include <boost/test/unit_test.hpp>
11 
13 
14 static uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& vMerkleBranch, uint32_t nIndex) {
15  uint256 hash = leaf;
16  for (std::vector<uint256>::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) {
17  if (nIndex & 1) {
18  hash = Hash(*it, hash);
19  } else {
20  hash = Hash(hash, *it);
21  }
22  nIndex >>= 1;
23  }
24  return hash;
25 }
26 
27 // Older version of the merkle root computation code, for comparison.
28 static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::vector<uint256>& vMerkleTree)
29 {
30  vMerkleTree.clear();
31  vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
32  for (std::vector<CTransactionRef>::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it)
33  vMerkleTree.push_back((*it)->GetHash().ToUint256());
34  int j = 0;
35  bool mutated = false;
36  for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
37  {
38  for (int i = 0; i < nSize; i += 2)
39  {
40  int i2 = std::min(i+1, nSize-1);
41  if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
42  // Two identical hashes at the end of the list at a particular level.
43  mutated = true;
44  }
45  vMerkleTree.push_back(Hash(vMerkleTree[j+i], vMerkleTree[j+i2]));
46  }
47  j += nSize;
48  }
49  if (fMutated) {
50  *fMutated = mutated;
51  }
52  return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
53 }
54 
55 // Older version of the merkle branch computation code, for comparison.
56 static std::vector<uint256> BlockGetMerkleBranch(const CBlock& block, const std::vector<uint256>& vMerkleTree, int nIndex)
57 {
58  std::vector<uint256> vMerkleBranch;
59  int j = 0;
60  for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
61  {
62  int i = std::min(nIndex^1, nSize-1);
63  vMerkleBranch.push_back(vMerkleTree[j+i]);
64  nIndex >>= 1;
65  j += nSize;
66  }
67  return vMerkleBranch;
68 }
69 
70 static inline int ctz(uint32_t i) {
71  if (i == 0) return 0;
72  int j = 0;
73  while (!(i & 1)) {
74  j++;
75  i >>= 1;
76  }
77  return j;
78 }
79 
81 {
82  for (int i = 0; i < 32; i++) {
83  // Try 32 block sizes: all sizes from 0 to 16 inclusive, and then 15 random sizes.
84  int ntx = (i <= 16) ? i : 17 + (m_rng.randrange(4000));
85  // Try up to 3 mutations.
86  for (int mutate = 0; mutate <= 3; mutate++) {
87  int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0; // The last how many transactions to duplicate first.
88  if (duplicate1 >= ntx) break; // Duplication of the entire tree results in a different root (it adds a level).
89  int ntx1 = ntx + duplicate1; // The resulting number of transactions after the first duplication.
90  int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation.
91  if (duplicate2 >= ntx1) break;
92  int ntx2 = ntx1 + duplicate2;
93  int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the third mutation.
94  if (duplicate3 >= ntx2) break;
95  int ntx3 = ntx2 + duplicate3;
96  // Build a block with ntx different transactions.
97  CBlock block;
98  block.vtx.resize(ntx);
99  for (int j = 0; j < ntx; j++) {
101  mtx.nLockTime = j;
102  block.vtx[j] = MakeTransactionRef(std::move(mtx));
103  }
104  // Compute the root of the block before mutating it.
105  bool unmutatedMutated = false;
106  uint256 unmutatedRoot = BlockMerkleRoot(block, &unmutatedMutated);
107  BOOST_CHECK(unmutatedMutated == false);
108  // Optionally mutate by duplicating the last transactions, resulting in the same merkle root.
109  block.vtx.resize(ntx3);
110  for (int j = 0; j < duplicate1; j++) {
111  block.vtx[ntx + j] = block.vtx[ntx + j - duplicate1];
112  }
113  for (int j = 0; j < duplicate2; j++) {
114  block.vtx[ntx1 + j] = block.vtx[ntx1 + j - duplicate2];
115  }
116  for (int j = 0; j < duplicate3; j++) {
117  block.vtx[ntx2 + j] = block.vtx[ntx2 + j - duplicate3];
118  }
119  // Compute the merkle root and merkle tree using the old mechanism.
120  bool oldMutated = false;
121  std::vector<uint256> merkleTree;
122  uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree);
123  // Compute the merkle root using the new mechanism.
124  bool newMutated = false;
125  uint256 newRoot = BlockMerkleRoot(block, &newMutated);
126  BOOST_CHECK(oldRoot == newRoot);
127  BOOST_CHECK(newRoot == unmutatedRoot);
128  BOOST_CHECK((newRoot == uint256()) == (ntx == 0));
129  BOOST_CHECK(oldMutated == newMutated);
130  BOOST_CHECK(newMutated == !!mutate);
131  // If no mutation was done (once for every ntx value), try up to 16 branches.
132  if (mutate == 0) {
133  for (int loop = 0; loop < std::min(ntx, 16); loop++) {
134  // If ntx <= 16, try all branches. Otherwise, try 16 random ones.
135  int mtx = loop;
136  if (ntx > 16) {
137  mtx = m_rng.randrange(ntx);
138  }
139  std::vector<uint256> newBranch = TransactionMerklePath(block, mtx);
140  std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx);
141  BOOST_CHECK(oldBranch == newBranch);
142  BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx]->GetHash().ToUint256(), newBranch, mtx) == oldRoot);
143  }
144  }
145  }
146  }
147 }
148 
149 
150 BOOST_AUTO_TEST_CASE(merkle_test_empty_block)
151 {
152  bool mutated = false;
153  CBlock block;
154  uint256 root = BlockMerkleRoot(block, &mutated);
155 
156  BOOST_CHECK_EQUAL(root.IsNull(), true);
157  BOOST_CHECK_EQUAL(mutated, false);
158 
159  // Verify TransactionMerklePath handles empty block correctly
160  // This tests the early-return path in MerkleComputation
161  std::vector<uint256> merkle_path = TransactionMerklePath(block, 0);
162  BOOST_CHECK(merkle_path.empty());
163 }
164 
165 BOOST_AUTO_TEST_CASE(merkle_test_oneTx_block)
166 {
167  bool mutated = false;
168  CBlock block;
169 
170  block.vtx.resize(1);
172  mtx.nLockTime = 0;
173  block.vtx[0] = MakeTransactionRef(std::move(mtx));
174  uint256 root = BlockMerkleRoot(block, &mutated);
175  BOOST_CHECK_EQUAL(root, block.vtx[0]->GetHash().ToUint256());
176  BOOST_CHECK_EQUAL(mutated, false);
177 }
178 
179 BOOST_AUTO_TEST_CASE(merkle_test_OddTxWithRepeatedLastTx_block)
180 {
181  bool mutated;
182  CBlock block, blockWithRepeatedLastTx;
183 
184  block.vtx.resize(3);
185 
186  for (std::size_t pos = 0; pos < block.vtx.size(); pos++) {
188  mtx.nLockTime = pos;
189  block.vtx[pos] = MakeTransactionRef(std::move(mtx));
190  }
191 
192  blockWithRepeatedLastTx = block;
193  blockWithRepeatedLastTx.vtx.push_back(blockWithRepeatedLastTx.vtx.back());
194 
195  uint256 rootofBlock = BlockMerkleRoot(block, &mutated);
196  BOOST_CHECK_EQUAL(mutated, false);
197 
198  uint256 rootofBlockWithRepeatedLastTx = BlockMerkleRoot(blockWithRepeatedLastTx, &mutated);
199  BOOST_CHECK_EQUAL(rootofBlock, rootofBlockWithRepeatedLastTx);
200  BOOST_CHECK_EQUAL(mutated, true);
201 }
202 
203 BOOST_AUTO_TEST_CASE(merkle_test_LeftSubtreeRightSubtree)
204 {
205  CBlock block, leftSubtreeBlock, rightSubtreeBlock;
206 
207  block.vtx.resize(4);
208  std::size_t pos;
209  for (pos = 0; pos < block.vtx.size(); pos++) {
211  mtx.nLockTime = pos;
212  block.vtx[pos] = MakeTransactionRef(std::move(mtx));
213  }
214 
215  for (pos = 0; pos < block.vtx.size() / 2; pos++)
216  leftSubtreeBlock.vtx.push_back(block.vtx[pos]);
217 
218  for (pos = block.vtx.size() / 2; pos < block.vtx.size(); pos++)
219  rightSubtreeBlock.vtx.push_back(block.vtx[pos]);
220 
221  uint256 root = BlockMerkleRoot(block);
222  uint256 rootOfLeftSubtree = BlockMerkleRoot(leftSubtreeBlock);
223  uint256 rootOfRightSubtree = BlockMerkleRoot(rightSubtreeBlock);
224  std::vector<uint256> leftRight;
225  leftRight.push_back(rootOfLeftSubtree);
226  leftRight.push_back(rootOfRightSubtree);
227  uint256 rootOfLR = ComputeMerkleRoot(leftRight);
228 
229  BOOST_CHECK_EQUAL(root, rootOfLR);
230 }
231 
232 BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness)
233 {
234  CBlock block;
235 
236  constexpr size_t vtx_count{3};
237  block.vtx.resize(vtx_count);
238  for (std::size_t pos = 0; pos < vtx_count; pos++) {
240  mtx.nLockTime = pos;
241  block.vtx[pos] = MakeTransactionRef(std::move(mtx));
242  }
243 
244  uint256 blockWitness = BlockWitnessMerkleRoot(block);
245 
246  std::vector<uint256> hashes;
247  hashes.resize(vtx_count); // Odd count exercises leaf duplication in ComputeMerkleRoot (which can append one extra hash).
248  hashes[0] = uint256::ZERO; // The witness hash of the coinbase is 0.
249  for (size_t pos{1}; pos < vtx_count; ++pos) {
250  hashes[pos] = block.vtx[pos]->GetWitnessHash().ToUint256();
251  }
252 
253  uint256 merkleRootofHashes = ComputeMerkleRoot(hashes);
254  BOOST_CHECK_EQUAL(merkleRootofHashes, blockWitness);
255 }
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Definition: merkle.cpp:46
Definition: block.h:73
std::vector< uint256 > TransactionMerklePath(const CBlock &block, uint32_t position)
Compute merkle path to the specified transaction.
Definition: merkle.cpp:172
Definition: common.h:29
static uint256 ComputeMerkleRootFromBranch(const uint256 &leaf, const std::vector< uint256 > &vMerkleBranch, uint32_t nIndex)
BOOST_AUTO_TEST_CASE(merkle_test)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
static const uint256 ZERO
Definition: uint256.h:203
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
Definition: merkle.cpp:66
constexpr bool IsNull() const
Definition: uint256.h:48
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:404
uint256 BlockWitnessMerkleRoot(const CBlock &block)
Definition: merkle.cpp:76
256-bit opaque blob.
Definition: uint256.h:195
std::vector< CTransactionRef > vtx
Definition: block.h:77
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
static uint256 BlockBuildMerkleTree(const CBlock &block, bool *fMutated, std::vector< uint256 > &vMerkleTree)
A mutable version of CTransaction.
Definition: transaction.h:357
static int ctz(uint32_t i)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
Testing setup that configures a complete environment.
Definition: setup_common.h:121
static std::vector< uint256 > BlockGetMerkleBranch(const CBlock &block, const std::vector< uint256 > &vMerkleTree, int nIndex)
#define BOOST_CHECK(expr)
Definition: object.cpp:16