private void DisplayPeersReport() { _syncPeersReport.Write(); }
private async Task RunRefreshPeerLoop() { foreach (PeerInfo peerInfo in _peerRefreshQueue.GetConsumingEnumerable(_refreshLoopCancellation.Token)) { try { if (_logger.IsDebug) { _logger.Debug($"Running refresh peer info for {peerInfo}."); } _syncPeersReport.Write(); var initCancelSource = _refreshCancelTokens[peerInfo.SyncPeer.Node.Id] = new CancellationTokenSource(); var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(initCancelSource.Token, _refreshLoopCancellation.Token); await RefreshPeerInfo(peerInfo, linkedSource.Token).ContinueWith(t => { _refreshCancelTokens.TryRemove(peerInfo.SyncPeer.Node.Id, out _); if (t.IsFaulted) { if (t.Exception != null && t.Exception.InnerExceptions.Any(x => x.InnerException is TimeoutException)) { if (_logger.IsTrace) { _logger.Trace($"Refreshing {peerInfo} failed due to timeout: {t.Exception.Message}"); } } else if (_logger.IsDebug) { _logger.Debug($"Refreshing {peerInfo} failed {t.Exception}"); } } else if (t.IsCanceled) { if (_logger.IsTrace) { _logger.Trace($"Refresh peer info canceled: {peerInfo.SyncPeer.Node:s}"); } } else { UpdateAllocations("REFRESH"); // cases when we want other nodes to resolve the impasse (check Goerli discussion on 5 out of 9 validators) if (peerInfo.TotalDifficulty == _blockTree.BestSuggested?.TotalDifficulty && peerInfo.HeadHash != _blockTree.BestSuggested?.Hash) { Block block = _blockTree.FindBlock(_blockTree.BestSuggested.Hash, false); if (block != null) // can be null if fast syncing headers only { peerInfo.SyncPeer.SendNewBlock(block); if (_logger.IsDebug) { _logger.Debug($"Sending my best block {block} to {peerInfo}"); } } } } if (_logger.IsDebug) { _logger.Debug($"Refreshed peer info for {peerInfo}."); } initCancelSource.Dispose(); linkedSource.Dispose(); }); } catch (Exception e) { if (_logger.IsDebug) { _logger.Debug($"Failed to refresh {peerInfo} {e}"); } } } if (_logger.IsInfo) { _logger.Info($"Exiting sync peer refresh loop"); } }