Given that has_witness
is only used for templating, what do you think about this approach? I think it’s a bit more straightforward, and as a probably not-very-useful benefit, it also allows for adding more txid types when necessary.
0diff --git a/src/util/transaction_identifier.h b/src/util/transaction_identifier.h
1index b5c0f25093..a845c5c0f9 100644
2--- a/src/util/transaction_identifier.h
3+++ b/src/util/transaction_identifier.h
4@@ -14,7 +14,7 @@
5 * transaction_identifier to uint256 (e.g. by making the base class private).
6 * This should be easy to do once most of the code base has converted to the
7 * Txid and Wtxid types to avoid churn. */
8-template <bool has_witness>
9+template <typename Derived>
10 class transaction_identifier : public uint256
11 {
12 public:
13@@ -24,8 +24,7 @@ public:
14 transaction_identifier(const Other& other)
15 : uint256{other}
16 {
17- static_assert(std::is_same_v<Other, transaction_identifier<has_witness>>,
18- "Forbidden copy type");
19+ static_assert(std::is_same_v<Other, Derived>, "Forbidden copy type");
20 }
21
22 // Allow comparison with the same transaction_identifier type
23@@ -39,7 +38,7 @@ public:
24 constexpr int Compare(const Other& other) const
25 {
26 if constexpr (std::is_same_v<Other, uint256> || // TODO forbid uint256 comparisons
27- std::is_same_v<Other, transaction_identifier<has_witness>>) {
28+ std::is_same_v<Other, Derived>) {
29 return reinterpret_cast<const uint256&>(*this).Compare(other);
30 } else {
31 static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
32@@ -49,12 +48,12 @@ public:
33 uint256 Uint256() const { return reinterpret_cast<const uint256&>(*this); }
34
35 template <typename Other>
36- static transaction_identifier FromUint256(const Other& other)
37+ static Derived FromUint256(const Other& other)
38 {
39 // TODO this does not need to be a template function after we disallow
40- // `uint256 a = transaction_identifier<has_witness>{};`
41+ // `uint256 a = Derived{};`
42 if constexpr (std::is_same_v<Other, uint256>) {
43- return reinterpret_cast<const transaction_identifier&>(other);
44+ return reinterpret_cast<const Derived&>(other);
45 } else {
46 static_assert(ALWAYS_FALSE<Other>, "FromUint256 only allows uint256");
47 }
48@@ -62,8 +61,8 @@ public:
49 };
50
51 /** Txid commits to all transaction fields except the witness. */
52-using Txid = transaction_identifier<false>;
53+class Txid : public transaction_identifier<Txid> {};
54 /** Wtxid commits to all transaction fields including the witness. */
55-using Wtxid = transaction_identifier<true>;
56+class Wtxid : public transaction_identifier<Wtxid> {};
57
58 #endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H