Make CTxMemPoolEntry derive from TxGraph::Ref
What changed, and why it matters
This is a routine internal code refactoring in Bitcoin Core. It changes how memory-pool transaction entries are constructed so they inherit from a new transaction-graph reference type. There is no user-visible behavior change, no bug fix, and no security-relevant change evident in the commit.
No security action needed. Treat as normal codebase maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit makes CTxMemPoolEntry derive from TxGraph::Ref and updates all constructors to accept a TxGraph::Ref&& argument. It also adds txgraph.cpp to the kernel CMake build. All call sites pass a default-constructed TxGraph::Ref(). This is purely structural plumbing for an in-progress mempool graph abstraction; no logic, validation, or network behavior is altered.
Changed components
src/kernel/mempool_entry.hsrc/txmempool.cppsrc/kernel/CMakeLists.txtbenchmark and test helpersInspect captured patch +16 / −12
diff --git a/src/bench/blockencodings.cpp b/src/bench/blockencodings.cpp
index 8f665991..c92ade60 100644
--- a/src/bench/blockencodings.cpp
+++ b/src/bench/blockencodings.cpp
@@ -22,7 +22,7 @@
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
LockPoints lp;
- AddToMempool(pool, CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
+ AddToMempool(pool, CTxMemPoolEntry(TxGraph::Ref(), tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
}
namespace {
diff --git a/src/bench/mempool_ephemeral_spends.cpp b/src/bench/mempool_ephemeral_spends.cpp
index 8f294113..ce17650e 100644
--- a/src/bench/mempool_ephemeral_spends.cpp
+++ b/src/bench/mempool_ephemeral_spends.cpp
@@ -29,7 +29,7 @@ static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_R
unsigned int sigOpCost{4};
uint64_t fee{0};
LockPoints lp;
- AddToMempool(pool, CTxMemPoolEntry(
+ AddToMempool(pool, CTxMemPoolEntry(TxGraph::Ref(),
tx, fee, nTime, nHeight, sequence,
spendsCoinbase, sigOpCost, lp));
}
diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp
index aa2e8682..72d2356a 100644
--- a/src/bench/mempool_eviction.cpp
+++ b/src/bench/mempool_eviction.cpp
@@ -27,7 +27,7 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
bool spendsCoinbase = false;
unsigned int sigOpCost = 4;
LockPoints lp;
- AddToMempool(pool, CTxMemPoolEntry(
+ AddToMempool(pool, CTxMemPoolEntry(TxGraph::Ref(),
tx, nFee, nTime, nHeight, sequence,
spendsCoinbase, sigOpCost, lp));
}
diff --git a/src/bench/mempool_stress.cpp b/src/bench/mempool_stress.cpp
index fbac25db..5095438c 100644
--- a/src/bench/mempool_stress.cpp
+++ b/src/bench/mempool_stress.cpp
@@ -29,7 +29,7 @@ static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_R
bool spendsCoinbase = false;
unsigned int sigOpCost = 4;
LockPoints lp;
- AddToMempool(pool, CTxMemPoolEntry(tx, 1000, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp));
+ AddToMempool(pool, CTxMemPoolEntry(TxGraph::Ref(), tx, 1000, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp));
}
struct Available {
diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp
index a61c6609..4ad1f0b2 100644
--- a/src/bench/rpc_mempool.cpp
+++ b/src/bench/rpc_mempool.cpp
@@ -22,7 +22,7 @@
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
LockPoints lp;
- AddToMempool(pool, CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
+ AddToMempool(pool, CTxMemPoolEntry(TxGraph::Ref(), tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
}
static void RpcMempool(benchmark::Bench& bench)
diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt
index c45ce781..9ab2d672 100644
--- a/src/kernel/CMakeLists.txt
+++ b/src/kernel/CMakeLists.txt
@@ -58,6 +58,7 @@ add_library(bitcoinkernel
../support/lockedpool.cpp
../sync.cpp
../txdb.cpp
+ ../txgraph.cpp
../txmempool.cpp
../uint256.cpp
../util/chaintype.cpp
diff --git a/src/kernel/mempool_entry.h b/src/kernel/mempool_entry.h
index 40aa77b5..cd86f366 100644
--- a/src/kernel/mempool_entry.h
+++ b/src/kernel/mempool_entry.h
@@ -11,6 +11,7 @@
#include <policy/policy.h>
#include <policy/settings.h>
#include <primitives/transaction.h>
+#include <txgraph.h>
#include <util/epochguard.h>
#include <util/overflow.h>
@@ -62,7 +63,7 @@ struct CompareIteratorByHash {
*
*/
-class CTxMemPoolEntry
+class CTxMemPoolEntry : public TxGraph::Ref
{
public:
typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef;
@@ -103,11 +104,13 @@ private:
int64_t nSigOpCostWithAncestors;
public:
- CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
+ virtual ~CTxMemPoolEntry() = default;
+ CTxMemPoolEntry(TxGraph::Ref&& ref, const CTransactionRef& tx, CAmount fee,
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
bool spends_coinbase,
int64_t sigops_cost, LockPoints lp)
- : tx{tx},
+ : TxGraph::Ref(std::move(ref)),
+ tx{tx},
nFee{fee},
nTxWeight{GetTransactionWeight(*tx)},
nUsageSize{RecursiveDynamicUsage(tx)},
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index fd3fa226..0626e2c6 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -720,7 +720,7 @@ public:
{
if (!m_node.mempool) return {};
LockPoints lp;
- CTxMemPoolEntry entry(tx, 0, 0, 0, 0, false, 0, lp);
+ CTxMemPoolEntry entry(TxGraph::Ref(), tx, 0, 0, 0, 0, false, 0, lp);
LOCK(m_node.mempool->cs);
return m_node.mempool->CheckPackageLimits({tx}, entry.GetTxSize());
}
diff --git a/src/test/fuzz/util/mempool.cpp b/src/test/fuzz/util/mempool.cpp
index a6a28f94..241a4d55 100644
--- a/src/test/fuzz/util/mempool.cpp
+++ b/src/test/fuzz/util/mempool.cpp
@@ -27,5 +27,5 @@ CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider,
const auto entry_height{fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, max_height)};
const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
- return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, entry_sequence, spends_coinbase, sig_op_cost, {}};
+ return CTxMemPoolEntry{TxGraph::Ref(), MakeTransactionRef(tx), fee, time, entry_height, entry_sequence, spends_coinbase, sig_op_cost, {}};
}
diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp
index 5febb679..0cb15b69 100644
--- a/src/test/util/txmempool.cpp
+++ b/src/test/util/txmempool.cpp
@@ -37,7 +37,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx) co
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransactionRef& tx) const
{
- return CTxMemPoolEntry{tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), nHeight, m_sequence, spendsCoinbase, sigOpCost, lp};
+ return CTxMemPoolEntry{TxGraph::Ref(), tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), nHeight, m_sequence, spendsCoinbase, sigOpCost, lp};
}
std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index a695fbff..e6e2042e 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -1386,7 +1386,7 @@ CTxMemPool::ChangeSet::TxHandle CTxMemPool::ChangeSet::StageAddition(const CTran
{
LOCK(m_pool->cs);
Assume(m_to_add.find(tx->GetHash()) == m_to_add.end());
- auto newit = m_to_add.emplace(tx, fee, time, entry_height, entry_sequence, spends_coinbase, sigops_cost, lp).first;
+ auto newit = m_to_add.emplace(TxGraph::Ref(), tx, fee, time, entry_height, entry_sequence, spends_coinbase, sigops_cost, lp).first;
CAmount delta{0};
m_pool->ApplyDelta(tx->GetHash(), delta);
if (delta) m_to_add.modify(newit, [&delta](CTxMemPoolEntry& e) { e.UpdateModifiedFee(delta); });
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.