public int Compare(Peer x, Peer y) { if (x == null) { return(y == null ? 0 : 1); } if (y == null) { return(-1); } int staticValue = -x.Node.IsStatic.CompareTo(y.Node.IsStatic); if (staticValue != 0) { return(staticValue); } int trust = -x.Node.IsTrusted.CompareTo(y.Node.IsTrusted); if (trust != 0) { return(trust); } int reputation = -_stats.GetCurrentReputation(x.Node).CompareTo(_stats.GetCurrentReputation(y.Node)); return(reputation); }
private async Task SetupPeerConnection(Peer peer) { // Can happen when In connection is received from the same peer and is initialized before we get here // In this case we do not initialize OUT connection if (!AddActivePeer(peer.Node.Id, peer, "upgrading candidate")) { if (_logger.IsTrace) { _logger.Trace($"Active peer was already added to collection: {peer.Node.Id}"); } return; } Interlocked.Increment(ref _tryCount); Interlocked.Increment(ref _pending); bool result = await InitializePeerConnection(peer); // for some time we will have a peer in active that has no session assigned - analyze this? Interlocked.Decrement(ref _pending); if (_logger.IsTrace) { _logger.Trace($"Connecting to {_stats.GetCurrentReputation(peer.Node)} rep node - {result}, ACTIVE: {_activePeers.Count}, CAND: {_peerPool.CandidatePeerCount}"); } if (!result) { _stats.ReportEvent(peer.Node, NodeStatsEventType.ConnectionFailed); Interlocked.Increment(ref _failedInitialConnect); if (peer.OutSession != null) { if (_logger.IsTrace) { _logger.Trace($"Timeout, doing additional disconnect: {peer.Node.Id}"); } peer.OutSession?.MarkDisconnected(DisconnectReason.ReceiveMessageTimeout, DisconnectType.Local, "timeout"); } peer.IsAwaitingConnection = false; DeactivatePeerIfDisconnected(peer, "Failed to initialize connections"); return; } Interlocked.Increment(ref _newActiveNodes); }
public void Can_sort_by_Reputation() { Node a = new Node(TestItem.PublicKeyA, "127.0.0.1", 30303); Peer peerA = new Peer(a); Node b = new Node(TestItem.PublicKeyB, "127.0.0.1", 30303); Peer peerB = new Peer(b); Node c = new Node(TestItem.PublicKeyC, "127.0.0.1", 30303); Peer peerC = new Peer(c); _statsManager.GetCurrentReputation(a).Returns(100); _statsManager.GetCurrentReputation(b).Returns(50); _statsManager.GetCurrentReputation(c).Returns(200); Assert.AreEqual(-1, _comparer.Compare(peerA, peerB)); Assert.AreEqual(1, _comparer.Compare(peerA, peerC)); Assert.AreEqual(1, _comparer.Compare(peerB, peerC)); Assert.AreEqual(0, _comparer.Compare(peerA, peerA)); Assert.AreEqual(0, _comparer.Compare(peerB, peerB)); Assert.AreEqual(0, _comparer.Compare(peerC, peerC)); }
private (IReadOnlyCollection <Peer> Candidates, IDictionary <ActivePeerSelectionCounter, int> Counters, IReadOnlyCollection <Peer> IncompatiblePeers) SelectAndRankCandidates() { var counters = Enum.GetValues(typeof(ActivePeerSelectionCounter)).OfType <ActivePeerSelectionCounter>().ToDictionary(x => x, y => 0); var availableActiveCount = _networkConfig.ActivePeersMaxCount - _activePeers.Count; if (availableActiveCount <= 0) { return(Array.Empty <Peer>(), counters, Array.Empty <Peer>()); } var candidatesSnapshot = _candidatePeers.Where(x => !_activePeers.ContainsKey(x.Key)).ToArray(); if (!candidatesSnapshot.Any()) { return(Array.Empty <Peer>(), counters, Array.Empty <Peer>()); } counters[ActivePeerSelectionCounter.AllNonActiveCandidates] = candidatesSnapshot.Length; List <Peer> candidates = new List <Peer>(); List <Peer> incompatiblePeers = new List <Peer>(); for (int i = 0; i < candidatesSnapshot.Length; i++) { var candidate = candidatesSnapshot[i]; if (candidate.Value.Node.Port == 0) { counters[ActivePeerSelectionCounter.FilteredByZeroPort] = counters[ActivePeerSelectionCounter.FilteredByZeroPort] + 1; continue; } var delayResult = _stats.IsConnectionDelayed(candidate.Value.Node); if (delayResult.Result) { if (delayResult.DelayReason == NodeStatsEventType.Disconnect) { counters[ActivePeerSelectionCounter.FilteredByDisconnect] = counters[ActivePeerSelectionCounter.FilteredByDisconnect] + 1; } else if (delayResult.DelayReason == NodeStatsEventType.ConnectionFailed) { counters[ActivePeerSelectionCounter.FilteredByFailedConnection] = counters[ActivePeerSelectionCounter.FilteredByFailedConnection] + 1; } continue; } if (_stats.FindCompatibilityValidationResult(candidate.Value.Node).HasValue) { incompatiblePeers.Add(candidate.Value); continue; } if (!PeerIsDisconnected(candidate.Value)) { // in transition continue; } candidates.Add(candidate.Value); } return(candidates.OrderBy(x => x.Node.IsTrusted).ThenByDescending(x => _stats.GetCurrentReputation(x.Node)).ToList(), counters, incompatiblePeers); }