refactor: Move `transaction_identifier.h` to primitives
What changed, and why it matters
This commit is a pure code reorganization: it moves a header file that defines transaction ID types (Txid, Wtxid) from one directory to another and updates all the places that include it. There are no functional changes to how Bitcoin Core behaves, and no security issue is present.
No security action needed. Treat as ordinary refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates transaction_identifier.h from src/util/ to src/primitives/ and updates include directives across 20 files. The file content is identical except for the include guard name (BITCOIN_PRIMITIVES_TRANSACTION_IDENTIFIER_H vs BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H). No logic, data structures, serialization, or behavior is modified.
Changed components
src/primitives/transaction_identifier.hinclude path updates in index, interfaces, merkleblock, primitives, qt, test, txmempool, wallet modulesInspect captured patch +113 / −113
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index 2a7c0066..11dd856e 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -9,7 +9,7 @@
#include <index/disktxpos.h>
#include <logging.h>
#include <node/blockstorage.h>
-#include <util/transaction_identifier.h>
+#include <primitives/transaction_identifier.h>
#include <validation.h>
constexpr uint8_t DB_TXINDEX{'t'};
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 94869aff..412cbb61 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -9,12 +9,12 @@
#include <common/signmessage.h>
#include <consensus/amount.h>
#include <interfaces/chain.h>
+#include <primitives/transaction_identifier.h>
#include <pubkey.h>
#include <script/script.h>
#include <support/allocators/secure.h>
#include <util/fs.h>
#include <util/result.h>
-#include <util/transaction_identifier.h>
#include <util/ui_change_type.h>
#include <cstdint>
diff --git a/src/merkleblock.h b/src/merkleblock.h
index 8f1d45a3..a7b37d3b 100644
--- a/src/merkleblock.h
+++ b/src/merkleblock.h
@@ -8,9 +8,9 @@
#include <common/bloom.h>
#include <primitives/block.h>
+#include <primitives/transaction_identifier.h>
#include <serialize.h>
#include <uint256.h>
-#include <util/transaction_identifier.h>
#include <set>
#include <vector>
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index fab5c407..e80ab60f 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -8,11 +8,11 @@
#include <consensus/amount.h>
#include <crypto/hex_base.h>
#include <hash.h>
+#include <primitives/transaction_identifier.h>
#include <script/script.h>
#include <serialize.h>
#include <tinyformat.h>
#include <uint256.h>
-#include <util/transaction_identifier.h>
#include <algorithm>
#include <cassert>
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index c5d27591..295bce61 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -8,10 +8,10 @@
#include <attributes.h>
#include <consensus/amount.h>
+#include <primitives/transaction_identifier.h> // IWYU pragma: export
#include <script/script.h>
#include <serialize.h>
#include <uint256.h>
-#include <util/transaction_identifier.h> // IWYU pragma: export
#include <cstddef>
#include <cstdint>
diff --git a/src/primitives/transaction_identifier.h b/src/primitives/transaction_identifier.h
new file mode 100644
index 00000000..b753c1df
--- /dev/null
+++ b/src/primitives/transaction_identifier.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2023-present The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://opensource.org/license/mit.
+
+#ifndef BITCOIN_PRIMITIVES_TRANSACTION_IDENTIFIER_H
+#define BITCOIN_PRIMITIVES_TRANSACTION_IDENTIFIER_H
+
+#include <attributes.h>
+#include <uint256.h>
+#include <util/types.h>
+
+#include <compare>
+#include <concepts>
+#include <tuple>
+#include <variant>
+
+/** transaction_identifier represents the two canonical transaction identifier
+ * types (txid, wtxid).*/
+template <bool has_witness>
+class transaction_identifier
+{
+ uint256 m_wrapped;
+
+ // Note: Use FromUint256 externally instead.
+ transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
+
+ constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
+ template <typename Other>
+ constexpr int Compare(const Other& other) const
+ {
+ static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
+ return 0;
+ }
+
+public:
+ transaction_identifier() : m_wrapped{} {}
+
+ template <typename Other>
+ bool operator==(const Other& other) const { return Compare(other) == 0; }
+ template <typename Other>
+ bool operator!=(const Other& other) const { return Compare(other) != 0; }
+ template <typename Other>
+ bool operator<(const Other& other) const { return Compare(other) < 0; }
+
+ const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
+ static transaction_identifier FromUint256(const uint256& id) { return {id}; }
+
+ /** Wrapped `uint256` methods. */
+ constexpr bool IsNull() const { return m_wrapped.IsNull(); }
+ constexpr void SetNull() { m_wrapped.SetNull(); }
+ static std::optional<transaction_identifier> FromHex(std::string_view hex)
+ {
+ auto u{uint256::FromHex(hex)};
+ if (!u) return std::nullopt;
+ return FromUint256(*u);
+ }
+ std::string GetHex() const { return m_wrapped.GetHex(); }
+ std::string ToString() const { return m_wrapped.ToString(); }
+ static constexpr auto size() { return decltype(m_wrapped)::size(); }
+ constexpr const std::byte* data() const { return reinterpret_cast<const std::byte*>(m_wrapped.data()); }
+ constexpr const std::byte* begin() const { return reinterpret_cast<const std::byte*>(m_wrapped.begin()); }
+ constexpr const std::byte* end() const { return reinterpret_cast<const std::byte*>(m_wrapped.end()); }
+ template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
+ template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
+};
+
+/** Txid commits to all transaction fields except the witness. */
+using Txid = transaction_identifier<false>;
+/** Wtxid commits to all transaction fields including the witness. */
+using Wtxid = transaction_identifier<true>;
+
+template <typename T>
+concept TxidOrWtxid = std::is_same_v<T, Txid> || std::is_same_v<T, Wtxid>;
+
+class GenTxid : public std::variant<Txid, Wtxid>
+{
+public:
+ using variant::variant;
+
+ bool IsWtxid() const { return std::holds_alternative<Wtxid>(*this); }
+
+ const uint256& ToUint256() const LIFETIMEBOUND
+ {
+ return std::visit([](const auto& id) -> const uint256& { return id.ToUint256(); }, *this);
+ }
+
+ friend auto operator<=>(const GenTxid& a, const GenTxid& b)
+ {
+ // Use a reference for read-only access to the hash, avoiding a copy that might not be optimized away.
+ return std::tuple<bool, const uint256&>(a.IsWtxid(), a.ToUint256()) <=> std::tuple<bool, const uint256&>(b.IsWtxid(), b.ToUint256());
+ }
+};
+
+#endif // BITCOIN_PRIMITIVES_TRANSACTION_IDENTIFIER_H
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index adb8e7fc..4d5adc4f 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -5,9 +5,9 @@
#ifndef BITCOIN_QT_SENDCOINSDIALOG_H
#define BITCOIN_QT_SENDCOINSDIALOG_H
+#include <primitives/transaction_identifier.h>
#include <qt/clientmodel.h>
#include <qt/walletmodel.h>
-#include <util/transaction_identifier.h>
#include <QDialog>
#include <QMessageBox>
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index fc28fc3e..2c5d834b 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -6,8 +6,8 @@
#define BITCOIN_QT_TRANSACTIONRECORD_H
#include <consensus/amount.h>
+#include <primitives/transaction_identifier.h>
#include <uint256.h>
-#include <util/transaction_identifier.h>
#include <QList>
#include <QString>
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index bff1b198..d661d9b6 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -7,8 +7,8 @@
#include <qt/guiutil.h>
+#include <primitives/transaction_identifier.h>
#include <uint256.h>
-#include <util/transaction_identifier.h>
#include <QWidget>
#include <QKeyEvent>
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index bcdd6dbd..ece797bf 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -10,8 +10,8 @@
#include <qt/walletmodeltransaction.h>
#include <interfaces/wallet.h>
+#include <primitives/transaction_identifier.h>
#include <support/allocators/secure.h>
-#include <util/transaction_identifier.h>
#include <vector>
diff --git a/src/test/fuzz/hex.cpp b/src/test/fuzz/hex.cpp
index 64c75304..e2d08ac2 100644
--- a/src/test/fuzz/hex.cpp
+++ b/src/test/fuzz/hex.cpp
@@ -4,13 +4,13 @@
#include <core_io.h>
#include <primitives/block.h>
+#include <primitives/transaction_identifier.h>
#include <pubkey.h>
#include <rpc/util.h>
#include <test/fuzz/fuzz.h>
#include <uint256.h>
#include <univalue.h>
#include <util/strencodings.h>
-#include <util/transaction_identifier.h>
#include <algorithm>
#include <cassert>
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 5f03641e..cd178d26 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -16,6 +16,7 @@
#include <key.h>
#include <policy/policy.h>
#include <policy/settings.h>
+#include <primitives/transaction_identifier.h>
#include <script/script.h>
#include <script/script_error.h>
#include <script/sigcache.h>
@@ -29,7 +30,6 @@
#include <test/util/transaction_utils.h>
#include <util/strencodings.h>
#include <util/string.h>
-#include <util/transaction_identifier.h>
#include <validation.h>
#include <functional>
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index de75c5c7..80e10104 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <primitives/transaction_identifier.h>
#include <streams.h>
#include <test/util/setup_common.h>
#include <uint256.h>
#include <util/strencodings.h>
-#include <util/transaction_identifier.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/txmempool.h b/src/txmempool.h
index 5c81876a..f471726c 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -17,12 +17,12 @@
#include <policy/feerate.h>
#include <policy/packages.h>
#include <primitives/transaction.h>
+#include <primitives/transaction_identifier.h>
#include <sync.h>
#include <util/epochguard.h>
#include <util/feefrac.h>
#include <util/hasher.h>
#include <util/result.h>
-#include <util/transaction_identifier.h>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
diff --git a/src/util/transaction_identifier.h b/src/util/transaction_identifier.h
deleted file mode 100644
index b59f2e77..00000000
--- a/src/util/transaction_identifier.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2023-present The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or https://opensource.org/license/mit.
-
-#ifndef BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
-#define BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
-
-#include <attributes.h>
-#include <uint256.h>
-#include <util/types.h>
-
-#include <compare>
-#include <concepts>
-#include <tuple>
-#include <variant>
-
-/** transaction_identifier represents the two canonical transaction identifier
- * types (txid, wtxid).*/
-template <bool has_witness>
-class transaction_identifier
-{
- uint256 m_wrapped;
-
- // Note: Use FromUint256 externally instead.
- transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {}
-
- constexpr int Compare(const transaction_identifier<has_witness>& other) const { return m_wrapped.Compare(other.m_wrapped); }
- template <typename Other>
- constexpr int Compare(const Other& other) const
- {
- static_assert(ALWAYS_FALSE<Other>, "Forbidden comparison type");
- return 0;
- }
-
-public:
- transaction_identifier() : m_wrapped{} {}
-
- template <typename Other>
- bool operator==(const Other& other) const { return Compare(other) == 0; }
- template <typename Other>
- bool operator!=(const Other& other) const { return Compare(other) != 0; }
- template <typename Other>
- bool operator<(const Other& other) const { return Compare(other) < 0; }
-
- const uint256& ToUint256() const LIFETIMEBOUND { return m_wrapped; }
- static transaction_identifier FromUint256(const uint256& id) { return {id}; }
-
- /** Wrapped `uint256` methods. */
- constexpr bool IsNull() const { return m_wrapped.IsNull(); }
- constexpr void SetNull() { m_wrapped.SetNull(); }
- static std::optional<transaction_identifier> FromHex(std::string_view hex)
- {
- auto u{uint256::FromHex(hex)};
- if (!u) return std::nullopt;
- return FromUint256(*u);
- }
- std::string GetHex() const { return m_wrapped.GetHex(); }
- std::string ToString() const { return m_wrapped.ToString(); }
- static constexpr auto size() { return decltype(m_wrapped)::size(); }
- constexpr const std::byte* data() const { return reinterpret_cast<const std::byte*>(m_wrapped.data()); }
- constexpr const std::byte* begin() const { return reinterpret_cast<const std::byte*>(m_wrapped.begin()); }
- constexpr const std::byte* end() const { return reinterpret_cast<const std::byte*>(m_wrapped.end()); }
- template <typename Stream> void Serialize(Stream& s) const { m_wrapped.Serialize(s); }
- template <typename Stream> void Unserialize(Stream& s) { m_wrapped.Unserialize(s); }
-};
-
-/** Txid commits to all transaction fields except the witness. */
-using Txid = transaction_identifier<false>;
-/** Wtxid commits to all transaction fields including the witness. */
-using Wtxid = transaction_identifier<true>;
-
-template <typename T>
-concept TxidOrWtxid = std::is_same_v<T, Txid> || std::is_same_v<T, Wtxid>;
-
-class GenTxid : public std::variant<Txid, Wtxid>
-{
-public:
- using variant::variant;
-
- bool IsWtxid() const { return std::holds_alternative<Wtxid>(*this); }
-
- const uint256& ToUint256() const LIFETIMEBOUND
- {
- return std::visit([](const auto& id) -> const uint256& { return id.ToUint256(); }, *this);
- }
-
- friend auto operator<=>(const GenTxid& a, const GenTxid& b)
- {
- // Use a reference for read-only access to the hash, avoiding a copy that might not be optimized away.
- return std::tuple<bool, const uint256&>(a.IsWtxid(), a.ToUint256()) <=> std::tuple<bool, const uint256&>(b.IsWtxid(), b.ToUint256());
- }
-};
-
-#endif // BITCOIN_UTIL_TRANSACTION_IDENTIFIER_H
diff --git a/src/wallet/receive.h b/src/wallet/receive.h
index b995e21c..f129c195 100644
--- a/src/wallet/receive.h
+++ b/src/wallet/receive.h
@@ -6,7 +6,7 @@
#define BITCOIN_WALLET_RECEIVE_H
#include <consensus/amount.h>
-#include <util/transaction_identifier.h>
+#include <primitives/transaction_identifier.h>
#include <wallet/transaction.h>
#include <wallet/types.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp
index 69c5e011..b58d3dad 100644
--- a/src/wallet/rpc/transactions.cpp
+++ b/src/wallet/rpc/transactions.cpp
@@ -5,9 +5,9 @@
#include <core_io.h>
#include <key_io.h>
#include <policy/rbf.h>
+#include <primitives/transaction_identifier.h>
#include <rpc/util.h>
#include <rpc/blockchain.h>
-#include <util/transaction_identifier.h>
#include <util/vector.h>
#include <wallet/receive.h>
#include <wallet/rpc/util.h>
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 4ae34d0b..8ff89600 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -13,6 +13,7 @@
#include <numeric>
#include <policy/policy.h>
#include <primitives/transaction.h>
+#include <primitives/transaction_identifier.h>
#include <script/script.h>
#include <script/signingprovider.h>
#include <script/solver.h>
@@ -21,7 +22,6 @@
#include <util/rbf.h>
#include <util/trace.h>
#include <util/translation.h>
-#include <util/transaction_identifier.h>
#include <wallet/coincontrol.h>
#include <wallet/fees.h>
#include <wallet/receive.h>
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 95ed7af8..f39df174 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -15,6 +15,7 @@
#include <outputtype.h>
#include <policy/feerate.h>
#include <primitives/transaction.h>
+#include <primitives/transaction_identifier.h>
#include <script/interpreter.h>
#include <script/script.h>
#include <support/allocators/secure.h>
@@ -26,7 +27,6 @@
#include <util/result.h>
#include <util/string.h>
#include <util/time.h>
-#include <util/transaction_identifier.h>
#include <util/ui_change_type.h>
#include <wallet/crypter.h>
#include <wallet/db.h>
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 2c0073f3..773f65ca 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -9,6 +9,7 @@
#include <common/system.h>
#include <key_io.h>
+#include <primitives/transaction_identifier.h>
#include <protocol.h>
#include <script/script.h>
#include <serialize.h>
@@ -16,7 +17,6 @@
#include <util/bip32.h>
#include <util/check.h>
#include <util/fs.h>
-#include <util/transaction_identifier.h>
#include <util/time.h>
#include <util/translation.h>
#include <wallet/migrate.h>
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 5327a2cf..771d3a37 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -7,8 +7,8 @@
#define BITCOIN_WALLET_WALLETDB_H
#include <key.h>
+#include <primitives/transaction_identifier.h>
#include <script/sign.h>
-#include <util/transaction_identifier.h>
#include <wallet/db.h>
#include <wallet/walletutil.h>
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.