diff options
| author | p-j01 <[email protected]> | 2021-06-13 23:33:42 +0000 |
|---|---|---|
| committer | p-j01 <[email protected]> | 2021-06-14 00:03:51 +0000 |
| commit | 4c68245cf79036b2eba493221d93791b98412448 (patch) | |
| tree | e38791d056117e46d2bd28f8e930062646bea56e /src/net_processing.cpp | |
| parent | Merge pull request #1825 from alamshafil/master (diff) | |
| download | discoin-4c68245cf79036b2eba493221d93791b98412448.tar.xz discoin-4c68245cf79036b2eba493221d93791b98412448.zip | |
fix: Disconnect stalling peers after timeout of header sync
Diffstat (limited to 'src/net_processing.cpp')
| -rw-r--r-- | src/net_processing.cpp | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1b33d529b..5c595a891 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -169,6 +169,8 @@ struct CNodeState { int nUnconnectingHeaders; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; + //! When to potentially disconnect peer for stalling headers download + int64_t nHeadersSyncTimeout; //! Since when we're stalling block download progress (in microseconds), or 0. int64_t nStallingSince; std::list<QueuedBlock> vBlocksInFlight; @@ -208,6 +210,7 @@ struct CNodeState { pindexBestHeaderSent = NULL; nUnconnectingHeaders = 0; fSyncStarted = false; + nHeadersSyncTimeout = 0; nStallingSince = 0; nDownloadingSince = 0; nBlocksInFlight = 0; @@ -2899,6 +2902,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr // Only actively request headers from a single peer, unless we're close to today. if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { state.fSyncStarted = true; + state.nHeadersSyncTimeout = GetTimeMicros() + HEADERS_DOWNLOAD_TIMEOUT_BASE + HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER * (GetAdjustedTime() - pindexBestHeader->GetBlockTime())/(consensusParams.nPowTargetSpacing); nSyncStarted++; const CBlockIndex *pindexStart = pindexBestHeader; /* If possible, start at the block preceding the currently @@ -3197,7 +3201,6 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr } if (!vInv.empty()) connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); - // Detect whether we're stalling nNow = GetTimeMicros(); if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { @@ -3222,7 +3225,38 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr return true; } } - + // Check for headers sync timeouts + if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) { + // Detect whether this is a stalling initial-headers-sync peer + if (pindexBestHeader->GetBlockTime() <= GetAdjustedTime() - 24*60*60) { + if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) { + // Disconnect a (non-whitelisted) peer if it is our only sync peer, + // and we have others we could be using instead. + // Note: If all our peers are inbound, then we won't + // disconnect our sync peer for stalling; we have bigger + // problems if we can't get any outbound peers. + if (!pto->fWhitelisted) { + LogPrintf("Timeout downloading headers from peer=%d, disconnecting\n", pto->GetId()); + pto->fDisconnect = true; + return true; + } else { + LogPrintf("Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->GetId()); + // Reset the headers sync state so that we have a + // chance to try downloading from a different peer. + // Note: this will also result in at least one more + // getheaders message to be sent to + // this peer (eventually). + state.fSyncStarted = false; + nSyncStarted--; + state.nHeadersSyncTimeout = 0; + } + } + } else { + // After we've caught up once, reset the timeout so we can't trigger + // disconnect later. + state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max(); + } + } // // Message: getdata (blocks) // |