@ -144,6 +144,12 @@ private:
*/
*/
std : : set < CBlockIndex * > g_failed_blocks ;
std : : set < CBlockIndex * > g_failed_blocks ;
/**
* the ChainState CriticalSection
* A lock that must be held when modifying this ChainState - held in ActivateBestChain ( )
*/
CCriticalSection m_cs_chainstate ;
public :
public :
CChain chainActive ;
CChain chainActive ;
BlockMap mapBlockIndex ;
BlockMap mapBlockIndex ;
@ -2451,6 +2457,7 @@ void CChainState::PruneBlockIndexCandidates() {
bool CChainState : : ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const std : : shared_ptr < const CBlock > & pblock , bool & fInvalidFound , ConnectTrace & connectTrace )
bool CChainState : : ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const std : : shared_ptr < const CBlock > & pblock , bool & fInvalidFound , ConnectTrace & connectTrace )
{
{
AssertLockHeld ( cs_main ) ;
AssertLockHeld ( cs_main ) ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
const CBlockIndex * pindexFork = chainActive . FindFork ( pindexMostWork ) ;
const CBlockIndex * pindexFork = chainActive . FindFork ( pindexMostWork ) ;
@ -2562,6 +2569,12 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
// sanely for performance or correctness!
// sanely for performance or correctness!
AssertLockNotHeld ( cs_main ) ;
AssertLockNotHeld ( cs_main ) ;
// 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 ) ;
CBlockIndex * pindexMostWork = nullptr ;
CBlockIndex * pindexMostWork = nullptr ;
CBlockIndex * pindexNewTip = nullptr ;
CBlockIndex * pindexNewTip = nullptr ;
int nStopAtHeight = gArgs . GetArg ( " -stopatheight " , DEFAULT_STOPATHEIGHT ) ;
int nStopAtHeight = gArgs . GetArg ( " -stopatheight " , DEFAULT_STOPATHEIGHT ) ;