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