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