Bitcoin Core 31.99.0
P2P Digital Currency
merkleblock.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-present The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <merkleblock.h>
7
9#include <hash.h>
10#include <util/overflow.h>
11
12
13std::vector<unsigned char> BitsToBytes(const std::vector<bool>& bits)
14{
15 std::vector<unsigned char> ret(CeilDiv(bits.size(), 8u));
16 for (unsigned int p = 0; p < bits.size(); p++) {
17 ret[p / 8] |= bits[p] << (p % 8);
18 }
19 return ret;
20}
21
22std::vector<bool> BytesToBits(const std::vector<unsigned char>& bytes)
23{
24 std::vector<bool> ret(bytes.size() * 8);
25 for (unsigned int p = 0; p < ret.size(); p++) {
26 ret[p] = (bytes[p / 8] & (1 << (p % 8))) != 0;
27 }
28 return ret;
29}
30
31CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std::set<Txid>* txids)
32{
33 header = static_cast<const CBlockHeader&>(block);
34
35 std::vector<bool> vMatch;
36 std::vector<Txid> vHashes;
37
38 vMatch.reserve(block.vtx.size());
39 vHashes.reserve(block.vtx.size());
40
41 for (unsigned int i = 0; i < block.vtx.size(); i++)
42 {
43 const Txid& hash{block.vtx[i]->GetHash()};
44 if (txids && txids->contains(hash)) {
45 vMatch.push_back(true);
46 } else if (filter && filter->IsRelevantAndUpdate(*block.vtx[i])) {
47 vMatch.push_back(true);
48 vMatchedTxn.emplace_back(i, hash);
49 } else {
50 vMatch.push_back(false);
51 }
52 vHashes.push_back(hash);
53 }
54
55 txn = CPartialMerkleTree(vHashes, vMatch);
56}
57
58// NOLINTNEXTLINE(misc-no-recursion)
59uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<Txid> &vTxid) {
60 //we can never have zero txs in a merkle block, we always need the coinbase tx
61 //if we do not have this assert, we can hit a memory access violation when indexing into vTxid
62 assert(vTxid.size() != 0);
63 if (height == 0) {
64 // hash at height 0 is the txids themselves
65 return vTxid[pos].ToUint256();
66 } else {
67 // calculate left hash
68 uint256 left = CalcHash(height-1, pos*2, vTxid), right;
69 // calculate right hash if not beyond the end of the array - copy left hash otherwise
70 if (pos*2+1 < CalcTreeWidth(height-1))
71 right = CalcHash(height-1, pos*2+1, vTxid);
72 else
73 right = left;
74 // combine subhashes
75 return Hash(left, right);
76 }
77}
78
79// NOLINTNEXTLINE(misc-no-recursion)
80void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch) {
81 // determine whether this node is the parent of at least one matched txid
82 bool fParentOfMatch = false;
83 for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
84 fParentOfMatch |= vMatch[p];
85 // store as flag bit
86 vBits.push_back(fParentOfMatch);
87 if (height==0 || !fParentOfMatch) {
88 // if at height 0, or nothing interesting below, store hash and stop
89 vHash.push_back(CalcHash(height, pos, vTxid));
90 } else {
91 // otherwise, don't store any hash, but descend into the subtrees
92 TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
93 if (pos*2+1 < CalcTreeWidth(height-1))
94 TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
95 }
96}
97
98// NOLINTNEXTLINE(misc-no-recursion)
99uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex) {
100 if (nBitsUsed >= vBits.size()) {
101 // overflowed the bits array - failure
102 fBad = true;
103 return uint256();
104 }
105 bool fParentOfMatch = vBits[nBitsUsed++];
106 if (height==0 || !fParentOfMatch) {
107 // if at height 0, or nothing interesting below, use stored hash and do not descend
108 if (nHashUsed >= vHash.size()) {
109 // overflowed the hash array - failure
110 fBad = true;
111 return uint256();
112 }
113 const uint256 &hash = vHash[nHashUsed++];
114 if (height==0 && fParentOfMatch) { // in case of height 0, we have a matched txid
115 vMatch.push_back(Txid::FromUint256(hash));
116 vnIndex.push_back(pos);
117 }
118 return hash;
119 } else {
120 // otherwise, descend into the subtrees to extract matched txids and hashes
121 uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch, vnIndex), right;
122 if (pos*2+1 < CalcTreeWidth(height-1)) {
123 right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch, vnIndex);
124 if (right == left) {
125 // The left and right branches should never be identical, as the transaction
126 // hashes covered by them must each be unique.
127 fBad = true;
128 }
129 } else {
130 right = left;
131 }
132 // and combine them before returning
133 return Hash(left, right);
134 }
135}
136
137CPartialMerkleTree::CPartialMerkleTree(const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
138 // reset state
139 vBits.clear();
140 vHash.clear();
141
142 // calculate height of tree
143 int nHeight = 0;
144 while (CalcTreeWidth(nHeight) > 1)
145 nHeight++;
146
147 // traverse the partial tree
148 TraverseAndBuild(nHeight, 0, vTxid, vMatch);
149}
150
151CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
152
153uint256 CPartialMerkleTree::ExtractMatches(std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex) {
154 vMatch.clear();
155 // An empty set will not work
156 if (nTransactions == 0)
157 return uint256();
158 // check for excessively high numbers of transactions
160 return uint256();
161 // there can never be more hashes provided than one for every txid
162 if (vHash.size() > nTransactions)
163 return uint256();
164 // there must be at least one bit per node in the partial tree, and at least one node per hash
165 if (vBits.size() < vHash.size())
166 return uint256();
167 // calculate height of tree
168 int nHeight = 0;
169 while (CalcTreeWidth(nHeight) > 1)
170 nHeight++;
171 // traverse the partial tree
172 unsigned int nBitsUsed = 0, nHashUsed = 0;
173 uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch, vnIndex);
174 // verify that no problems occurred during the tree traversal
175 if (fBad)
176 return uint256();
177 // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
178 if (CeilDiv(nBitsUsed, 8u) != CeilDiv(vBits.size(), 8u))
179 return uint256();
180 // verify that all hashes were consumed
181 if (nHashUsed != vHash.size())
182 return uint256();
183 return hashMerkleRoot;
184}
int ret
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:27
Definition: block.h:74
std::vector< CTransactionRef > vtx
Definition: block.h:77
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
Definition: bloom.h:45
bool IsRelevantAndUpdate(const CTransaction &tx)
Also adds any outputs which match the filter to the filter (to match their spending txes)
Definition: bloom.cpp:95
std::vector< std::pair< unsigned int, Txid > > vMatchedTxn
Public only for unit testing and relay testing (not relayed).
Definition: merkleblock.h:139
CBlockHeader header
Public only for unit testing.
Definition: merkleblock.h:130
CPartialMerkleTree txn
Definition: merkleblock.h:131
CMerkleBlock()=default
Data structure that represents a partial merkle tree.
Definition: merkleblock.h:57
unsigned int nTransactions
the total number of transactions in the block
Definition: merkleblock.h:60
uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector< Txid > &vMatch, std::vector< unsigned int > &vnIndex)
recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBu...
Definition: merkleblock.cpp:99
std::vector< bool > vBits
node-is-parent-of-matched-txid bits
Definition: merkleblock.h:63
bool fBad
flag set when encountering invalid data
Definition: merkleblock.h:69
uint256 CalcHash(int height, unsigned int pos, const std::vector< Txid > &vTxid)
calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves)
Definition: merkleblock.cpp:59
std::vector< uint256 > vHash
txids and internal hashes
Definition: merkleblock.h:66
void TraverseAndBuild(int height, unsigned int pos, const std::vector< Txid > &vTxid, const std::vector< bool > &vMatch)
recursive function that traverses tree nodes, storing the data as bits and hashes
Definition: merkleblock.cpp:80
uint256 ExtractMatches(std::vector< Txid > &vMatch, std::vector< unsigned int > &vnIndex)
extract the matching txid's represented by this partial merkle tree and their respective indices with...
unsigned int CalcTreeWidth(int height) const
helper function to efficiently calculate the number of nodes at given height in the merkle tree
Definition: merkleblock.h:72
static transaction_identifier FromUint256(const uint256 &id)
256-bit opaque blob.
Definition: uint256.h:195
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
Definition: consensus.h:15
static const size_t MIN_TRANSACTION_WEIGHT
Definition: consensus.h:23
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
unsigned int nHeight
std::vector< unsigned char > BitsToBytes(const std::vector< bool > &bits)
Definition: merkleblock.cpp:13
std::vector< bool > BytesToBits(const std::vector< unsigned char > &bytes)
Definition: merkleblock.cpp:22
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
Definition: overflow.h:70
assert(!tx.IsCoinBase())