From 11d28f21bb8f0c3094934b3fef45871f73bb216a Mon Sep 17 00:00:00 2001 From: marcofleon Date: Mon, 31 Mar 2025 12:37:38 +0100 Subject: [PATCH] Implement GenTxid as a variant Reimplements the GenTxid class as a variant for better type safety. Also adds two temporary functions to the old GenTxid class that convert to and from the new variant. --- src/primitives/transaction.h | 14 ++++++++++++++ src/util/transaction_identifier.h | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index bf86562886a..adadb2a3e74 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -437,6 +437,20 @@ public: const uint256& GetHash() const LIFETIMEBOUND { return m_hash; } friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; } friend bool operator<(const GenTxid& a, const GenTxid& b) { return std::tie(a.m_is_wtxid, a.m_hash) < std::tie(b.m_is_wtxid, b.m_hash); } + + GenTxidVariant ToVariant() const + { + return m_is_wtxid ? + GenTxidVariant{Wtxid::FromUint256(m_hash)} : + GenTxidVariant{Txid::FromUint256(m_hash)}; + } + + static GenTxid FromVariant(const GenTxidVariant& variant) + { + return GenTxid{ + std::holds_alternative<::Wtxid>(variant), + variant.ToUint256()}; + } }; #endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/util/transaction_identifier.h b/src/util/transaction_identifier.h index c86c8930158..22ef43ea510 100644 --- a/src/util/transaction_identifier.h +++ b/src/util/transaction_identifier.h @@ -9,6 +9,10 @@ #include #include +#include +#include +#include + /** transaction_identifier represents the two canonical transaction identifier * types (txid, wtxid).*/ template @@ -76,4 +80,22 @@ using Txid = transaction_identifier; /** Wtxid commits to all transaction fields including the witness. */ using Wtxid = transaction_identifier; +class GenTxidVariant : public std::variant +{ +public: + using variant::variant; + + bool IsWtxid() const { return std::holds_alternative(*this); } + + const uint256& ToUint256() const LIFETIMEBOUND + { + return std::visit([](const auto& id) -> const uint256& { return id.ToUint256(); }, *this); + } + + friend auto operator<=>(const GenTxidVariant& a, const GenTxidVariant& b) + { + return std::tuple(a.IsWtxid(), a.ToUint256()) <=> std::tuple(b.IsWtxid(), b.ToUint256()); + } +}; + #endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H