diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1248,10 +1248,11 @@ const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); - LOCK(cs_main); - bool send = false; + std::shared_ptr a_recent_block; + bool need_activate_chain = false; { + LOCK(cs_main); BlockMap::iterator mi = mapBlockIndex.find(inv.hash); if (mi != mapBlockIndex.end()) { if (mi->second->nChainTx && @@ -1263,16 +1264,20 @@ // ActivateBestChain but after AcceptBlock). In this // case, we need to run ActivateBestChain prior to // checking the relay conditions below. - std::shared_ptr a_recent_block; { LOCK(cs_most_recent_block); a_recent_block = most_recent_block; } - 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); @@ -1403,6 +1408,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()); @@ -1449,17 +1456,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); @@ -2368,7 +2374,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; }