merkleblock.h raw

   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  #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      unsigned int CalcTreeWidth(int height) const {
  73          return (nTransactions+(1 << height)-1) >> height;
  74      }
  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      {
  92          READWRITE(obj.nTransactions, obj.vHash);
  93          std::vector<unsigned char> bytes;
  94          SER_WRITE(obj, bytes = BitsToBytes(obj.vBits));
  95          READWRITE(bytes);
  96          SER_READ(obj, obj.vBits = BytesToBits(bytes));
  97          SER_READ(obj, obj.fBad = false);
  98      }
  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      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      CMerkleBlock(const CBlock& block, CBloomFilter& filter) : CMerkleBlock(block, &filter, nullptr) { }
 147  
 148      // Create from a CBlock, matching the txids in the set
 149      CMerkleBlock(const CBlock& block, const std::set<Txid>& txids) : CMerkleBlock{block, nullptr, &txids} {}
 150  
 151      CMerkleBlock() = default;
 152  
 153      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
 161