Skip to content

Commit

Permalink
Avoid cs_main in net_processing ActivateBestChain calls
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBlueMatt authored and codablock committed Mar 12, 2019
1 parent f69c437 commit 2eb5531
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,8 +1060,6 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma

void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensusParams, const CInv& inv, CConnman& connman, const std::atomic<bool>& interruptMsgProc)
{
LOCK(cs_main);

bool send = false;
std::shared_ptr<const CBlock> a_recent_block;
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
Expand All @@ -1071,7 +1069,9 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
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())
{
Expand All @@ -1082,11 +1082,16 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
// before ActivateBestChain but after AcceptBlock).
// In this case, we need to run ActivateBestChain prior to checking the relay
// conditions below.
CValidationState dummy;
ActivateBestChain(dummy, Params(), a_recent_block);
need_activate_chain = true;
}
}
} // release cs_main before calling ActivateBestChain
if (need_activate_chain) {
CValidationState dummy;
ActivateBestChain(dummy, Params(), a_recent_block);
}

LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end()) {
send = BlockRequestAllowed(mi->second, consensusParams);
Expand Down Expand Up @@ -1181,6 +1186,8 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus

void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman& connman, const std::atomic<bool>& interruptMsgProc)
{
AssertLockNotHeld(cs_main);

std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
std::vector<CInv> vNotFound;
const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
Expand Down Expand Up @@ -1362,15 +1369,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// 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(pfrom, consensusParams, 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(pfrom, consensusParams, inv, connman, interruptMsgProc);
}
} // release cs_main
}

pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);

Expand Down Expand Up @@ -1977,7 +1984,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
inv.type = MSG_BLOCK;
inv.hash = req.blockhash;
pfrom->vRecvGetData.push_back(inv);
ProcessGetData(pfrom, chainparams.GetConsensus(), connman, interruptMsgProc);
// The message processing loop will go around again (without pausing) and we'll respond then (without cs_main)
return true;
}

Expand Down

0 comments on commit 2eb5531

Please sign in to comment.