Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/util/transaction_identifier.h
Line
Count
Source
1
// Copyright (c) 2023-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or https://opensource.org/license/mit.
4
5
#ifndef BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
6
#define BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
7
8
#include <attributes.h>
9
#include <uint256.h>
10
#include <util/types.h>
11
12
/** transaction_identifier represents the two canonical transaction identifier
13
 * types (txid, wtxid).*/
14
template <bool has_witness>
15
class transaction_identifier
16
{
17
    uint256 m_wrapped;
18
19
    // Note: Use FromUint256 externally instead.
20
7.88M
    transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
transaction_identifier<false>::transaction_identifier(uint256 const&)
Line
Count
Source
20
2.99M
    transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
transaction_identifier<true>::transaction_identifier(uint256 const&)
Line
Count
Source
20
4.89M
    transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
21
22
    // TODO: Comparisons with uint256 should be disallowed once we have
23
    // converted most of the code to using the new txid types.
24
8.97k
    constexpr int Compare(const uint256& other) const { return m_wrapped.Compare(other); }
25
170M
    constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
transaction_identifier<false>::Compare(transaction_identifier<false> const&) const
Line
Count
Source
25
150M
    constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
transaction_identifier<true>::Compare(transaction_identifier<true> const&) const
Line
Count
Source
25
20.5M
    constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
26
    template <typename Other>
27
    constexpr int Compare(const Other& other) const
28
    {
29
        static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
30
        return 0;
31
    }
32
33
public:
34
8.43M
    transaction_identifier() : m_wrapped{} {}
transaction_identifier<false>::transaction_identifier()
Line
Count
Source
34
8.37M
    transaction_identifier() : m_wrapped{} {}
transaction_identifier<true>::transaction_identifier()
Line
Count
Source
34
53.5k
    transaction_identifier() : m_wrapped{} {}
35
36
    template <typename Other>
37
19.9M
    bool operator==(const Other& other) const { return Compare(other) == 0; }
bool transaction_identifier<false>::operator==<transaction_identifier<false> >(transaction_identifier<false> const&) const
Line
Count
Source
37
19.9M
    bool operator==(const Other& other) const { return Compare(other) == 0; }
bool transaction_identifier<false>::operator==<uint256>(uint256 const&) const
Line
Count
Source
37
8.97k
    bool operator==(const Other& other) const { return Compare(other) == 0; }
38
    template <typename Other>
39
370
    bool operator!=(const Other& other) const { return Compare(other) != 0; }
bool transaction_identifier<false>::operator!=<transaction_identifier<false> >(transaction_identifier<false> const&) const
Line
Count
Source
39
370
    bool operator!=(const Other& other) const { return Compare(other) != 0; }
Unexecuted instantiation: bool transaction_identifier<true>::operator!=<transaction_identifier<true> >(transaction_identifier<true> const&) const
Unexecuted instantiation: bool transaction_identifier<false>::operator!=<uint256>(uint256 const&) const
40
    template <typename Other>
41
150M
    bool operator<(const Other& other) const { return Compare(other) < 0; }
bool transaction_identifier<false>::operator< <transaction_identifier<false> >(transaction_identifier<false> const&) const
Line
Count
Source
41
130M
    bool operator<(const Other& other) const { return Compare(other) < 0; }
bool transaction_identifier<true>::operator< <transaction_identifier<true> >(transaction_identifier<true> const&) const
Line
Count
Source
41
20.5M
    bool operator<(const Other& other) const { return Compare(other) < 0; }
42
43
5.61M
    const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
transaction_identifier<true>::ToUint256() const
Line
Count
Source
43
2.88M
    const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
transaction_identifier<false>::ToUint256() const
Line
Count
Source
43
2.72M
    const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
44
7.88M
    static transaction_identifier FromUint256(const uint256& id) { return {id}; }
transaction_identifier<false>::FromUint256(uint256 const&)
Line
Count
Source
44
2.99M
    static transaction_identifier FromUint256(const uint256& id) { return {id}; }
transaction_identifier<true>::FromUint256(uint256 const&)
Line
Count
Source
44
4.89M
    static transaction_identifier FromUint256(const uint256& id) { return {id}; }
45
46
    /** Wrapped `uint256` methods. */
47
24.6M
    constexpr bool IsNull() const { return m_wrapped.IsNull(); }
48
0
    constexpr void SetNull() { m_wrapped.SetNull(); }
49
    static std::optional<transaction_identifier> FromHex(std::string_view hex)
50
0
    {
51
0
        auto u{uint256::FromHex(hex)};
52
0
        if (!u) return std::nullopt;
  Branch (52:13): [True: 0, False: 0]
53
0
        return FromUint256(*u);
54
0
    }
55
0
    std::string GetHex() const { return m_wrapped.GetHex(); }
Unexecuted instantiation: transaction_identifier<false>::GetHex[abi:cxx11]() const
Unexecuted instantiation: transaction_identifier<true>::GetHex[abi:cxx11]() const
56
2.70M
    std::string ToString() const { return m_wrapped.ToString(); }
transaction_identifier<false>::ToString[abi:cxx11]() const
Line
Count
Source
56
1.19M
    std::string ToString() const { return m_wrapped.ToString(); }
transaction_identifier<true>::ToString[abi:cxx11]() const
Line
Count
Source
56
1.50M
    std::string ToString() const { return m_wrapped.ToString(); }
57
0
    static constexpr auto size() { return decltype(m_wrapped)::size(); }
Unexecuted instantiation: transaction_identifier<false>::size()
Unexecuted instantiation: transaction_identifier<true>::size()
58
0
    constexpr const std::byte* data() const { return reinterpret_cast<const std::byte*>(m_wrapped.data()); }
Unexecuted instantiation: transaction_identifier<false>::data() const
Unexecuted instantiation: transaction_identifier<true>::data() const
59
131k
    constexpr const std::byte* begin() const { return reinterpret_cast<const std::byte*>(m_wrapped.begin()); }
Unexecuted instantiation: transaction_identifier<false>::begin() const
transaction_identifier<true>::begin() const
Line
Count
Source
59
131k
    constexpr const std::byte* begin() const { return reinterpret_cast<const std::byte*>(m_wrapped.begin()); }
60
16.4k
    constexpr const std::byte* end() const { return reinterpret_cast<const std::byte*>(m_wrapped.end()); }
Unexecuted instantiation: transaction_identifier<false>::end() const
transaction_identifier<true>::end() const
Line
Count
Source
60
16.4k
    constexpr const std::byte* end() const { return reinterpret_cast<const std::byte*>(m_wrapped.end()); }
61
31.1M
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<ParamsStream<SizeComputer&, TransactionSerParams> >(ParamsStream<SizeComputer&, TransactionSerParams>&) const
Line
Count
Source
61
15.5M
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<ParamsStream<VectorWriter&, TransactionSerParams> >(ParamsStream<VectorWriter&, TransactionSerParams>&) const
Line
Count
Source
61
10.2k
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams> >(ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&) const
Line
Count
Source
61
2.34M
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<ParamsStream<AutoFile&, TransactionSerParams> >(ParamsStream<AutoFile&, TransactionSerParams>&) const
Line
Count
Source
61
29.1k
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<true>::Serialize<HashWriter>(HashWriter&) const
Line
Count
Source
61
10.6k
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
Unexecuted instantiation: void transaction_identifier<false>::Serialize<ParamsStream<DataStream&, TransactionSerParams> >(ParamsStream<DataStream&, TransactionSerParams>&) const
Unexecuted instantiation: void transaction_identifier<false>::Serialize<AutoFile>(AutoFile&) const
void transaction_identifier<false>::Serialize<DataStream>(DataStream&) const
Line
Count
Source
61
7.09M
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<HashWriter>(HashWriter&) const
Line
Count
Source
61
62.7k
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
void transaction_identifier<false>::Serialize<ParamsStream<HashWriter&, TransactionSerParams> >(ParamsStream<HashWriter&, TransactionSerParams>&) const
Line
Count
Source
61
6.02M
    template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
62
3.02M
    template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
void transaction_identifier<false>::Unserialize<ParamsStream<DataStream&, TransactionSerParams> >(ParamsStream<DataStream&, TransactionSerParams>&)
Line
Count
Source
62
2.95M
    template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
void transaction_identifier<false>::Unserialize<ParamsStream<SpanReader&, TransactionSerParams> >(ParamsStream<SpanReader&, TransactionSerParams>&)
Line
Count
Source
62
66.5k
    template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
Unexecuted instantiation: void transaction_identifier<false>::Unserialize<ParamsStream<AutoFile&, TransactionSerParams> >(ParamsStream<AutoFile&, TransactionSerParams>&)
Unexecuted instantiation: void transaction_identifier<false>::Unserialize<DataStream>(DataStream&)
Unexecuted instantiation: void transaction_identifier<false>::Unserialize<ParamsStream<BufferedFile&, TransactionSerParams> >(ParamsStream<BufferedFile&, TransactionSerParams>&)
Unexecuted instantiation: void transaction_identifier<false>::Unserialize<AutoFile>(AutoFile&)
63
64
    /** Conversion function to `uint256`.
65
     *
66
     * Note: new code should use `ToUint256`.
67
     *
68
     * TODO: This should be removed once the majority of the code has switched
69
     * to using the Txid and Wtxid types. Until then it makes for a smoother
70
     * transition to allow this conversion. */
71
97.5M
    operator const uint256&() const LIFETIMEBOUND { return m_wrapped; }
transaction_identifier<false>::operator uint256 const&() const
Line
Count
Source
71
88.7M
    operator const uint256&() const LIFETIMEBOUND { return m_wrapped; }
transaction_identifier<true>::operator uint256 const&() const
Line
Count
Source
71
8.77M
    operator const uint256&() const LIFETIMEBOUND { return m_wrapped; }
72
};
73
74
/** Txid commits to all transaction fields except the witness. */
75
using Txid = transaction_identifier<false>;
76
/** Wtxid commits to all transaction fields including the witness. */
77
using Wtxid = transaction_identifier<true>;
78
79
#endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H