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.
<details>
<summary>git diff on c4c7b6ea9fe2e7ba89a994127073c54af30d6f88</summary>
diff --git a/src/util/transaction_identifier.h b/src/util/transaction_identifier.h
index b5c0f25093..a845c5c0f9 100644
--- a/src/util/transaction_identifier.h
+++ b/src/util/transaction_identifier.h
@@ -14,7 +14,7 @@
* transaction_identifier to uint256 (e.g. by making the base class private).
* This should be easy to do once most of the code base has converted to the
* Txid and Wtxid types to avoid churn. */
-template <bool has_witness>
+template <typename Derived>
class transaction_identifier : public uint256
{
public:
@@ -24,8 +24,7 @@ public:
transaction_identifier(const Other& other)
: uint256{other}
{
- static_assert(std::is_same_v<Other, transaction_identifier<has_witness>>,
- "Forbidden copy type");
+ static_assert(std::is_same_v<Other, Derived>, "Forbidden copy type");
}
// Allow comparison with the same transaction_identifier type
@@ -39,7 +38,7 @@ public:
constexpr int Compare(const Other& other) const
{
if constexpr (std::is_same_v<Other, uint256> || // TODO forbid uint256 comparisons
- std::is_same_v<Other, transaction_identifier<has_witness>>) {
+ std::is_same_v<Other, Derived>) {
return reinterpret_cast<const uint256&>(*this).Compare(other);
} else {
static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
@@ -49,12 +48,12 @@ public:
uint256 Uint256() const { return reinterpret_cast<const uint256&>(*this); }
template <typename Other>
- static transaction_identifier FromUint256(const Other& other)
+ static Derived FromUint256(const Other& other)
{
// TODO this does not need to be a template function after we disallow
- // `uint256 a = transaction_identifier<has_witness>{};`
+ // `uint256 a = Derived{};`
if constexpr (std::is_same_v<Other, uint256>) {
- return reinterpret_cast<const transaction_identifier&>(other);
+ return reinterpret_cast<const Derived&>(other);
} else {
static_assert(ALWAYS_FALSE<Other>, "FromUint256 only allows uint256");
}
@@ -62,8 +61,8 @@ public:
};
/** Txid commits to all transaction fields except the witness. */
-using Txid = transaction_identifier<false>;
+class Txid : public transaction_identifier<Txid> {};
/** Wtxid commits to all transaction fields including the witness. */
-using Wtxid = transaction_identifier<true>;
+class Wtxid : public transaction_identifier<Wtxid> {};
#endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
</details>