Bitcoin Core
32.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
test
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
>
8
#include <
test/util/setup_common.h
>
9
10
#include <boost/test/unit_test.hpp>
11
12
BOOST_FIXTURE_TEST_SUITE
(merkle_tests,
BasicTestingSetup
)
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
80
BOOST_AUTO_TEST_CASE
(merkle_test)
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++) {
100
CMutableTransaction
mtx;
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);
171
CMutableTransaction
mtx;
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++) {
187
CMutableTransaction
mtx;
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_mutated_return_value)
204
{
205
// CVE-2012-2459 construction: [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] produce the same root.
206
const
std::vector leaves{
uint256
{1},
uint256
{2},
uint256
{3},
uint256
{4},
uint256
{5},
uint256
{6}};
207
auto
mutated_leaves{leaves};
208
mutated_leaves.insert(mutated_leaves.end(), leaves.end() - 2, leaves.end());
// repeat last two elements
209
210
bool
mutated{
true
};
211
const
uint256
unmutated_root{
ComputeMerkleRoot
(leaves, &mutated)};
212
BOOST_CHECK
(!mutated);
213
BOOST_CHECK_EQUAL
(unmutated_root,
ComputeMerkleRoot
(mutated_leaves, &mutated));
214
BOOST_CHECK
( mutated);
215
216
const
std::vector nontrailing_duplicate_leaves{
uint256
{1},
uint256
{1},
uint256
{3},
uint256
{4}};
217
mutated =
false
;
218
const
uint256
nontrailing_duplicate_root{
ComputeMerkleRoot
(nontrailing_duplicate_leaves, &mutated)};
219
BOOST_CHECK
(nontrailing_duplicate_root ==
ComputeMerkleRoot
(nontrailing_duplicate_leaves));
220
BOOST_CHECK
(mutated);
221
}
222
223
BOOST_AUTO_TEST_CASE
(merkle_test_LeftSubtreeRightSubtree)
224
{
225
CBlock
block, leftSubtreeBlock, rightSubtreeBlock;
226
227
block.
vtx
.resize(4);
228
std::size_t pos;
229
for
(pos = 0; pos < block.
vtx
.size(); pos++) {
230
CMutableTransaction
mtx;
231
mtx.
nLockTime
= pos;
232
block.
vtx
[pos] = MakeTransactionRef(std::move(mtx));
233
}
234
235
for
(pos = 0; pos < block.
vtx
.size() / 2; pos++)
236
leftSubtreeBlock.
vtx
.push_back(block.
vtx
[pos]);
237
238
for
(pos = block.
vtx
.size() / 2; pos < block.
vtx
.size(); pos++)
239
rightSubtreeBlock.
vtx
.push_back(block.
vtx
[pos]);
240
241
uint256
root =
BlockMerkleRoot
(block);
242
uint256
rootOfLeftSubtree =
BlockMerkleRoot
(leftSubtreeBlock);
243
uint256
rootOfRightSubtree =
BlockMerkleRoot
(rightSubtreeBlock);
244
std::vector<uint256> leftRight;
245
leftRight.push_back(rootOfLeftSubtree);
246
leftRight.push_back(rootOfRightSubtree);
247
uint256
rootOfLR =
ComputeMerkleRoot
(leftRight);
248
249
BOOST_CHECK_EQUAL
(root, rootOfLR);
250
}
251
252
BOOST_AUTO_TEST_CASE
(merkle_test_BlockWitness)
253
{
254
CBlock
block;
255
256
constexpr
size_t
vtx_count{3};
257
block.
vtx
.resize(vtx_count);
258
for
(std::size_t pos = 0; pos < vtx_count; pos++) {
259
CMutableTransaction
mtx;
260
mtx.
nLockTime
= pos;
261
block.
vtx
[pos] = MakeTransactionRef(std::move(mtx));
262
}
263
264
uint256
blockWitness =
BlockWitnessMerkleRoot
(block);
265
266
std::vector<uint256> hashes;
267
hashes.resize(vtx_count);
// Odd count exercises leaf duplication in ComputeMerkleRoot (which can append one extra hash).
268
hashes[0] =
uint256::ZERO
;
// The witness hash of the coinbase is 0.
269
for
(
size_t
pos{1}; pos < vtx_count; ++pos) {
270
hashes[pos] = block.
vtx
[pos]->GetWitnessHash().ToUint256();
271
}
272
273
uint256
merkleRootofHashes =
ComputeMerkleRoot
(hashes);
274
BOOST_CHECK_EQUAL
(merkleRootofHashes, blockWitness);
275
}
276
BOOST_AUTO_TEST_SUITE_END
()
CBlock
Definition
block.h:74
CBlock::vtx
std::vector< CTransactionRef > vtx
Definition
block.h:77
base_blob::IsNull
constexpr bool IsNull() const
Definition
uint256.h:50
uint256
256-bit opaque blob.
Definition
uint256.h:196
uint256::uint256
constexpr uint256()=default
uint256::ZERO
static const uint256 ZERO
Definition
uint256.h:204
ComputeMerkleRoot
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Compute a Merkle root from the provided leaf hashes.
Definition
merkle.cpp:51
BlockMerkleRoot
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
Definition
merkle.cpp:76
TransactionMerklePath
std::vector< uint256 > TransactionMerklePath(const CBlock &block, uint32_t position)
Compute merkle path to the specified transaction.
Definition
merkle.cpp:182
BlockWitnessMerkleRoot
uint256 BlockWitnessMerkleRoot(const CBlock &block)
Definition
merkle.cpp:86
BOOST_FIXTURE_TEST_SUITE
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
Hash
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition
hash.h:83
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(ipc_tests)
Definition
ipc_tests.cpp:202
merkle.h
BlockBuildMerkleTree
static uint256 BlockBuildMerkleTree(const CBlock &block, bool *fMutated, std::vector< uint256 > &vMerkleTree)
Definition
merkle_tests.cpp:28
ctz
static int ctz(uint32_t i)
Definition
merkle_tests.cpp:70
ComputeMerkleRootFromBranch
static uint256 ComputeMerkleRootFromBranch(const uint256 &leaf, const std::vector< uint256 > &vMerkleBranch, uint32_t nIndex)
Definition
merkle_tests.cpp:14
BlockGetMerkleBranch
static std::vector< uint256 > BlockGetMerkleBranch(const CBlock &block, const std::vector< uint256 > &vMerkleTree, int nIndex)
Definition
merkle_tests.cpp:56
std
Definition
transaction.h:420
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition
object.cpp:17
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition
object.cpp:16
setup_common.h
BasicTestingSetup
Basic testing setup.
Definition
setup_common.h:58
CMutableTransaction
A mutable version of CTransaction.
Definition
transaction.h:372
CMutableTransaction::nLockTime
uint32_t nLockTime
Definition
transaction.h:376
common.h
random.h
Generated on
for Bitcoin Core by
1.18.0