What changed, and why it matters
This commit adds a new way to look up transactions in Bitcoin Core's memory pool (mempool) using the transaction's witness hash (wtxid), in addition to the existing lookup by regular transaction hash (txid). It also adds a unit test to verify both lookup methods work. There is no indication this change fixes a security vulnerability; it appears to be a normal feature or code-quality improvement.
No security action required. Review as a routine code change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a second overload of CTxMemPool::get() that accepts a Wtxid instead of a Txid, querying the existing index_by_wtxid index in mapTx. It adds Doxygen comments for both overloads and a BOOST_AUTO_TEST_CASE (MempoolLookupTest) that constructs a simple transaction, confirms it is absent before insertion, adds it to the mempool, and then verifies retrieval by both txid and wtxid. No existing behavior is removed or altered, and no security-sensitive logic is changed.
Changed components
src/txmempool.hsrc/txmempool.cppsrc/test/mempool_tests.cppInspect captured patch +49 / −0
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 77024c3e..ba484f9b 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -24,6 +24,32 @@ public:
using CTxMemPool::GetMinFee;
};
+BOOST_AUTO_TEST_CASE(MempoolLookupTest)
+{
+ auto& pool = static_cast<MemPoolTest&>(*Assert(m_node.mempool));
+ LOCK2(cs_main, pool.cs);
+ TestMemPoolEntryHelper entry;
+
+ CMutableTransaction tx = CMutableTransaction();
+ tx.vin.resize(1);
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vout.resize(1);
+ tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
+ tx.vout[0].nValue = 10 * COIN;
+
+ // Not in the mempool, so can't find it by txid or wtxid
+ BOOST_CHECK(!pool.get(tx.GetHash()));
+ BOOST_CHECK(!pool.get(CTransaction(tx).GetWitnessHash()));
+
+ TryAddToMempool(pool, entry.Fee(1000LL).FromTx(tx));
+
+ // Lookup by Txid
+ BOOST_CHECK(pool.get(tx.GetHash()));
+
+ // Lookup by Wtxid
+ BOOST_CHECK(pool.get(CTransaction(tx).GetWitnessHash()));
+}
+
BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
{
// Test CTxMemPool::remove functionality
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index a22cd2b1..86cbc1ad 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -627,6 +627,15 @@ CTransactionRef CTxMemPool::get(const Txid& hash) const
return i->GetSharedTx();
}
+CTransactionRef CTxMemPool::get(const Wtxid& hash) const
+{
+ LOCK(cs);
+ const auto& wtxid_map{mapTx.get<index_by_wtxid>()};
+ const auto it{wtxid_map.find(hash)};
+ if (it == wtxid_map.end()) return nullptr;
+ return it->GetSharedTx();
+}
+
void CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta)
{
{
diff --git a/src/txmempool.h b/src/txmempool.h
index ae59057c..1a5405d5 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -512,8 +512,22 @@ public:
const CTxMemPoolEntry* GetEntry(const Txid& txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs);
+ /**
+ * Return a mempool transaction with a given hash.
+ *
+ * @param[in] hash the txid
+ * @returns the tx if found, otherwise nullptr
+ */
CTransactionRef get(const Txid& hash) const;
+ /**
+ * Return a mempool transaction with a given witness hash.
+ *
+ * @param[in] hash the wtxid
+ * @returns the tx if found, otherwise nullptr
+ */
+ CTransactionRef get(const Wtxid& hash) const;
+
template <TxidOrWtxid T>
TxMempoolInfo info(const T& id) const
{
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.