@@ -1040,8 +1040,6 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma
1040
1040
1041
1041
void static ProcessGetBlockData (CNode* pfrom, const Consensus::Params& consensusParams, const CInv& inv, CConnman* connman, const std::atomic<bool >& interruptMsgProc)
1042
1042
{
1043
- LOCK (cs_main);
1044
-
1045
1043
bool send = false ;
1046
1044
std::shared_ptr<const CBlock> a_recent_block;
1047
1045
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
@@ -1053,7 +1051,9 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
1053
1051
fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock ;
1054
1052
}
1055
1053
1054
+ bool need_activate_chain = false ;
1056
1055
{
1056
+ LOCK (cs_main);
1057
1057
BlockMap::iterator mi = mapBlockIndex.find (inv.hash );
1058
1058
if (mi != mapBlockIndex.end ())
1059
1059
{
@@ -1064,11 +1064,16 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
1064
1064
// before ActivateBestChain but after AcceptBlock).
1065
1065
// In this case, we need to run ActivateBestChain prior to checking the relay
1066
1066
// conditions below.
1067
- CValidationState dummy;
1068
- ActivateBestChain (dummy, Params (), a_recent_block);
1067
+ need_activate_chain = true ;
1069
1068
}
1070
1069
}
1070
+ } // release cs_main before calling ActivateBestChain
1071
+ if (need_activate_chain) {
1072
+ CValidationState dummy;
1073
+ ActivateBestChain (dummy, Params (), a_recent_block);
1071
1074
}
1075
+
1076
+ LOCK (cs_main);
1072
1077
BlockMap::iterator mi = mapBlockIndex.find (inv.hash );
1073
1078
if (mi != mapBlockIndex.end ()) {
1074
1079
send = BlockRequestAllowed (mi->second , consensusParams);
@@ -1177,6 +1182,8 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
1177
1182
1178
1183
void static ProcessGetData (CNode* pfrom, const Consensus::Params& consensusParams, CConnman* connman, const std::atomic<bool >& interruptMsgProc)
1179
1184
{
1185
+ AssertLockNotHeld (cs_main);
1186
+
1180
1187
std::deque<CInv>::iterator it = pfrom->vRecvGetData .begin ();
1181
1188
std::vector<CInv> vNotFound;
1182
1189
const CNetMsgMaker msgMaker (pfrom->GetSendVersion ());
@@ -1216,15 +1223,15 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
1216
1223
// Track requests for our stuff.
1217
1224
GetMainSignals ().Inventory (inv.hash );
1218
1225
}
1226
+ } // release cs_main
1219
1227
1220
- if (it != pfrom->vRecvGetData .end ()) {
1221
- const CInv &inv = *it;
1222
- it++;
1223
- if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) {
1224
- ProcessGetBlockData (pfrom, consensusParams, inv, connman, interruptMsgProc);
1225
- }
1228
+ if (it != pfrom->vRecvGetData .end ()) {
1229
+ const CInv &inv = *it;
1230
+ it++;
1231
+ if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) {
1232
+ ProcessGetBlockData (pfrom, consensusParams, inv, connman, interruptMsgProc);
1226
1233
}
1227
- } // release cs_main
1234
+ }
1228
1235
1229
1236
pfrom->vRecvGetData .erase (pfrom->vRecvGetData .begin (), it);
1230
1237
@@ -2027,7 +2034,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2027
2034
inv.type = State (pfrom->GetId ())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK;
2028
2035
inv.hash = req.blockhash ;
2029
2036
pfrom->vRecvGetData .push_back (inv);
2030
- ProcessGetData (pfrom, chainparams. GetConsensus (), connman, interruptMsgProc);
2037
+ // The message processing loop will go around again (without pausing) and we'll respond then (without cs_main)
2031
2038
return true ;
2032
2039
}
2033
2040
0 commit comments