/Users/eugenesiegel/btc/bitcoin/src/merkleblock.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2009-2010 Satoshi Nakamoto | 
| 2 |  | // Copyright (c) 2009-2021 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 |  | #ifndef BITCOIN_MERKLEBLOCK_H | 
| 7 |  | #define BITCOIN_MERKLEBLOCK_H | 
| 8 |  |  | 
| 9 |  | #include <common/bloom.h> | 
| 10 |  | #include <primitives/block.h> | 
| 11 |  | #include <primitives/transaction_identifier.h> | 
| 12 |  | #include <serialize.h> | 
| 13 |  | #include <uint256.h> | 
| 14 |  |  | 
| 15 |  | #include <set> | 
| 16 |  | #include <vector> | 
| 17 |  |  | 
| 18 |  | // Helper functions for serialization. | 
| 19 |  | std::vector<unsigned char> BitsToBytes(const std::vector<bool>& bits); | 
| 20 |  | std::vector<bool> BytesToBits(const std::vector<unsigned char>& bytes); | 
| 21 |  |  | 
| 22 |  | /** Data structure that represents a partial merkle tree. | 
| 23 |  |  * | 
| 24 |  |  * It represents a subset of the txid's of a known block, in a way that | 
| 25 |  |  * allows recovery of the list of txid's and the merkle root, in an | 
| 26 |  |  * authenticated way. | 
| 27 |  |  * | 
| 28 |  |  * The encoding works as follows: we traverse the tree in depth-first order, | 
| 29 |  |  * storing a bit for each traversed node, signifying whether the node is the | 
| 30 |  |  * parent of at least one matched leaf txid (or a matched txid itself). In | 
| 31 |  |  * case we are at the leaf level, or this bit is 0, its merkle node hash is | 
| 32 |  |  * stored, and its children are not explored further. Otherwise, no hash is | 
| 33 |  |  * stored, but we recurse into both (or the only) child branch. During | 
| 34 |  |  * decoding, the same depth-first traversal is performed, consuming bits and | 
| 35 |  |  * hashes as they written during encoding. | 
| 36 |  |  * | 
| 37 |  |  * The serialization is fixed and provides a hard guarantee about the | 
| 38 |  |  * encoded size: | 
| 39 |  |  * | 
| 40 |  |  *   SIZE <= 10 + ceil(32.25*N) | 
| 41 |  |  * | 
| 42 |  |  * Where N represents the number of leaf nodes of the partial tree. N itself | 
| 43 |  |  * is bounded by: | 
| 44 |  |  * | 
| 45 |  |  *   N <= total_transactions | 
| 46 |  |  *   N <= 1 + matched_transactions*tree_height | 
| 47 |  |  * | 
| 48 |  |  * The serialization format: | 
| 49 |  |  *  - uint32     total_transactions (4 bytes) | 
| 50 |  |  *  - varint     number of hashes   (1-3 bytes) | 
| 51 |  |  *  - uint256[]  hashes in depth-first order (<= 32*N bytes) | 
| 52 |  |  *  - varint     number of bytes of flag bits (1-3 bytes) | 
| 53 |  |  *  - byte[]     flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits) | 
| 54 |  |  * The size constraints follow from this. | 
| 55 |  |  */ | 
| 56 |  | class CPartialMerkleTree | 
| 57 |  | { | 
| 58 |  | protected: | 
| 59 |  |     /** the total number of transactions in the block */ | 
| 60 |  |     unsigned int nTransactions; | 
| 61 |  |  | 
| 62 |  |     /** node-is-parent-of-matched-txid bits */ | 
| 63 |  |     std::vector<bool> vBits; | 
| 64 |  |  | 
| 65 |  |     /** txids and internal hashes */ | 
| 66 |  |     std::vector<uint256> vHash; | 
| 67 |  |  | 
| 68 |  |     /** flag set when encountering invalid data */ | 
| 69 |  |     bool fBad; | 
| 70 |  |  | 
| 71 |  |     /** helper function to efficiently calculate the number of nodes at given height in the merkle tree */ | 
| 72 | 0 |     unsigned int CalcTreeWidth(int height) const { | 
| 73 | 0 |         return (nTransactions+(1 << height)-1) >> height; | 
| 74 | 0 |     } | 
| 75 |  |  | 
| 76 |  |     /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */ | 
| 77 |  |     uint256 CalcHash(int height, unsigned int pos, const std::vector<Txid> &vTxid); | 
| 78 |  |  | 
| 79 |  |     /** recursive function that traverses tree nodes, storing the data as bits and hashes */ | 
| 80 |  |     void TraverseAndBuild(int height, unsigned int pos, const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch); | 
| 81 |  |  | 
| 82 |  |     /** | 
| 83 |  |      * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild. | 
| 84 |  |      * it returns the hash of the respective node and its respective index. | 
| 85 |  |      */ | 
| 86 |  |     uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex); | 
| 87 |  |  | 
| 88 |  | public: | 
| 89 |  |  | 
| 90 |  |     SERIALIZE_METHODS(CPartialMerkleTree, obj) | 
| 91 | 0 |     { | 
| 92 | 0 |         READWRITE(obj.nTransactions, obj.vHash); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(obj.nTransactions, obj.vHash); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(obj.nTransactions, obj.vHash); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 | 
| 93 | 0 |         std::vector<unsigned char> bytes; | 
| 94 | 0 |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits)); | Line | Count | Source |  | 147 | 0 | #define SER_WRITE(obj, code) ser_action.SerWrite(s, obj, [&](Stream& s, const Type& obj) { code; }) | 
 |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits)); | Line | Count | Source |  | 147 | 0 | #define SER_WRITE(obj, code) ser_action.SerWrite(s, obj, [&](Stream& s, const Type& obj) { code; }) | 
 |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits)); | Line | Count | Source |  | 147 | 0 | #define SER_WRITE(obj, code) ser_action.SerWrite(s, obj, [&](Stream& s, const Type& obj) { code; }) | 
 | 
| 95 | 0 |         READWRITE(bytes); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(bytes); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(bytes); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 | 
| 96 | 0 |         SER_READ(obj, obj.vBits = BytesToBits(bytes)); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 |         SER_READ(obj, obj.vBits = BytesToBits(bytes)); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 |         SER_READ(obj, obj.vBits = BytesToBits(bytes)); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 | 
| 97 | 0 |         SER_READ(obj, obj.fBad = false); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 |         SER_READ(obj, obj.fBad = false); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 |         SER_READ(obj, obj.fBad = false); | Line | Count | Source |  | 146 | 0 | #define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, std::remove_const_t<Type>& obj) { code; }) | 
 | 
| 98 | 0 |     } Unexecuted instantiation: _ZN18CPartialMerkleTree16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN18CPartialMerkleTree16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN18CPartialMerkleTree16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 99 |  |  | 
| 100 |  |     /** Construct a partial merkle tree from a list of transaction ids, and a mask that selects a subset of them */ | 
| 101 |  |     CPartialMerkleTree(const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch); | 
| 102 |  |  | 
| 103 |  |     CPartialMerkleTree(); | 
| 104 |  |  | 
| 105 |  |     /** | 
| 106 |  |      * extract the matching txid's represented by this partial merkle tree | 
| 107 |  |      * and their respective indices within the partial tree. | 
| 108 |  |      * returns the merkle root, or 0 in case of failure | 
| 109 |  |      */ | 
| 110 |  |     uint256 ExtractMatches(std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex); | 
| 111 |  |  | 
| 112 |  |     /** Get number of transactions the merkle proof is indicating for cross-reference with | 
| 113 |  |      * local blockchain knowledge. | 
| 114 |  |      */ | 
| 115 | 0 |     unsigned int GetNumTransactions() const { return nTransactions; }; | 
| 116 |  |  | 
| 117 |  | }; | 
| 118 |  |  | 
| 119 |  |  | 
| 120 |  | /** | 
| 121 |  |  * Used to relay blocks as header + vector<merkle branch> | 
| 122 |  |  * to filtered nodes. | 
| 123 |  |  * | 
| 124 |  |  * NOTE: The class assumes that the given CBlock has *at least* 1 transaction. If the CBlock has 0 txs, it will hit an assertion. | 
| 125 |  |  */ | 
| 126 |  | class CMerkleBlock | 
| 127 |  | { | 
| 128 |  | public: | 
| 129 |  |     /** Public only for unit testing */ | 
| 130 |  |     CBlockHeader header; | 
| 131 |  |     CPartialMerkleTree txn; | 
| 132 |  |  | 
| 133 |  |     /** | 
| 134 |  |      * Public only for unit testing and relay testing (not relayed). | 
| 135 |  |      * | 
| 136 |  |      * Used only when a bloom filter is specified to allow | 
| 137 |  |      * testing the transactions which matched the bloom filter. | 
| 138 |  |      */ | 
| 139 |  |     std::vector<std::pair<unsigned int, Txid> > vMatchedTxn; | 
| 140 |  |  | 
| 141 |  |     /** | 
| 142 |  |      * Create from a CBlock, filtering transactions according to filter | 
| 143 |  |      * Note that this will call IsRelevantAndUpdate on the filter for each transaction, | 
| 144 |  |      * thus the filter will likely be modified. | 
| 145 |  |      */ | 
| 146 | 0 |     CMerkleBlock(const CBlock& block, CBloomFilter& filter) : CMerkleBlock(block, &filter, nullptr) { } | 
| 147 |  |  | 
| 148 |  |     // Create from a CBlock, matching the txids in the set | 
| 149 | 0 |     CMerkleBlock(const CBlock& block, const std::set<Txid>& txids) : CMerkleBlock{block, nullptr, &txids} {} | 
| 150 |  |  | 
| 151 | 0 |     CMerkleBlock() = default; | 
| 152 |  |  | 
| 153 | 0 |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); }| Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); }| Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); }| Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
Unexecuted instantiation: _ZN12CMerkleBlock16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN12CMerkleBlock16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN12CMerkleBlock16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 154 |  |  | 
| 155 |  | private: | 
| 156 |  |     // Combined constructor to consolidate code | 
| 157 |  |     CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std::set<Txid>* txids); | 
| 158 |  | }; | 
| 159 |  |  | 
| 160 |  | #endif // BITCOIN_MERKLEBLOCK_H |