merkleblock.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2020 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 8 #include <hash.h> 9 #include <consensus/consensus.h> 10 11 12 std::vector<unsigned char> BitsToBytes(const std::vector<bool>& bits) 13 { 14 std::vector<unsigned char> ret((bits.size() + 7) / 8); 15 for (unsigned int p = 0; p < bits.size(); p++) { 16 ret[p / 8] |= bits[p] << (p % 8); 17 } 18 return ret; 19 } 20 21 std::vector<bool> BytesToBits(const std::vector<unsigned char>& bytes) 22 { 23 std::vector<bool> ret(bytes.size() * 8); 24 for (unsigned int p = 0; p < ret.size(); p++) { 25 ret[p] = (bytes[p / 8] & (1 << (p % 8))) != 0; 26 } 27 return ret; 28 } 29 30 CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std::set<Txid>* txids) 31 { 32 header = block.GetBlockHeader(); 33 34 std::vector<bool> vMatch; 35 std::vector<uint256> vHashes; 36 37 vMatch.reserve(block.vtx.size()); 38 vHashes.reserve(block.vtx.size()); 39 40 for (unsigned int i = 0; i < block.vtx.size(); i++) 41 { 42 const Txid& hash{block.vtx[i]->GetHash()}; 43 if (txids && txids->count(hash)) { 44 vMatch.push_back(true); 45 } else if (filter && filter->IsRelevantAndUpdate(*block.vtx[i])) { 46 vMatch.push_back(true); 47 vMatchedTxn.emplace_back(i, hash); 48 } else { 49 vMatch.push_back(false); 50 } 51 vHashes.push_back(hash); 52 } 53 54 txn = CPartialMerkleTree(vHashes, vMatch); 55 } 56 57 // NOLINTNEXTLINE(misc-no-recursion) 58 uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { 59 //we can never have zero txs in a merkle block, we always need the coinbase tx 60 //if we do not have this assert, we can hit a memory access violation when indexing into vTxid 61 assert(vTxid.size() != 0); 62 if (height == 0) { 63 // hash at height 0 is the txids themselves 64 return vTxid[pos]; 65 } else { 66 // calculate left hash 67 uint256 left = CalcHash(height-1, pos*2, vTxid), right; 68 // calculate right hash if not beyond the end of the array - copy left hash otherwise 69 if (pos*2+1 < CalcTreeWidth(height-1)) 70 right = CalcHash(height-1, pos*2+1, vTxid); 71 else 72 right = left; 73 // combine subhashes 74 return Hash(left, right); 75 } 76 } 77 78 // NOLINTNEXTLINE(misc-no-recursion) 79 void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { 80 // determine whether this node is the parent of at least one matched txid 81 bool fParentOfMatch = false; 82 for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) 83 fParentOfMatch |= vMatch[p]; 84 // store as flag bit 85 vBits.push_back(fParentOfMatch); 86 if (height==0 || !fParentOfMatch) { 87 // if at height 0, or nothing interesting below, store hash and stop 88 vHash.push_back(CalcHash(height, pos, vTxid)); 89 } else { 90 // otherwise, don't store any hash, but descend into the subtrees 91 TraverseAndBuild(height-1, pos*2, vTxid, vMatch); 92 if (pos*2+1 < CalcTreeWidth(height-1)) 93 TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch); 94 } 95 } 96 97 // NOLINTNEXTLINE(misc-no-recursion) 98 uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) { 99 if (nBitsUsed >= vBits.size()) { 100 // overflowed the bits array - failure 101 fBad = true; 102 return uint256(); 103 } 104 bool fParentOfMatch = vBits[nBitsUsed++]; 105 if (height==0 || !fParentOfMatch) { 106 // if at height 0, or nothing interesting below, use stored hash and do not descend 107 if (nHashUsed >= vHash.size()) { 108 // overflowed the hash array - failure 109 fBad = true; 110 return uint256(); 111 } 112 const uint256 &hash = vHash[nHashUsed++]; 113 if (height==0 && fParentOfMatch) { // in case of height 0, we have a matched txid 114 vMatch.push_back(hash); 115 vnIndex.push_back(pos); 116 } 117 return hash; 118 } else { 119 // otherwise, descend into the subtrees to extract matched txids and hashes 120 uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch, vnIndex), right; 121 if (pos*2+1 < CalcTreeWidth(height-1)) { 122 right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch, vnIndex); 123 if (right == left) { 124 // The left and right branches should never be identical, as the transaction 125 // hashes covered by them must each be unique. 126 fBad = true; 127 } 128 } else { 129 right = left; 130 } 131 // and combine them before returning 132 return Hash(left, right); 133 } 134 } 135 136 CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) { 137 // reset state 138 vBits.clear(); 139 vHash.clear(); 140 141 // calculate height of tree 142 int nHeight = 0; 143 while (CalcTreeWidth(nHeight) > 1) 144 nHeight++; 145 146 // traverse the partial tree 147 TraverseAndBuild(nHeight, 0, vTxid, vMatch); 148 } 149 150 CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} 151 152 uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) { 153 vMatch.clear(); 154 // An empty set will not work 155 if (nTransactions == 0) 156 return uint256(); 157 // check for excessively high numbers of transactions 158 if (nTransactions > MAX_BLOCK_WEIGHT / MIN_TRANSACTION_WEIGHT) 159 return uint256(); 160 // there can never be more hashes provided than one for every txid 161 if (vHash.size() > nTransactions) 162 return uint256(); 163 // there must be at least one bit per node in the partial tree, and at least one node per hash 164 if (vBits.size() < vHash.size()) 165 return uint256(); 166 // calculate height of tree 167 int nHeight = 0; 168 while (CalcTreeWidth(nHeight) > 1) 169 nHeight++; 170 // traverse the partial tree 171 unsigned int nBitsUsed = 0, nHashUsed = 0; 172 uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch, vnIndex); 173 // verify that no problems occurred during the tree traversal 174 if (fBad) 175 return uint256(); 176 // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) 177 if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) 178 return uint256(); 179 // verify that all hashes were consumed 180 if (nHashUsed != vHash.size()) 181 return uint256(); 182 return hashMerkleRoot; 183 }