Skip to content

Commit fa5ed4f

Browse files
author
MarcoFalke
committed
refactor: Avoid locking tx pool cs thrice
1 parent ad51e13 commit fa5ed4f

File tree

8 files changed

+18
-15
lines changed

8 files changed

+18
-15
lines changed

src/bench/mempool_eviction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <list>
1010
#include <vector>
1111

12-
static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& pool)
12+
static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
1313
{
1414
int64_t nTime = 0;
1515
unsigned int nHeight = 1;
@@ -108,6 +108,7 @@ static void MempoolEviction(benchmark::State& state)
108108
tx7.vout[1].nValue = 10 * COIN;
109109

110110
CTxMemPool pool;
111+
LOCK(pool.cs);
111112
// Create transaction references outside the "hot loop"
112113
const CTransactionRef tx1_r{MakeTransactionRef(tx1)};
113114
const CTransactionRef tx2_r{MakeTransactionRef(tx2)};

src/test/blockencodings_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
6262
TestMemPoolEntryHelper entry;
6363
CBlock block(BuildBlockTestCase());
6464

65-
pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2]));
6665
LOCK(pool.cs);
66+
pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2]));
6767
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
6868

6969
// Do a simple ShortTxIDs RT
@@ -162,8 +162,8 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
162162
TestMemPoolEntryHelper entry;
163163
CBlock block(BuildBlockTestCase());
164164

165-
pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2]));
166165
LOCK(pool.cs);
166+
pool.addUnchecked(block.vtx[2]->GetHash(), entry.FromTx(block.vtx[2]));
167167
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
168168

169169
uint256 txhash;
@@ -232,8 +232,8 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
232232
TestMemPoolEntryHelper entry;
233233
CBlock block(BuildBlockTestCase());
234234

235-
pool.addUnchecked(block.vtx[1]->GetHash(), entry.FromTx(block.vtx[1]));
236235
LOCK(pool.cs);
236+
pool.addUnchecked(block.vtx[1]->GetHash(), entry.FromTx(block.vtx[1]));
237237
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
238238

239239
uint256 txhash;

src/test/mempool_tests.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
5555

5656

5757
CTxMemPool testPool;
58+
LOCK(testPool.cs);
5859

5960
// Nothing in pool, remove should do nothing:
6061
unsigned int poolSize = testPool.size();
@@ -119,6 +120,7 @@ static void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) E
119120
BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
120121
{
121122
CTxMemPool pool;
123+
LOCK(pool.cs);
122124
TestMemPoolEntryHelper entry;
123125

124126
/* 3rd highest fee */
@@ -165,7 +167,6 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
165167
sortedOrder[2] = tx1.GetHash().ToString(); // 10000
166168
sortedOrder[3] = tx4.GetHash().ToString(); // 15000
167169
sortedOrder[4] = tx2.GetHash().ToString(); // 20000
168-
LOCK(pool.cs);
169170
CheckSort<descendant_score>(pool, sortedOrder);
170171

171172
/* low fee but with high fee child */
@@ -292,6 +293,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
292293
BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
293294
{
294295
CTxMemPool pool;
296+
LOCK(pool.cs);
295297
TestMemPoolEntryHelper entry;
296298

297299
/* 3rd highest fee */
@@ -347,7 +349,6 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
347349
}
348350
sortedOrder[4] = tx3.GetHash().ToString(); // 0
349351

350-
LOCK(pool.cs);
351352
CheckSort<ancestor_score>(pool, sortedOrder);
352353

353354
/* low fee parent with high fee child */
@@ -421,6 +422,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
421422
BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
422423
{
423424
CTxMemPool pool;
425+
LOCK(pool.cs);
424426
TestMemPoolEntryHelper entry;
425427

426428
CMutableTransaction tx1 = CMutableTransaction();
@@ -593,6 +595,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests)
593595
size_t ancestors, descendants;
594596

595597
CTxMemPool pool;
598+
LOCK(pool.cs);
596599
TestMemPoolEntryHelper entry;
597600

598601
/* Base transaction */

src/test/miner_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static bool TestSequenceLocks(const CTransaction &tx, int flags)
9999
// Test suite for ancestor feerate transaction selection.
100100
// Implemented as an additional function, rather than a separate test case,
101101
// to allow reusing the blockchain created in CreateNewBlock_validity.
102-
static void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransactionRef>& txFirst)
102+
static void TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::mempool.cs)
103103
{
104104
// Test the ancestor feerate transaction selection.
105105
TestMemPoolEntryHelper entry;
@@ -253,6 +253,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
253253
}
254254

255255
LOCK(cs_main);
256+
LOCK(::mempool.cs);
256257

257258
// Just to make sure we can still make simple blocks
258259
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));

src/test/policyestimator_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
1818
{
1919
CBlockPolicyEstimator feeEst;
2020
CTxMemPool mpool(&feeEst);
21+
LOCK(mpool.cs);
2122
TestMemPoolEntryHelper entry;
2223
CAmount basefee(2000);
2324
CAmount deltaFee(100);

src/txmempool.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes
151151

152152
bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const
153153
{
154-
LOCK(cs);
155-
156154
setEntries parentHashes;
157155
const CTransaction &tx = entry.GetTx();
158156

@@ -363,7 +361,6 @@ void CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
363361
// Add to memory pool without checking anything.
364362
// Used by AcceptToMemoryPool(), which DOES do
365363
// all the appropriate checks.
366-
LOCK(cs);
367364
indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
368365
mapLinks.insert(make_pair(newit, TxLinks()));
369366

@@ -933,7 +930,6 @@ int CTxMemPool::Expire(int64_t time) {
933930

934931
void CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool validFeeEstimate)
935932
{
936-
LOCK(cs);
937933
setEntries setAncestors;
938934
uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
939935
std::string dummy;

src/txmempool.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,8 @@ class CTxMemPool
539539
// Note that addUnchecked is ONLY called from ATMP outside of tests
540540
// and any other callers may break wallet's in-mempool tracking (due to
541541
// lack of CValidationInterface::TransactionAddedToMempool callbacks).
542-
void addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool validFeeEstimate = true);
543-
void addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true);
542+
void addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs);
543+
void addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs);
544544

545545
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
546546
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
@@ -596,7 +596,7 @@ class CTxMemPool
596596
* fSearchForParents = whether to search a tx's vin for in-mempool parents, or
597597
* look up parents from mapLinks. Must be true for entries not in the mempool
598598
*/
599-
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true) const;
599+
bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string& errString, bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs);
600600

601601
/** Populate setDescendants with all in-mempool descendants of hash.
602602
* Assumes that setDescendants includes all in-mempool descendants of anything

src/wallet/wallet.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3018,7 +3018,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
30183018
size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
30193019
size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
30203020
std::string errString;
3021-
if (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
3021+
LOCK(::mempool.cs);
3022+
if (!::mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
30223023
strFailReason = _("Transaction has too long of a mempool chain");
30233024
return false;
30243025
}

0 commit comments

Comments
 (0)