aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2018-02-06 13:51:44 -0500
committerMatt Corallo <git@bluematt.me>2018-02-06 13:51:44 -0500
commit85aa8398f5d13c659299b81cdae377462b4f8316 (patch)
tree2d1fd73c3efdec208b4e607ea403a38275cec668 /src/validation.cpp
parent1462bde767a121233118c04c5629bd9de1ba0f16 (diff)
downloadbitcoin-85aa8398f5d13c659299b81cdae377462b4f8316.tar.xz
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
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp9
1 files changed, 1 insertions, 8 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 698ef9181d..a8b41d16e6 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -547,6 +547,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
const CTransaction& tx = *ptx;
const uint256 hash = tx.GetHash();
AssertLockHeld(cs_main);
+ LOCK(pool.cs); // mempool "read lock" (held through GetMainSignals().TransactionAddedToMempool())
if (pfMissingInputs)
*pfMissingInputs = false;
@@ -581,8 +582,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// Check for conflicts with in-memory transactions
std::set<uint256> setConflicts;
- {
- LOCK(pool.cs); // protect pool.mapNextTx
for (const CTxIn &txin : tx.vin)
{
auto itConflicting = pool.mapNextTx.find(txin.prevout);
@@ -623,15 +622,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
}
}
}
- }
{
CCoinsView dummy;
CCoinsViewCache view(&dummy);
LockPoints lp;
- {
- LOCK(pool.cs);
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
view.SetBackend(viewMemPool);
@@ -670,8 +666,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final");
- } // end LOCK(pool.cs)
-
CAmount nFees = 0;
if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) {
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
@@ -768,7 +762,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// If we don't hold the lock allConflicting might be incomplete; the
// subsequent RemoveStaged() and addUnchecked() calls don't guarantee
// mempool consistency for us.
- LOCK(pool.cs);
const bool fReplacementTransaction = setConflicts.size();
if (fReplacementTransaction)
{