Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 <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
13.4M
    size_t operator()(const uint256& txid) const {
27
13.4M
        return SipHashUint256(k0, k1, txid);
28
13.4M
    }
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
59.2M
    size_t operator()(const COutPoint& id) const noexcept {
50
59.2M
        return SipHashUint256Extra(k0, k1, id.hash, id.n);
51
59.2M
    }
52
};
53
54
struct FilterHeaderHasher
55
{
56
0
    size_t operator()(const uint256& hash) const { return ReadLE64(hash.begin()); }
57
};
58
59
/**
60
 * We're hashing a nonce into the entries themselves, so we don't need extra
61
 * blinding in the set hash computation.
62
 *
63
 * This may exhibit platform endian dependent behavior but because these are
64
 * nonced hashes (random) and this state is only ever used locally it is safe.
65
 * All that matters is local consistency.
66
 */
67
class SignatureCacheHasher
68
{
69
public:
70
    template <uint8_t hash_select>
71
    uint32_t operator()(const uint256& key) const
72
1.25M
    {
73
1.25M
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
1.25M
        uint32_t u;
75
1.25M
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
1.25M
        return u;
77
1.25M
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)0>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)1>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)2>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)3>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)4>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)5>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)6>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
unsigned int SignatureCacheHasher::operator()<(unsigned char)7>(uint256 const&) const
Line
Count
Source
72
156k
    {
73
156k
        static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
74
156k
        uint32_t u;
75
156k
        std::memcpy(&u, key.begin()+4*hash_select, 4);
76
156k
        return u;
77
156k
    }
78
};
79
80
struct BlockHasher
81
{
82
    // this used to call `GetCheapHash()` in uint256, which was later moved; the
83
    // cheap hash function simply calls ReadLE64() however, so the end result is
84
    // identical
85
27.7M
    size_t operator()(const uint256& hash) const { return ReadLE64(hash.begin()); }
86
};
87
88
class SaltedSipHasher
89
{
90
private:
91
    /** Salt */
92
    const uint64_t m_k0, m_k1;
93
94
public:
95
    SaltedSipHasher();
96
97
    size_t operator()(const std::span<const unsigned char>& script) const;
98
};
99
100
#endif // BITCOIN_UTIL_HASHER_H