Example #1
0
 public void ReportBreachOfProtocol(PeerInfo peerInfo, string details)
 {
     /* since the allocations can have the peers dynamically changed
      * it may be hard for the external classes to ensure that the peerInfo is not null at the time when they report
      * so we decide to check for null here and not consider the scenario to be exceptional
      */
     if (peerInfo != null)
     {
         _stats.ReportSyncEvent(peerInfo.SyncPeer.Node, NodeStatsEventType.SyncFailed);
         peerInfo.SyncPeer.Disconnect(DisconnectReason.BreachOfProtocol, details);
     }
 }
Example #2
0
        public void ReportWeakPeer(PeerInfo weakPeer, AllocationContexts allocationContexts)
        {
            if (weakPeer == null)
            {
                /* it may have just got disconnected and in such case the allocation would be nullified
                 * in such case there is no need to talk about whether the peer is good or bad
                 */
                return;
            }

            AllocationContexts sleeps = weakPeer.IncreaseWeakness(allocationContexts);

            if (sleeps != AllocationContexts.None)
            {
                weakPeer.PutToSleep(sleeps, DateTime.UtcNow);
            }
        }
        public void Cancel()
        {
            PeerInfo current = Current;

            if (current == null)
            {
                return;
            }

            lock (_allocationLock)
            {
                current.Free(Contexts);
                Current = null;
            }

            AllocationChangeEventArgs args = new AllocationChangeEventArgs(current, null);

            Cancelled?.Invoke(this, args);
        }
Example #4
0
        public void AddPeer(ISyncPeer syncPeer)
        {
            if (_logger.IsDebug)
            {
                _logger.Debug($"Adding sync peer {syncPeer.Node:c}");
            }
            if (!_isStarted)
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Sync peer pool not started yet - adding peer is blocked: {syncPeer.Node:s}");
                }
                return;
            }

            if (_peers.ContainsKey(syncPeer.Node.Id))
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Sync peer {syncPeer.Node:c} already in peers collection.");
                }
                return;
            }

            PeerInfo peerInfo = new PeerInfo(syncPeer);

            _peers.TryAdd(syncPeer.Node.Id, peerInfo);
            Metrics.SyncPeers = _peers.Count;

            if (_logger.IsDebug)
            {
                _logger.Debug($"Adding {syncPeer.Node:c} to refresh queue");
            }
            if (NetworkDiagTracer.IsEnabled)
            {
                NetworkDiagTracer.ReportInterestingEvent(syncPeer.Node.Host, "adding node to refresh queue");
            }
            _peerRefreshQueue.Add(new RefreshTotalDiffTask {
                SyncPeer = syncPeer
            });
        }
        public void AllocateBestPeer(IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree)
        {
            PeerInfo current  = Current;
            PeerInfo selected = _peerAllocationStrategy.Allocate(Current, peers, nodeStatsManager, blockTree);

            if (selected == current)
            {
                return;
            }

            AllocationChangeEventArgs args;

            lock (_allocationLock)
            {
                if (selected != null && selected.TryAllocate(Contexts))
                {
                    Current = selected;
                    args    = new AllocationChangeEventArgs(current, selected);
                    current?.Free(Contexts);
                    Replaced?.Invoke(this, args);
                }
            }
        }
Example #6
0
 public void ReportNoSyncProgress(PeerInfo peerInfo, AllocationContexts allocationContexts)
 {
     ReportWeakPeer(peerInfo, allocationContexts);
 }
Example #7
0
        internal void DropUselessPeers(bool force = false)
        {
            if (!force && DateTime.UtcNow - _lastUselessPeersDropTime < TimeSpan.FromSeconds(30))
            {
                // give some time to monitoring nodes
                // (monitoring nodes are nodes that are investigating the network but are not synced themselves)
                return;
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Reviewing {PeerCount} peer usefulness");
            }

            int peersDropped = 0;

            _lastUselessPeersDropTime = DateTime.UtcNow;

            long    ourNumber     = _blockTree.BestSuggestedHeader?.Number ?? 0L;
            UInt256 ourDifficulty = _blockTree.BestSuggestedHeader?.TotalDifficulty ?? UInt256.Zero;

            foreach (PeerInfo peerInfo in AllPeers)
            {
                if (peerInfo.HeadNumber == 0 &&
                    peerInfo.IsInitialized &&
                    ourNumber != 0 &&
                    peerInfo.PeerClientType != PeerClientType.Nethermind)
                // we know that Nethermind reports 0 HeadNumber when it is in sync (and it can still serve a lot of data to other nodes)
                {
                    if (!CanBeUsefulForFastBlocks(peerInfo.HeadNumber))
                    {
                        peersDropped++;
                        peerInfo.SyncPeer.Disconnect(DisconnectReason.UselessPeer, "PEER REVIEW / HEAD 0");
                    }
                }
                else if (peerInfo.HeadNumber == 1920000 && _blockTree.ChainId == ChainId.Mainnet) // mainnet, stuck Geth nodes
                {
                    if (!CanBeUsefulForFastBlocks(peerInfo.HeadNumber))
                    {
                        peersDropped++;
                        peerInfo.SyncPeer.Disconnect(DisconnectReason.UselessPeer, "PEER REVIEW / 1920000");
                    }
                }
                else if (peerInfo.HeadNumber == 7280022 && _blockTree.ChainId == ChainId.Mainnet) // mainnet, stuck Geth nodes
                {
                    if (!CanBeUsefulForFastBlocks(peerInfo.HeadNumber))
                    {
                        peersDropped++;
                        peerInfo.SyncPeer.Disconnect(DisconnectReason.UselessPeer, "PEER REVIEW / 7280022");
                    }
                }
                else if (peerInfo.HeadNumber > ourNumber + 1024L && peerInfo.TotalDifficulty < ourDifficulty)
                {
                    if (!CanBeUsefulForFastBlocks(MainnetSpecProvider.Instance.DaoBlockNumber ?? 0))
                    {
                        // probably Ethereum Classic nodes tht remain connected after we went pass the DAO
                        // worth to find a better way to discard them at the right time
                        peersDropped++;
                        peerInfo.SyncPeer.Disconnect(DisconnectReason.UselessPeer, "STRAY PEER");
                    }
                }
            }

            if (PeerCount == PeerMaxCount)
            {
                long     lowestBlockNumber = long.MaxValue;
                PeerInfo worstPeer         = null;
                foreach (PeerInfo peerInfo in AllPeers)
                {
                    if (peerInfo.HeadNumber < lowestBlockNumber)
                    {
                        lowestBlockNumber = peerInfo.HeadNumber;
                        worstPeer         = peerInfo;
                    }
                }

                peersDropped++;
                worstPeer?.SyncPeer.Disconnect(DisconnectReason.TooManyPeers, "PEER REVIEW / LOWEST NUMBER");
            }

            if (_logger.IsDebug)
            {
                _logger.Debug($"Dropped {peersDropped} useless peers");
            }
        }
Example #8
0
 private void AddPeerInfo(PeerInfo peerInfo)
 {
     _stringBuilder.Append($"   {peerInfo}[{_stats.GetOrAdd(peerInfo.SyncPeer.Node).GetAverageTransferSpeed(TransferSpeedType.Latency) ?? 0}|{_stats.GetOrAdd(peerInfo.SyncPeer.Node).GetAverageTransferSpeed(TransferSpeedType.Headers) ?? 0}|{_stats.GetOrAdd(peerInfo.SyncPeer.Node).GetAverageTransferSpeed(TransferSpeedType.Bodies) ?? 0}|{_stats.GetOrAdd(peerInfo.SyncPeer.Node).GetAverageTransferSpeed(TransferSpeedType.Receipts) ?? 0}|{_stats.GetOrAdd(peerInfo.SyncPeer.Node).GetAverageTransferSpeed(TransferSpeedType.NodeData) ?? 0}]");
 }
 public SyncPeerAllocation(PeerInfo peerInfo, AllocationContexts contexts)
     : this(new StaticStrategy(peerInfo), contexts)
 {
 }