Line data Source code
1 : // Copyright (c) 2019-2025 The Dash 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_SALTEDHASHER_H
6 : #define BITCOIN_SALTEDHASHER_H
7 :
8 : #include <hash.h>
9 : #include <uint256.h>
10 : #include <crypto/siphash.h>
11 :
12 : #include <unordered_map>
13 : #include <unordered_set>
14 :
15 : /** Helper classes for std::unordered_map and std::unordered_set hashing */
16 :
17 : template<typename T> struct SaltedHasherImpl;
18 :
19 : template<typename N>
20 : struct SaltedHasherImpl<std::pair<uint256, N>>
21 : {
22 3899 : static std::size_t CalcHash(const std::pair<uint256, N>& v, uint64_t k0, uint64_t k1)
23 : {
24 3899 : return SipHashUint256Extra(k0, k1, v.first, (uint32_t) v.second);
25 : }
26 : };
27 :
28 : template<typename N>
29 : struct SaltedHasherImpl<std::pair<N, uint256>>
30 : {
31 0 : static std::size_t CalcHash(const std::pair<N, uint256>& v, uint64_t k0, uint64_t k1)
32 : {
33 0 : return SipHashUint256Extra(k0, k1, v.second, (uint32_t) v.first);
34 : }
35 : };
36 :
37 : template<>
38 : struct SaltedHasherImpl<uint256>
39 : {
40 1023041 : static std::size_t CalcHash(const uint256& v, uint64_t k0, uint64_t k1)
41 : {
42 1023041 : return SipHashUint256(k0, k1, v);
43 : }
44 : };
45 :
46 : struct SaltedHasherBase
47 : {
48 : /** Salt */
49 : const uint64_t k0, k1;
50 :
51 : SaltedHasherBase();
52 : };
53 :
54 : /* Allows each instance of unordered maps/sest to have their own salt */
55 : template<typename T, typename S>
56 : struct SaltedHasher
57 : {
58 : S s;
59 : std::size_t operator()(const T& v) const
60 : {
61 : return SaltedHasherImpl<T>::CalcHash(v, s.k0, s.k1);
62 : }
63 : };
64 :
65 : /* Allows to use a static salt for all instances. The salt is a random value set at startup
66 : * (through static initialization)
67 : */
68 : struct StaticSaltedHasher
69 : {
70 : static SaltedHasherBase s;
71 :
72 : template<typename T>
73 1026940 : std::size_t operator()(const T& v) const
74 : {
75 1026940 : return SaltedHasherImpl<T>::CalcHash(v, s.k0, s.k1);
76 : }
77 : };
78 :
79 :
80 : template <typename T>
81 : using Uint256HashMap = std::unordered_map<uint256, T, StaticSaltedHasher>;
82 :
83 : using Uint256HashSet = std::unordered_set<uint256, StaticSaltedHasher>;
84 :
85 :
86 : template <typename Key, typename Value, typename Hasher, size_t MaxSize, size_t TruncateThreshold>
87 : class unordered_lru_cache;
88 : template <typename T, size_t MaxSize = 0ul, size_t TruncateThreshold = 0ul>
89 : using Uint256LruHashMap = unordered_lru_cache<uint256, T, StaticSaltedHasher, MaxSize, TruncateThreshold>;
90 :
91 : #endif // BITCOIN_SALTEDHASHER_H
|