aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2017-12-24 11:59:02 -0500
committerMatt Corallo <git@bluematt.me>2017-12-24 13:20:52 -0500
commita7348960389af9d86983e767b4aea2c7778ab726 (patch)
treef8ef8e71b6732f7d335ebc8c3613278dfd3608ad
parent66aa1d58a158991a8014a91335b5bc9c00062f56 (diff)
Avoid cs_main in net_processing ActivateBestChain calls
-rw-r--r--src/net_processing.cpp31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 3225d429b9..76e82a5ef6 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -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)
{
- LOCK(cs_main);
-
bool send = false;
std::shared_ptr<const CBlock> a_recent_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;
}
+ bool need_activate_chain = false;
{
+ LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
@@ -1064,11 +1064,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);
@@ -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)
{
+ AssertLockNotHeld(cs_main);
+
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
std::vector<CInv> vNotFound;
const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
@@ -1216,15 +1223,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 || inv.type == MSG_WITNESS_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 || inv.type == MSG_WITNESS_BLOCK) {
+ ProcessGetBlockData(pfrom, consensusParams, inv, connman, interruptMsgProc);
}
- } // release cs_main
+ }
pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
@@ -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.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;
}