9 #include <boost/test/unit_test.hpp>
14 static uint256 BlockBuildMerkleTree(
const CBlock& block,
bool* fMutated, std::vector<uint256>& vMerkleTree)
17 vMerkleTree.reserve(block.
vtx.size() * 2 + 16);
18 for (std::vector<CTransactionRef>::const_iterator it(block.
vtx.begin()); it != block.
vtx.end(); ++it)
19 vMerkleTree.push_back((*it)->GetHash());
22 for (
int nSize = block.
vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
24 for (
int i = 0; i < nSize; i += 2)
26 int i2 = std::min(i+1, nSize-1);
27 if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
31 vMerkleTree.push_back(
Hash(vMerkleTree[j+i].begin(), vMerkleTree[j+i].end(),
32 vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end()));
39 return (vMerkleTree.empty() ?
uint256() : vMerkleTree.back());
43 static std::vector<uint256> BlockGetMerkleBranch(
const CBlock& block,
const std::vector<uint256>& vMerkleTree,
int nIndex)
45 std::vector<uint256> vMerkleBranch;
47 for (
int nSize = block.
vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
49 int i = std::min(nIndex^1, nSize-1);
50 vMerkleBranch.push_back(vMerkleTree[j+i]);
57 static inline int ctz(uint32_t i) {
69 for (
int i = 0; i < 32; i++) {
71 int ntx = (i <= 16) ? i : 17 + (InsecureRandRange(4000));
73 for (
int mutate = 0; mutate <= 3; mutate++) {
74 int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0;
75 if (duplicate1 >= ntx)
break;
76 int ntx1 = ntx + duplicate1;
77 int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0;
78 if (duplicate2 >= ntx1)
break;
79 int ntx2 = ntx1 + duplicate2;
80 int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0;
81 if (duplicate3 >= ntx2)
break;
82 int ntx3 = ntx2 + duplicate3;
85 block.
vtx.resize(ntx);
86 for (
int j = 0; j < ntx; j++) {
89 block.
vtx[j] = std::make_shared<const CTransaction>(mtx);
92 bool unmutatedMutated =
false;
96 block.
vtx.resize(ntx3);
97 for (
int j = 0; j < duplicate1; j++) {
98 block.
vtx[ntx + j] = block.
vtx[ntx + j - duplicate1];
100 for (
int j = 0; j < duplicate2; j++) {
101 block.
vtx[ntx1 + j] = block.
vtx[ntx1 + j - duplicate2];
103 for (
int j = 0; j < duplicate3; j++) {
104 block.
vtx[ntx2 + j] = block.
vtx[ntx2 + j - duplicate3];
107 bool oldMutated =
false;
108 std::vector<uint256> merkleTree;
109 uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree);
111 bool newMutated =
false;
120 for (
int loop = 0; loop < std::min(ntx, 16); loop++) {
124 mtx = InsecureRandRange(ntx);
127 std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx);
std::vector< CTransactionRef > vtx
BOOST_AUTO_TEST_SUITE_END()
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
uint256 ComputeMerkleRootFromBranch(const uint256 &leaf, const std::vector< uint256 > &vMerkleBranch, uint32_t nIndex)
std::vector< uint256 > BlockMerkleBranch(const CBlock &block, uint32_t position)
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
BOOST_AUTO_TEST_CASE(merkle_test)
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK(expr)
A mutable version of CTransaction.