diff --git a/src/validation.cpp b/src/validation.cpp index 6e9f7149604e5..c7c76d9f9e930 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2934,6 +2934,8 @@ static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main) { bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr pblock) { + AssertLockNotHeld(m_chainstate_mutex); + // Note that while we're often called here from ProcessNewBlock, this is // far from a guarantee. Things in the P2P/RPC will often end up calling // us in the middle of ProcessNewBlock - do not assume pblock is set @@ -2943,8 +2945,8 @@ bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr // ABC maintains a fair degree of expensive-to-calculate internal state // because this function periodically releases cs_main so that it does not lock up other threads for too long // during large connects - and to allow for e.g. the callback queue to drain - // we use m_cs_chainstate to enforce mutual exclusion so that only one caller may execute this function at a time - LOCK(m_cs_chainstate); + // we use m_chainstate_mutex to enforce mutual exclusion so that only one caller may execute this function at a time + LOCK(m_chainstate_mutex); auto start = Now(); @@ -3070,6 +3072,8 @@ bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) { + AssertLockNotHeld(m_chainstate_mutex); + // Genesis block can't be invalidated assert(pindex); if (pindex->nHeight == 0) return false; @@ -3081,7 +3085,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind // We do not allow ActivateBestChain() to run while InvalidateBlock() is // running, as that could cause the tip to change while we disconnect // blocks. - LOCK(m_cs_chainstate); + LOCK(m_chainstate_mutex); // We'll be acquiring and releasing cs_main below, to allow the validation // callbacks to run. However, we should keep the block index in a @@ -3223,9 +3227,10 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind void CChainState::EnforceBlock(BlockValidationState& state, const CBlockIndex *pindex) { + AssertLockNotHeld(m_chainstate_mutex); AssertLockNotHeld(::cs_main); - LOCK2(m_cs_chainstate, ::cs_main); + LOCK2(m_chainstate_mutex, ::cs_main); const CBlockIndex* pindex_walk = pindex; diff --git a/src/validation.h b/src/validation.h index e2aa77ffe77f3..fef6bfe62d501 100644 --- a/src/validation.h +++ b/src/validation.h @@ -468,10 +468,11 @@ class CChainState arith_uint256 nLastPreciousChainwork = 0; /** - * the ChainState CriticalSection - * A lock that must be held when modifying this ChainState - held in ActivateBestChain() + * The ChainState Mutex + * A lock that must be held when modifying this ChainState - held in ActivateBestChain() and + * InvalidateBlock() */ - RecursiveMutex m_cs_chainstate; + Mutex m_chainstate_mutex; /** * Whether this chainstate is undergoing initial block download. @@ -643,7 +644,7 @@ class CChainState */ bool ActivateBestChain( BlockValidationState& state, - std::shared_ptr pblock = nullptr) LOCKS_EXCLUDED(cs_main); + std::shared_ptr pblock = nullptr) LOCKS_EXCLUDED(m_chainstate_mutex, cs_main); bool AcceptBlock(const std::shared_ptr& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main); @@ -661,9 +662,9 @@ class CChainState */ bool PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); /** Mark a block as invalid. */ - bool InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); + bool InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(m_chainstate_mutex, cs_main); /** Enforce a block marking all the other chains as conflicting. */ - void EnforceBlock(BlockValidationState& state, const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); + void EnforceBlock(BlockValidationState& state, const CBlockIndex* pindex) LOCKS_EXCLUDED(m_chainstate_mutex, cs_main); /** Remove invalidity status from a block and its descendants. */ void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);