예제 #1
0
 private void DisplayPeersReport()
 {
     _syncPeersReport.Write();
 }
예제 #2
0
        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");
            }
        }