Skip to content

Commit b09ad73

Browse files
author
MarcoFalke
committed
Merge #20944: rpc: Return total fee in getmempoolinfo
fa36206 rpc: Return total fee in mempool (MarcoFalke) Pull request description: This avoids having to loop over the whole mempool to query each entry's fee ACKs for top commit: achow101: ACK fa36206 glozow: ACK bitcoin/bitcoin@fa36206 🧸 jnewbery: ACK fa36206 Tree-SHA512: e2fa1664df39c9e187f9229fc35764ccf436f6f75889c5a206d34fff473fc21efbf2bb143f4ca7895c27659218c22884d0ec4195e7a536a5a96973fc9dd82d08
2 parents b401b09 + fa36206 commit b09ad73

File tree

5 files changed

+32
-14
lines changed

5 files changed

+32
-14
lines changed

doc/REST-interface.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,7 @@ $ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76
111111

112112
Returns various information about the TX mempool.
113113
Only supports JSON as output format.
114-
* loaded : (boolean) if the mempool is fully loaded
115-
* size : (numeric) the number of transactions in the TX mempool
116-
* bytes : (numeric) size of the TX mempool in bytes
117-
* usage : (numeric) total TX mempool memory usage
118-
* maxmempool : (numeric) maximum memory usage for the mempool in bytes
119-
* mempoolminfee : (numeric) minimum feerate (BTC per KB) for tx to be accepted
114+
Refer to the `getmempoolinfo` RPC for documentation of the fields.
120115

121116
`GET /rest/mempool/contents.json`
122117

src/rpc/blockchain.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#include <node/coinstats.h>
1818
#include <node/context.h>
1919
#include <node/utxo_snapshot.h>
20-
#include <policy/fees.h>
2120
#include <policy/feerate.h>
21+
#include <policy/fees.h>
2222
#include <policy/policy.h>
2323
#include <policy/rbf.h>
2424
#include <primitives/transaction.h>
@@ -1500,6 +1500,7 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool)
15001500
ret.pushKV("size", (int64_t)pool.size());
15011501
ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
15021502
ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
1503+
ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
15031504
size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
15041505
ret.pushKV("maxmempool", (int64_t) maxmempool);
15051506
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
@@ -1520,6 +1521,7 @@ static RPCHelpMan getmempoolinfo()
15201521
{RPCResult::Type::NUM, "size", "Current tx count"},
15211522
{RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"},
15221523
{RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
1524+
{RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritizetransaction"},
15231525
{RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
15241526
{RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
15251527
{RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},

src/txmempool.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
#include <consensus/tx_verify.h>
1010
#include <consensus/validation.h>
1111
#include <optional.h>
12-
#include <validation.h>
13-
#include <policy/policy.h>
1412
#include <policy/fees.h>
13+
#include <policy/policy.h>
1514
#include <policy/settings.h>
1615
#include <reverse_iterator.h>
17-
#include <util/system.h>
1816
#include <util/moneystr.h>
17+
#include <util/system.h>
1918
#include <util/time.h>
19+
#include <validation.h>
2020
#include <validationinterface.h>
2121

2222
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
@@ -396,7 +396,10 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
396396

397397
nTransactionsUpdated++;
398398
totalTxSize += entry.GetTxSize();
399-
if (minerPolicyEstimator) {minerPolicyEstimator->processTransaction(entry, validFeeEstimate);}
399+
m_total_fee += entry.GetFee();
400+
if (minerPolicyEstimator) {
401+
minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
402+
}
400403

401404
vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
402405
newit->vTxHashesIdx = vTxHashes.size() - 1;
@@ -432,6 +435,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
432435
vTxHashes.clear();
433436

434437
totalTxSize -= it->GetTxSize();
438+
m_total_fee -= it->GetFee();
435439
cachedInnerUsage -= it->DynamicMemoryUsage();
436440
cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
437441
mapTx.erase(it);
@@ -590,6 +594,7 @@ void CTxMemPool::_clear()
590594
mapTx.clear();
591595
mapNextTx.clear();
592596
totalTxSize = 0;
597+
m_total_fee = 0;
593598
cachedInnerUsage = 0;
594599
lastRollingFeeUpdate = GetTime();
595600
blockSinceLastRollingFeeBump = false;
@@ -623,6 +628,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
623628
LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
624629

625630
uint64_t checkTotal = 0;
631+
CAmount check_total_fee{0};
626632
uint64_t innerUsage = 0;
627633

628634
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
@@ -632,6 +638,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
632638
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
633639
unsigned int i = 0;
634640
checkTotal += it->GetTxSize();
641+
check_total_fee += it->GetFee();
635642
innerUsage += it->DynamicMemoryUsage();
636643
const CTransaction& tx = it->GetTx();
637644
innerUsage += memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
@@ -726,6 +733,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
726733
}
727734

728735
assert(totalTxSize == checkTotal);
736+
assert(m_total_fee == check_total_fee);
729737
assert(innerUsage == cachedInnerUsage);
730738
}
731739

src/txmempool.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#include <optional.h>
2020
#include <policy/feerate.h>
2121
#include <primitives/transaction.h>
22-
#include <sync.h>
2322
#include <random.h>
23+
#include <sync.h>
2424
#include <util/hasher.h>
2525

2626
#include <boost/multi_index_container.hpp>
@@ -478,8 +478,9 @@ class CTxMemPool
478478
std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
479479
CBlockPolicyEstimator* minerPolicyEstimator;
480480

481-
uint64_t totalTxSize; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
482-
uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
481+
uint64_t totalTxSize GUARDED_BY(cs); //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
482+
CAmount m_total_fee GUARDED_BY(cs); //!< sum of all mempool tx's fees (NOT modified fee)
483+
uint64_t cachedInnerUsage GUARDED_BY(cs); //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
483484

484485
mutable int64_t lastRollingFeeUpdate;
485486
mutable bool blockSinceLastRollingFeeBump;
@@ -724,6 +725,12 @@ class CTxMemPool
724725
return totalTxSize;
725726
}
726727

728+
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
729+
{
730+
AssertLockHeld(cs);
731+
return m_total_fee;
732+
}
733+
727734
bool exists(const GenTxid& gtxid) const
728735
{
729736
LOCK(cs);

test/functional/mempool_persist.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,19 @@ def run_test(self):
6969
assert_equal(len(self.nodes[0].getrawmempool()), 5)
7070
assert_equal(len(self.nodes[1].getrawmempool()), 5)
7171

72+
total_fee_old = self.nodes[0].getmempoolinfo()['total_fee']
73+
7274
self.log.debug("Prioritize a transaction on node0")
7375
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
7476
assert_equal(fees['base'], fees['modified'])
7577
self.nodes[0].prioritisetransaction(txid=last_txid, fee_delta=1000)
7678
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
7779
assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified'])
7880

81+
self.log.info('Check the total base fee is unchanged after prioritisetransaction')
82+
assert_equal(total_fee_old, self.nodes[0].getmempoolinfo()['total_fee'])
83+
assert_equal(total_fee_old, sum(v['fees']['base'] for k, v in self.nodes[0].getrawmempool(verbose=True).items()))
84+
7985
tx_creation_time = self.nodes[0].getmempoolentry(txid=last_txid)['time']
8086
assert_greater_than_or_equal(tx_creation_time, tx_creation_time_lower)
8187
assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time)

0 commit comments

Comments
 (0)