Branch data Line data Source code
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 : : #include <compare>
13 : : #include <concepts>
14 : : #include <tuple>
15 : : #include <variant>
16 : :
17 : : /** transaction_identifier represents the two canonical transaction identifier
18 : : * types (txid, wtxid).*/
19 : : template <bool has_witness>
20 : : class transaction_identifier
21 : : {
22 : : uint256 m_wrapped;
23 : :
24 : : // Note: Use FromUint256 externally instead.
25 : 3213362 : transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
26 : :
27 : : // TODO: Comparisons with uint256 should be disallowed once we have
28 : : // converted most of the code to using the new txid types.
29 : 5833 : constexpr int Compare(const uint256& other) const { return m_wrapped.Compare(other); }
30 : 819026740 : constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
31 : : template <typename Other>
32 : : constexpr int Compare(const Other& other) const
33 : : {
34 : : static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
35 : : return 0;
36 : : }
37 : :
38 : : public:
39 [ + - + - : 1888914 : transaction_identifier() : m_wrapped{} {}
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ][ + +
+ - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
[ + + + -
+ - ][ + +
+ - + - ]
40 : :
41 : : template <typename Other>
42 [ + + + + ]: 129992601 : bool operator==(const Other& other) const { return Compare(other) == 0; }
[ + + + +
+ + + - +
+ + + +
+ ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
[ + + + + ]
[ + - + +
+ + + - -
- # # # #
# # # # #
# # # ][ +
+ + + + +
+ - + + +
+ - - ][ +
- + + - -
- - ]
43 : : template <typename Other>
44 [ + + # # ]: 1874951 : bool operator!=(const Other& other) const { return Compare(other) != 0; }
[ + + + +
+ + ][ + +
+ - + - +
- + + +
- ][ + - +
+ + - # #
# # # # ]
[ - - + -
+ - + - -
- ]
45 : : template <typename Other>
46 [ + + + + : 469223939 : bool operator<(const Other& other) const { return Compare(other) < 0; }
- + ][ + +
+ + + + +
+ + + ][ -
+ + - + -
+ - - - -
- + + - -
- - + + -
+ + - - -
- - ][ - -
- - + + +
+ - - + +
+ + + - -
- ][ - - -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - + +
- - - - -
+ - ][ - -
- - - - +
- + - - -
- - - - -
- - - ][ -
- + + + +
+ + ][ + +
- + + + +
+ + + + -
+ - - - -
- + + + -
+ + - - -
- - - - -
- + - - -
- - + + -
- - - - ]
[ - - - -
+ + - - -
- - - - -
- - - - -
- - - +
+ ][ + + +
+ + + + +
- + + - +
- - - - -
- - - - -
- - - - -
- - - - -
- + + + +
+ + - - -
- - - - -
- - - - -
- - - -
- ][ - + +
- + - + +
+ + - - +
+ - - - -
- - - - +
- - - -
- ][ + + -
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
[ - - - +
+ + + + +
+ - + - -
- - + - -
- + + + +
- - - - -
- - - - -
+ + - - +
- - + + -
- + - - +
- ][ - - +
+ - - + -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- + + + +
+ + - - -
- - - - -
- - - - -
- - - -
- ]
47 : :
48 [ + - + - : 28086562 : const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - + - +
- + - + -
- - ][ # #
# # # # #
# ]
49 [ + - ][ + - : 1505882 : static transaction_identifier FromUint256(const uint256& id) { return {id}; }
+ - + - +
- + - +
- ][ + - +
- + - # #
# # # # ]
[ # # # #
# # ]
50 : :
51 : : /** Wrapped `uint256` methods. */
52 [ + + ]: 29407425 : constexpr bool IsNull() const { return m_wrapped.IsNull(); }
53 [ + - ][ + - : 94690 : constexpr void SetNull() { m_wrapped.SetNull(); }
+ - + - +
- ]
54 : 5073 : static std::optional<transaction_identifier> FromHex(std::string_view hex)
55 : : {
56 [ + + ]: 5073 : auto u{uint256::FromHex(hex)};
57 [ + + ]: 5073 : if (!u) return std::nullopt;
58 : 4901 : return FromUint256(*u);
59 : : }
60 [ + - + - : 239705 : std::string GetHex() const { return m_wrapped.GetHex(); }
+ - + - +
- + - ][ +
- + - + -
# # # # #
# ][ + - +
- + - # #
# # ][ + -
+ - + - +
- ][ + - #
# # # # #
# # ][ + -
- - + - +
- + - +
- ]
61 [ + - + - ]: 2319856 : std::string ToString() const { return m_wrapped.ToString(); }
[ + - + -
+ - + - +
- - - ][ -
- + - - -
+ - + - -
- + - + -
+ - + - +
- + - +
- ][ # # #
# # # # #
# # ][ + -
+ - + - +
- + - + -
+ - + - -
- + - + -
+ - + - -
- - - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- + - + -
+ - + - +
- + - + -
+ - ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
[ + - + -
+ - + - +
- - - + -
- - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- # # # #
# # # # #
# ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - +
- ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - - - -
- - - - -
+ - + - +
- + - + -
- - - - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - - - -
- - - - -
+ - + - +
- + - ][ #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
62 : : static constexpr auto size() { return decltype(m_wrapped)::size(); }
63 [ + - + - : 6 : constexpr const std::byte* data() const { return reinterpret_cast<const std::byte*>(m_wrapped.data()); }
+ - + - +
- + - ]
64 [ + - ]: 262567 : constexpr const std::byte* begin() const { return reinterpret_cast<const std::byte*>(m_wrapped.begin()); }
65 : 318 : constexpr const std::byte* end() const { return reinterpret_cast<const std::byte*>(m_wrapped.end()); }
66 : 32886636 : template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
67 : 701417 : template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
68 : :
69 : : /** Conversion function to `uint256`.
70 : : *
71 : : * Note: new code should use `ToUint256`.
72 : : *
73 : : * TODO: This should be removed once the majority of the code has switched
74 : : * to using the Txid and Wtxid types. Until then it makes for a smoother
75 : : * transition to allow this conversion. */
76 [ + - + - ]: 340342644 : operator const uint256&() const LIFETIMEBOUND { return m_wrapped; }
[ + - + -
+ - + - +
- + - + -
+ - + - +
- ][ + - +
- + - + -
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ + - +
- + - + -
+ - + - +
- + - + -
- - ][ + -
+ - + - +
- - - ][ +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ][ + +
+ - + - +
- ][ - - -
- - - - -
+ - + - ]
77 : : };
78 : :
79 : : /** Txid commits to all transaction fields except the witness. */
80 : : using Txid = transaction_identifier<false>;
81 : : /** Wtxid commits to all transaction fields including the witness. */
82 : : using Wtxid = transaction_identifier<true>;
83 : :
84 : : template <typename T>
85 : : concept TxidOrWtxid = std::is_same_v<T, Txid> || std::is_same_v<T, Wtxid>;
86 : :
87 : : class GenTxid : public std::variant<Txid, Wtxid>
88 : : {
89 : : public:
90 [ + - + - ]: 307161 : using variant::variant;
[ + - + -
+ - + - ]
91 : :
92 [ + + + + : 73639 : bool IsWtxid() const { return std::holds_alternative<Wtxid>(*this); }
+ + ][ + + ]
93 : :
94 [ + + - + : 1045143 : const uint256& ToUint256() const LIFETIMEBOUND
+ - + + -
+ + - ][ +
+ - + + -
+ + - + +
- ]
95 : : {
96 [ + + - + : 13237886 : return std::visit([](const auto& id) -> const uint256& { return id.ToUint256(); }, *this);
+ + + + +
+ - + - +
+ + + - -
+ - + - +
+ + - + ]
[ - - - -
- + + - +
+ + + - +
+ + + - +
+ - + + +
+ - + + -
+ + + + -
+ + - + +
+ + - + -
+ + - + +
- + + + +
- + + + +
- + + - -
- - - + +
- + + - +
+ + + - +
+ + + - +
+ - + + +
+ - + + -
+ + + + -
+ + - + +
+ + - + +
- + - + +
- + + - +
+ - - - -
- + + - +
+ - ][ + +
- + + + +
- + + + +
- + + + +
- + + - +
+ + + - +
+ - + + +
+ - + + -
+ + + + -
+ - + + -
+ + - + +
+ + - + +
+ + - + +
+ + - + -
+ + - + +
- - + + +
- + + + +
- + + - +
+ + + - +
+ - + + +
+ - + + -
+ + + + -
+ + - + +
+ + - + +
- + + + +
- + - + +
- + + - ]
[ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
97 : : }
98 : :
99 : 749749 : friend auto operator<=>(const GenTxid& a, const GenTxid& b)
100 : : {
101 : : // Use a reference for read-only access to the hash, avoiding a copy that might not be optimized away.
102 [ + + - + : 1499498 : return std::tuple<bool, const uint256&>(a.IsWtxid(), a.ToUint256()) <=> std::tuple<bool, const uint256&>(b.IsWtxid(), b.ToUint256());
+ - ]
103 : : }
104 : : };
105 : :
106 : : #endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
|