Skip to content

Commit 85aa839

Browse files
committed
Hold mempool.cs for the duration of ATMP.
This resolves an issue where getrawmempool() can race mempool notification signals. Intuitively we use mempool.cs as a "read lock" on the mempool with cs_main being the write lock, so holding the read lock intermittently while doing write operations is somewhat strange. This also avoids the introduction of cs_main in getrawmempool() which reviewers objected to in the previous fix in #12273
1 parent 1462bde commit 85aa839

File tree

1 file changed

+1
-8
lines changed

1 file changed

+1
-8
lines changed

src/validation.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
547547
const CTransaction& tx = *ptx;
548548
const uint256 hash = tx.GetHash();
549549
AssertLockHeld(cs_main);
550+
LOCK(pool.cs); // mempool "read lock" (held through GetMainSignals().TransactionAddedToMempool())
550551
if (pfMissingInputs)
551552
*pfMissingInputs = false;
552553

@@ -581,8 +582,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
581582

582583
// Check for conflicts with in-memory transactions
583584
std::set<uint256> setConflicts;
584-
{
585-
LOCK(pool.cs); // protect pool.mapNextTx
586585
for (const CTxIn &txin : tx.vin)
587586
{
588587
auto itConflicting = pool.mapNextTx.find(txin.prevout);
@@ -623,15 +622,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
623622
}
624623
}
625624
}
626-
}
627625

628626
{
629627
CCoinsView dummy;
630628
CCoinsViewCache view(&dummy);
631629

632630
LockPoints lp;
633-
{
634-
LOCK(pool.cs);
635631
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
636632
view.SetBackend(viewMemPool);
637633

@@ -670,8 +666,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
670666
if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
671667
return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final");
672668

673-
} // end LOCK(pool.cs)
674-
675669
CAmount nFees = 0;
676670
if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) {
677671
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
@@ -768,7 +762,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
768762
// If we don't hold the lock allConflicting might be incomplete; the
769763
// subsequent RemoveStaged() and addUnchecked() calls don't guarantee
770764
// mempool consistency for us.
771-
LOCK(pool.cs);
772765
const bool fReplacementTransaction = setConflicts.size();
773766
if (fReplacementTransaction)
774767
{

0 commit comments

Comments
 (0)