Skip to content

Commit fd5f8f9

Browse files
committed
Add CheckPeerHeaders() helper and check in (nCount == 0) too
1 parent 89b65bd commit fd5f8f9

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

src/net_processing.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,24 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac
13021302
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
13031303
}
13041304

1305+
bool static CheckGoodHeadersSyncPeer(CNode* pfrom, const CChainParams& chainparams, int nCount)
1306+
{
1307+
AssertLockHeld(cs_main);
1308+
1309+
bool fGenesis = pindexBestHeader->GetBlockHash() == chainparams.GetConsensus().hashGenesisBlock;
1310+
bool fDevNetGenesis = !chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && pindexBestHeader->GetBlockHash() == chainparams.GetConsensus().hashDevnetGenesisBlock;
1311+
if (!fGenesis && !fDevNetGenesis && nCount < MAX_HEADERS_RESULTS && GetAdjustedTime() - pindexBestHeader->GetBlockTime() > chainparams.DelayGetHeadersTime()) {
1312+
// peer has sent us a HEADERS message below maximum size and we are still quite far from being fully
1313+
// synced, this means we probably got a bad peer for initial sync and need to continue with another one.
1314+
// By disconnecting we force to start a new iteration of initial headers sync in SendMessages
1315+
// TODO should we handle whitelisted peers here as we do in headers sync timeout handling?
1316+
pfrom->fDisconnect = true;
1317+
return error("detected bad peer for initial headers sync, disconnecting peer=%d", pfrom->id);
1318+
}
1319+
1320+
return true;
1321+
}
1322+
13051323
bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman, const std::atomic<bool>& interruptMsgProc)
13061324
{
13071325
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
@@ -2417,7 +2435,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
24172435

24182436
if (nCount == 0) {
24192437
// Nothing interesting. Stop asking this peers for more headers.
2420-
return true;
2438+
// See if it's a peer with "good" headers though.
2439+
LOCK(cs_main);
2440+
return CheckGoodHeadersSyncPeer(pfrom, chainparams, nCount);
24212441
}
24222442

24232443
const CBlockIndex *pindexLast = NULL;
@@ -2491,17 +2511,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
24912511
// from there instead.
24922512
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
24932513
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()));
2494-
}
2495-
2496-
bool fGenesis = pindexBestHeader->GetBlockHash() == chainparams.GetConsensus().hashGenesisBlock;
2497-
bool fDevNetGenesis = !chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && pindexBestHeader->GetBlockHash() == chainparams.GetConsensus().hashDevnetGenesisBlock;
2498-
if (!fGenesis && !fDevNetGenesis && nCount < MAX_HEADERS_RESULTS && GetAdjustedTime() - pindexBestHeader->GetBlockTime() > chainparams.DelayGetHeadersTime()) {
2499-
// peer has sent us a HEADERS message below maximum size and we are still quite far from being fully
2500-
// synced, this means we probably got a bad peer for initial sync and need to continue with another one.
2501-
// By disconnecting we force to start a new iteration of initial headers sync in SendMessages
2502-
// TODO should we handle whitelisted peers here as we do in headers sync timeout handling?
2503-
pfrom->fDisconnect = true;
2504-
return error("detected bad peer for initial headers sync, disconnecting peer=%d", pfrom->id);
2514+
} else if (!CheckGoodHeadersSyncPeer(pfrom, chainparams, nCount)) {
2515+
return false;
25052516
}
25062517

25072518
bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus());

0 commit comments

Comments
 (0)