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