hasher.h raw
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
120