Avoid cs_main in net_processing ActivateBestChain calls

This commit is contained in:
Matt Corallo 2017-12-24 11:59:02 -05:00
parent 66aa1d58a1
commit a734896038

View file

@ -1040,8 +1040,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) 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; bool send = false;
std::shared_ptr<const CBlock> a_recent_block; std::shared_ptr<const CBlock> a_recent_block;
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
@ -1053,7 +1051,9 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock; fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
} }
bool need_activate_chain = false;
{ {
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(inv.hash); BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end()) if (mi != mapBlockIndex.end())
{ {
@ -1064,11 +1064,16 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
// before ActivateBestChain but after AcceptBlock). // before ActivateBestChain but after AcceptBlock).
// In this case, we need to run ActivateBestChain prior to checking the relay // In this case, we need to run ActivateBestChain prior to checking the relay
// conditions below. // conditions below.
CValidationState dummy; need_activate_chain = true;
ActivateBestChain(dummy, Params(), a_recent_block);
} }
} }
} // 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); BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end()) { if (mi != mapBlockIndex.end()) {
send = BlockRequestAllowed(mi->second, consensusParams); send = BlockRequestAllowed(mi->second, consensusParams);
@ -1177,6 +1182,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) 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::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
std::vector<CInv> vNotFound; std::vector<CInv> vNotFound;
const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
@ -1216,16 +1223,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// Track requests for our stuff. // Track requests for our stuff.
GetMainSignals().Inventory(inv.hash); GetMainSignals().Inventory(inv.hash);
} }
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 || inv.type == MSG_WITNESS_BLOCK) {
ProcessGetBlockData(pfrom, consensusParams, inv, connman, interruptMsgProc);
}
}
} // release cs_main } // 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 || inv.type == MSG_WITNESS_BLOCK) {
ProcessGetBlockData(pfrom, consensusParams, inv, connman, interruptMsgProc);
}
}
pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
if (!vNotFound.empty()) { if (!vNotFound.empty()) {
@ -2027,7 +2034,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK; inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK;
inv.hash = req.blockhash; inv.hash = req.blockhash;
pfrom->vRecvGetData.push_back(inv); 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; return true;
} }