Use mempool/txgraph to determine if a tx has descendants
What changed, and why it matters
This is a routine internal code cleanup in Bitcoin Core. It replaces one way of checking whether a transaction in the memory pool has dependent ('descendant') transactions with another, newer mechanism. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Treat as normal maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit removes a call to CTxMemPoolEntry::GetCountWithDescendants() from the node interface’s hasDescendantsInMempool() and adds a new CTxMemPool::HasDescendants() helper that uses the newer TxGraph::GetDescendants() API. The behavior remains the same: it returns true if the transaction exists in the mempool and has more than itself in its descendant set. This is preparatory refactoring for removing the older cached descendant-count state from the mempool.
Changed components
src/node/interfaces.cppsrc/txmempool.cppsrc/txmempool.hInspect captured patch +11 / −4
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 8e38ae12..c3e57291 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -665,10 +665,7 @@ public:
bool hasDescendantsInMempool(const Txid& txid) override
{
if (!m_node.mempool) return false;
- LOCK(m_node.mempool->cs);
- const auto entry{m_node.mempool->GetEntry(txid)};
- if (entry == nullptr) return false;
- return entry->GetCountWithDescendants() > 1;
+ return m_node.mempool->HasDescendants(txid);
}
bool broadcastTransaction(const CTransactionRef& tx,
const CAmount& max_tx_fee,
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 7fd5a470..f7bdbf94 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -229,6 +229,14 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
return {};
}
+bool CTxMemPool::HasDescendants(const Txid& txid) const
+{
+ LOCK(cs);
+ auto entry = GetEntry(txid);
+ if (!entry) return false;
+ return m_txgraph->GetDescendants(*entry, TxGraph::Level::MAIN).size() > 1;
+}
+
util::Result<CTxMemPool::setEntries> CTxMemPool::CalculateMemPoolAncestors(
const CTxMemPoolEntry &entry,
const Limits& limits,
diff --git a/src/txmempool.h b/src/txmempool.h
index 475a3996..b65333cc 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -467,6 +467,8 @@ public:
const Limits& limits,
bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+ bool HasDescendants(const Txid& txid) const;
+
/** Collect the entire cluster of connected transactions for each transaction in txids.
* All txids must correspond to transaction entries in the mempool, otherwise this returns an
* empty vector. This call will also exit early and return an empty vector if it collects 500 or
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.