@@ -1302,6 +1302,24 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac
1302
1302
connman.PushMessage (pfrom, msgMaker.Make (NetMsgType::BLOCKTXN, resp));
1303
1303
}
1304
1304
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
+
1305
1323
bool static ProcessMessage (CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman, const std::atomic<bool >& interruptMsgProc)
1306
1324
{
1307
1325
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
2417
2435
2418
2436
if (nCount == 0 ) {
2419
2437
// 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);
2421
2441
}
2422
2442
2423
2443
const CBlockIndex *pindexLast = NULL ;
@@ -2491,17 +2511,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2491
2511
// from there instead.
2492
2512
LogPrint (" net" , " more getheaders (%d) to end to peer=%d (startheight:%d)\n " , pindexLast->nHeight , pfrom->id , pfrom->nStartingHeight );
2493
2513
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 ;
2505
2516
}
2506
2517
2507
2518
bool fCanDirectFetch = CanDirectFetch (chainparams.GetConsensus ());
0 commit comments