Skip to content

Commit cd72033

Browse files
author
MarcoFalke
committed
Merge #20222: refactor: CTxMempool constructor clean up
f15e780 refactor: Clean up CTxMemPool initializer list (Elle Mouton) e331069 refactor: Make CTxMemPool::m_check_ratio a const and a constructor argument (Elle Mouton) 9d4b4b2 refactor: Avoid double to int cast for nCheckFrequency (Elle Mouton) Pull request description: This PR cleans up the CTxMemPool interface by including the ratio used to determine when a mempool sanity check should run in the constructor of CTxMempool instead of using nCheckFrequency which required a cast from a double to a uint32_t. Since nCheckFrequency (now called m_check_ratio) is set in the constructor and only every read from there after, it can be turned into a const and no longer needs to be guarded by the 'cs' lock. Since nCheckFrequency/m_check_ratio no longer needs to lock the 'cs' mutux, mutex lock line in the "CTxMempool::check" function can be moved below where the m_check_ratio variable is checked. Since the variable is 0 by default (meaning that "CTxMempool::check" will most likely not run its logic) this saves us from unnecessarily grabbing the lock. ACKs for top commit: jnewbery: utACK f15e780 MarcoFalke: ACK f15e780 👘 glozow: utACK bitcoin/bitcoin@f15e780 theStack: Code Review ACK f15e780 Tree-SHA512: d83f3b5311ca128847b621e5e999c7e1bf0f4e6261d4cc090fb13e229a0f7eecd66ad997f654f50a838baf708d1515740aa3bffc244909a001d01fd5ae398b68
2 parents 24e4857 + f15e780 commit cd72033

File tree

4 files changed

+20
-30
lines changed

4 files changed

+20
-30
lines changed

src/init.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,16 +1389,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
13891389
assert(!node.connman);
13901390
node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true));
13911391

1392-
// Make mempool generally available in the node context. For example the connection manager, wallet, or RPC threads,
1393-
// which are all started after this, may use it from the node context.
13941392
assert(!node.mempool);
1395-
node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator);
1396-
if (node.mempool) {
1397-
int ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1398-
if (ratio != 0) {
1399-
node.mempool->setSanityCheck(1.0 / ratio);
1400-
}
1401-
}
1393+
int check_ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1394+
node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, check_ratio);
14021395

14031396
assert(!node.chainman);
14041397
node.chainman = &g_chainman;

src/test/util/setup_common.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
141141

142142
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
143143

144-
m_node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator);
145-
m_node.mempool->setSanityCheck(1.0);
144+
m_node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, 1);
146145

147146
m_node.chainman = &::g_chainman;
148147
m_node.chainman->InitializeChainstate(*m_node.mempool);

src/txmempool.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -331,15 +331,10 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
331331
assert(int(nSigOpCostWithAncestors) >= 0);
332332
}
333333

334-
CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator)
335-
: nTransactionsUpdated(0), minerPolicyEstimator(estimator), m_epoch(0), m_has_epoch_guard(false)
334+
CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
335+
: m_check_ratio(check_ratio), minerPolicyEstimator(estimator)
336336
{
337337
_clear(); //lock free clear
338-
339-
// Sanity checks off by default for performance, because otherwise
340-
// accepting transactions becomes O(N^2) where N is the number
341-
// of transactions in the pool
342-
nCheckFrequency = 0;
343338
}
344339

345340
bool CTxMemPool::isSpent(const COutPoint& outpoint) const
@@ -523,7 +518,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
523518
if (it2 != mapTx.end())
524519
continue;
525520
const Coin &coin = pcoins->AccessCoin(txin.prevout);
526-
if (nCheckFrequency != 0) assert(!coin.IsSpent());
521+
if (m_check_ratio != 0) assert(!coin.IsSpent());
527522
if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
528523
txToRemove.insert(it);
529524
break;
@@ -619,13 +614,11 @@ static void CheckInputsAndUpdateCoins(const CTransaction& tx, CCoinsViewCache& m
619614

620615
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
621616
{
622-
LOCK(cs);
623-
if (nCheckFrequency == 0)
624-
return;
617+
if (m_check_ratio == 0) return;
625618

626-
if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency)
627-
return;
619+
if (GetRand(m_check_ratio) >= 1) return;
628620

621+
LOCK(cs);
629622
LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
630623

631624
uint64_t checkTotal = 0;

src/txmempool.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,8 @@ class SaltedTxidHasher
488488
class CTxMemPool
489489
{
490490
private:
491-
uint32_t nCheckFrequency GUARDED_BY(cs); //!< Value n means that n times in 2^32 we check.
492-
std::atomic<unsigned int> nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
491+
const int m_check_ratio; //!< Value n means that 1 times in n we check.
492+
std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
493493
CBlockPolicyEstimator* minerPolicyEstimator;
494494

495495
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.
@@ -498,8 +498,8 @@ class CTxMemPool
498498
mutable int64_t lastRollingFeeUpdate;
499499
mutable bool blockSinceLastRollingFeeBump;
500500
mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially
501-
mutable uint64_t m_epoch;
502-
mutable bool m_has_epoch_guard;
501+
mutable uint64_t m_epoch{0};
502+
mutable bool m_has_epoch_guard{false};
503503

504504
// In-memory counter for external mempool tracking purposes.
505505
// This number is incremented once every time a transaction
@@ -601,8 +601,14 @@ class CTxMemPool
601601
std::map<uint256, CAmount> mapDeltas;
602602

603603
/** Create a new CTxMemPool.
604+
* Sanity checks will be off by default for performance, because otherwise
605+
* accepting transactions becomes O(N^2) where N is the number of transactions
606+
* in the pool.
607+
*
608+
* @param[in] estimator is used to estimate appropriate transaction fees.
609+
* @param[in] check_ratio is the ratio used to determine how often sanity checks will run.
604610
*/
605-
explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr);
611+
explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr, int check_ratio = 0);
606612

607613
/**
608614
* If sanity-checking is turned on, check makes sure the pool is
@@ -611,7 +617,6 @@ class CTxMemPool
611617
* check does nothing.
612618
*/
613619
void check(const CCoinsViewCache *pcoins) const;
614-
void setSanityCheck(double dFrequency = 1.0) { LOCK(cs); nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); }
615620

616621
// addUnchecked must updated state for all ancestors of a given transaction,
617622
// to track size/count of descendant transactions. First version of

0 commit comments

Comments
 (0)