It’s probably not too important, but this is a bit of a performance and memory regression to construct the vector of TxMempoolInfo
when really we only need the underlying txref.
I think it could make sense to add std::vector<const CTxMemPoolEntry*> entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs);
to reduce memory and computational overhead and as a bonus make the code a bit easier to read when we just want to iterate over the mempool entries?
0diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
1index a73530c142..155546c3a1 100644
2--- a/src/node/interfaces.cpp
3+++ b/src/node/interfaces.cpp
4@@ -807,8 +807,8 @@ public:
5 {
6 if (!m_node.mempool) return;
7 LOCK2(::cs_main, m_node.mempool->cs);
8- for (const auto& txinfo : m_node.mempool->infoAll()) {
9- notifications.transactionAddedToMempool(txinfo.tx);
10+ for (const auto& entry : m_node.mempool->entryAll()) {
11+ notifications.transactionAddedToMempool(Assert(entry)->GetSharedTx());
12 }
13 }
14 bool hasAssumedValidChain() override
15diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
16index 4093eb99af..82fe394b45 100644
17--- a/src/rpc/mempool.cpp
18+++ b/src/rpc/mempool.cpp
19@@ -343,16 +343,13 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempoo
20 }
21 LOCK(pool.cs);
22 UniValue o(UniValue::VOBJ);
23- for (const auto& txinfo : pool.infoAll()) {
24- const Txid& hash = txinfo.tx->GetHash();
25- const auto entry{pool.GetEntry(hash)};
26- CHECK_NONFATAL(entry != nullptr);
27+ for (const auto& entry : pool.entryAll()) {
28 UniValue info(UniValue::VOBJ);
29- entryToJSON(pool, info, *entry);
30+ entryToJSON(pool, info, *CHECK_NONFATAL(entry));
31 // Mempool has unique entries so there is no advantage in using
32 // UniValue::pushKV, which checks if the key already exists in O(N).
33 // UniValue::pushKVEnd is used instead which currently is O(1).
34- o.pushKVEnd(hash.ToString(), info);
35+ o.pushKVEnd(entry->GetTx().ToString(), info);
36 }
37 return o;
38 } else {
39diff --git a/src/txmempool.cpp b/src/txmempool.cpp
40index 684116c011..542c904a1a 100644
41--- a/src/txmempool.cpp
42+++ b/src/txmempool.cpp
43@@ -838,6 +838,20 @@ static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator
44 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
45 }
46
47+std::vector<const CTxMemPoolEntry*> CTxMemPool::entryAll() const
48+{
49+ AssertLockHeld(cs);
50+ auto iters{GetSortedDepthAndScore()};
51+
52+ std::vector<const CTxMemPoolEntry*> ret;
53+ ret.reserve(mapTx.size());
54+ for (const auto& it : iters) {
55+ ret.push_back(&(*it));
56+ }
57+
58+ return ret;
59+}
60+
61 std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
62 {
63 LOCK(cs);
64diff --git a/src/txmempool.h b/src/txmempool.h
65index e15b2972a4..7eb205b2df 100644
66--- a/src/txmempool.h
67+++ b/src/txmempool.h
68@@ -697,6 +697,7 @@ public:
69 /** Returns info for a transaction if its entry_sequence < last_sequence */
70 TxMempoolInfo info_for_relay(const GenTxid& gtxid, uint64_t last_sequence) const;
71
72+ std::vector<const CTxMemPoolEntry*> entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs);
73 std::vector<TxMempoolInfo> infoAll() const;
74
75 size_t DynamicMemoryUsage() const;