/root/bitcoin/src/merkleblock.h
Line  | Count  | Source  | 
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  | 382k  |     unsigned int CalcTreeWidth(int height) const { | 
73  | 382k  |         return (nTransactions+(1 << height)-1) >> height;  | 
74  | 382k  |     }  | 
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  | 920  |     { | 
92  | 920  |         READWRITE(obj.nTransactions, obj.vHash);  | 
93  | 920  |         std::vector<unsigned char> bytes;  | 
94  | 920  |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits));  | 
95  | 920  |         READWRITE(bytes);  | 
96  | 920  |         SER_READ(obj, obj.vBits = BytesToBits(bytes));  | 
97  | 920  |         SER_READ(obj, obj.fBad = false);  | 
98  | 920  |     } _ZN18CPartialMerkleTree16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_ Line  | Count  | Source  |  91  | 205  |     { |  92  | 205  |         READWRITE(obj.nTransactions, obj.vHash);  |  93  | 205  |         std::vector<unsigned char> bytes;  |  94  | 205  |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits));  |  95  | 205  |         READWRITE(bytes);  |  96  | 205  |         SER_READ(obj, obj.vBits = BytesToBits(bytes));  |  97  | 205  |         SER_READ(obj, obj.fBad = false);  |  98  | 205  |     }  |  
 _ZN18CPartialMerkleTree16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_ Line  | Count  | Source  |  91  | 97  |     { |  92  | 97  |         READWRITE(obj.nTransactions, obj.vHash);  |  93  | 97  |         std::vector<unsigned char> bytes;  |  94  | 97  |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits));  |  95  | 97  |         READWRITE(bytes);  |  96  | 97  |         SER_READ(obj, obj.vBits = BytesToBits(bytes));  |  97  | 97  |         SER_READ(obj, obj.fBad = false);  |  98  | 97  |     }  |  
 _ZN18CPartialMerkleTree16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ Line  | Count  | Source  |  91  | 618  |     { |  92  | 618  |         READWRITE(obj.nTransactions, obj.vHash);  |  93  | 618  |         std::vector<unsigned char> bytes;  |  94  | 618  |         SER_WRITE(obj, bytes = BitsToBytes(obj.vBits));  |  95  | 618  |         READWRITE(bytes);  |  96  | 618  |         SER_READ(obj, obj.vBits = BytesToBits(bytes));  |  97  | 618  |         SER_READ(obj, obj.fBad = false);  |  98  | 618  |     }  |  
  | 
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  | 311  |     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  | 661  |     CMerkleBlock(const CBlock& block, CBloomFilter& filter) : CMerkleBlock(block, &filter, nullptr) { } | 
147  |  |  | 
148  |  |     // Create from a CBlock, matching the txids in the set  | 
149  | 72  |     CMerkleBlock(const CBlock& block, const std::set<Txid>& txids) : CMerkleBlock{block, nullptr, &txids} {} | 
150  |  |  | 
151  | 1.11k  |     CMerkleBlock() = default;  | 
152  |  |  | 
153  | 770  |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); }_ZN12CMerkleBlock16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_ Line  | Count  | Source  |  153  | 103  |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); } |  
 _ZN12CMerkleBlock16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_ Line  | Count  | Source  |  153  | 49  |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); } |  
 _ZN12CMerkleBlock16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ Line  | Count  | Source  |  153  | 618  |     SERIALIZE_METHODS(CMerkleBlock, obj) { READWRITE(obj.header, obj.txn); } |  
  | 
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  |