diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1250,8 +1250,6 @@ const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); - LOCK(cs_main); - bool send = false; std::shared_ptr a_recent_block; std::shared_ptr a_recent_compact_block; @@ -1261,7 +1259,9 @@ a_recent_compact_block = most_recent_compact_block; } + bool need_activate_chain = false; { + LOCK(cs_main); BlockMap::iterator mi = mapBlockIndex.find(inv.hash); if (mi != mapBlockIndex.end()) { if (mi->second->nChainTx && @@ -1273,11 +1273,16 @@ // ActivateBestChain but after AcceptBlock). In this // case, we need to run ActivateBestChain prior to // checking the relay conditions below. - CValidationState dummy; - ActivateBestChain(config, dummy, a_recent_block); + need_activate_chain = true; } } + } // release cs_main before calling ActivateBestChain + if (need_activate_chain) { + CValidationState dummy; + ActivateBestChain(config, dummy, a_recent_block); } + + LOCK(cs_main); BlockMap::iterator mi = mapBlockIndex.find(inv.hash); if (mi != mapBlockIndex.end()) { send = BlockRequestAllowed(mi->second, consensusParams); @@ -1414,6 +1419,8 @@ static void ProcessGetData(const Config &config, CNode *pfrom, CConnman *connman, const std::atomic &interruptMsgProc) { + AssertLockNotHeld(cs_main); + std::deque::iterator it = pfrom->vRecvGetData.begin(); std::vector vNotFound; const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); @@ -1460,17 +1467,16 @@ // Track requests for our stuff. GetMainSignals().Inventory(inv.hash); } + } // release cs_main - if (it != pfrom->vRecvGetData.end()) { - const CInv &inv = *it; - it++; - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || - inv.type == MSG_CMPCT_BLOCK) { - ProcessGetBlockData(config, pfrom, inv, connman, - interruptMsgProc); - } + if (it != pfrom->vRecvGetData.end()) { + const CInv &inv = *it; + it++; + if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || + inv.type == MSG_CMPCT_BLOCK) { + ProcessGetBlockData(config, pfrom, inv, connman, interruptMsgProc); } - } // release cs_main + } pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); @@ -2379,7 +2385,8 @@ inv.type = MSG_BLOCK; inv.hash = req.blockhash; pfrom->vRecvGetData.push_back(inv); - ProcessGetData(config, pfrom, connman, interruptMsgProc); + // The message processing loop will go around again (without + // pausing) and we'll respond then (without cs_main) return true; }