public void OnPeriodicWorkException(IPeriodicWork failedWork, Exception ex, ref IPeriodicWorkExceptionHandler.Feedback feedback) { string?disconnectionReason = failedWork switch { IPeriodicWork work when work == _headerSyncLoop => "Peer header syncing loop had failures.", _ => null }; if (disconnectionReason != null) { feedback.ContinueExecution = false; PeerContext.Disconnect(disconnectionReason); } }
private void CheckSyncStallingLocked(BlockHeader bestHeader) { // Check for headers sync timeouts if (_status.IsSynchronizingHeaders && _status.HeadersSyncTimeout < long.MaxValue) { long now = _dateTimeProvider.GetTimeMicros(); // Detect whether this is a stalling initial-headers-sync peer if (bestHeader.TimeStamp <= _dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() - 24 * 60 * 60) { bool isTheOnlyPeerSynching = true; //nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1) if (now > _status.HeadersSyncTimeout && isTheOnlyPeerSynching) { // 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 (!PeerContext.Permissions.Has(BitcoinPeerPermissions.NOBAN)) { PeerContext.Disconnect("Timeout downloading headers, disconnecting"); return; } else { logger.LogDebug("Timeout downloading headers from whitelisted peer {PeerId}, not disconnecting.", PeerContext.PeerId); // 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). _status.IsSynchronizingHeaders = false; _status.HeadersSyncTimeout = 0; } } } else { // After we've caught up once, reset the timeout so we can't trigger disconnect later. _status.HeadersSyncTimeout = long.MaxValue; } } }