/ src / util / hasher.h
hasher.h
  1  // Copyright (c) 2019-present The Bitcoin Core developers
  2  // Distributed under the MIT software license, see the accompanying
  3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4  
  5  #ifndef BITCOIN_UTIL_HASHER_H
  6  #define BITCOIN_UTIL_HASHER_H
  7  
  8  #include <crypto/common.h>
  9  #include <crypto/siphash.h>
 10  #include <primitives/transaction.h>
 11  #include <uint256.h>
 12  
 13  #include <cstdint>
 14  #include <cstring>
 15  #include <span>
 16  
 17  class SaltedUint256Hasher
 18  {
 19      const PresaltedSipHasher m_hasher;
 20  
 21  public:
 22      SaltedUint256Hasher();
 23  
 24      size_t operator()(const uint256& hash) const
 25      {
 26          return m_hasher(hash);
 27      }
 28  };
 29  
 30  class SaltedTxidHasher
 31  {
 32      const PresaltedSipHasher m_hasher;
 33  
 34  public:
 35      SaltedTxidHasher();
 36  
 37      size_t operator()(const Txid& txid) const
 38      {
 39          return m_hasher(txid.ToUint256());
 40      }
 41  };
 42  
 43  class SaltedWtxidHasher
 44  {
 45      const PresaltedSipHasher m_hasher;
 46  
 47  public:
 48      SaltedWtxidHasher();
 49  
 50      size_t operator()(const Wtxid& wtxid) const
 51      {
 52          return m_hasher(wtxid.ToUint256());
 53      }
 54  };
 55  
 56  class SaltedOutpointHasher
 57  {
 58      const PresaltedSipHasher m_hasher;
 59  
 60  public:
 61      SaltedOutpointHasher(bool deterministic = false);
 62  
 63      /**
 64       * Having the hash noexcept allows libstdc++'s unordered_map to recalculate
 65       * the hash during rehash, so it does not have to cache the value. This
 66       * reduces node's memory by sizeof(size_t). The required recalculation has
 67       * a slight performance penalty (around 1.6%), but this is compensated by
 68       * memory savings of about 9% which allow for a larger dbcache setting.
 69       *
 70       * @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html
 71       */
 72      size_t operator()(const COutPoint& id) const noexcept
 73      {
 74          return m_hasher(id.hash.ToUint256(), id.n);
 75      }
 76  };
 77  
 78  /**
 79   * We're hashing a nonce into the entries themselves, so we don't need extra
 80   * blinding in the set hash computation.
 81   *
 82   * This may exhibit platform endian dependent behavior but because these are
 83   * nonced hashes (random) and this state is only ever used locally it is safe.
 84   * All that matters is local consistency.
 85   */
 86  class SignatureCacheHasher
 87  {
 88  public:
 89      template <uint8_t hash_select>
 90      uint32_t operator()(const uint256& key) const
 91      {
 92          static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
 93          uint32_t u;
 94          std::memcpy(&u, key.begin()+4*hash_select, 4);
 95          return u;
 96      }
 97  };
 98  
 99  struct BlockHasher
100  {
101      // this used to call `GetCheapHash()` in uint256, which was later moved; the
102      // cheap hash function simply calls ReadLE64() however, so the end result is
103      // identical
104      size_t operator()(const uint256& hash) const { return ReadLE64(hash.begin()); }
105  };
106  
107  class SaltedSipHasher
108  {
109  private:
110      /** Salt */
111      const uint64_t m_k0, m_k1;
112  
113  public:
114      SaltedSipHasher();
115  
116      size_t operator()(const std::span<const unsigned char>& script) const;
117  };
118  
119  #endif // BITCOIN_UTIL_HASHER_H