Coverage Report

Created: 2025-09-19 18:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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