private async Task ConnectToDiscoveryCandidatesAsync(List <IPEndPoint> peersToDiscover) { await peersToDiscover.ForEachAsync(5, this.nodeLifetime.ApplicationStopping, async (endPoint, cancellation) => { using (CancellationTokenSource connectTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellation)) { this.logger.LogDebug("Attempting to discover from : '{0}'", endPoint); connectTokenSource.CancelAfter(TimeSpan.FromSeconds(5)); INetworkPeer networkPeer = null; // Try to connect to a peer with only the address-sharing behaviour, to learn about their peers and disconnect within 5 seconds. try { NetworkPeerConnectionParameters clonedParameters = this.currentParameters.Clone(); clonedParameters.ConnectCancellation = connectTokenSource.Token; PeerAddressManagerBehaviour addressManagerBehaviour = clonedParameters.TemplateBehaviors.OfType <PeerAddressManagerBehaviour>().FirstOrDefault(); clonedParameters.TemplateBehaviors.Clear(); clonedParameters.TemplateBehaviors.Add(addressManagerBehaviour); networkPeer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(endPoint, clonedParameters).ConfigureAwait(false); await networkPeer.VersionHandshakeAsync(connectTokenSource.Token).ConfigureAwait(false); this.peerAddressManager.PeerDiscoveredFrom(endPoint, DateTimeProvider.Default.GetUtcNow()); connectTokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)); } catch { } finally { networkPeer?.Disconnect("Discovery job done"); networkPeer?.Dispose(); } this.logger.LogDebug("Discovery from '{0}' finished", endPoint); } }).ConfigureAwait(false); }
/// <summary> /// See <see cref="DiscoverPeers"/> /// </summary> private async Task DiscoverPeersAsync() { var peersToDiscover = new List <IPEndPoint>(); List <PeerAddress> foundPeers = this.peerAddressManager.PeerSelector.SelectPeersForDiscovery(1000).ToList(); peersToDiscover.AddRange(foundPeers.Select(p => p.Endpoint)); if (peersToDiscover.Count == 0) { // On normal circumstances the dns seeds are attempted only once per node lifetime. if (this.isSeedAndDnsAttempted) { this.logger.LogTrace("(-)[DNS_ATTEMPTED]"); return; } this.AddDNSSeedNodes(peersToDiscover); this.AddSeedNodes(peersToDiscover); this.isSeedAndDnsAttempted = true; if (peersToDiscover.Count == 0) { this.logger.LogTrace("(-)[NO_ADDRESSES]"); return; } peersToDiscover = peersToDiscover.OrderBy(a => RandomUtils.GetInt32()).ToList(); } else { // If all attempts have failed then attempt the dns seeds again. if (!this.isSeedAndDnsAttempted && foundPeers.All(peer => peer.Attempted)) { peersToDiscover.Clear(); this.AddDNSSeedNodes(peersToDiscover); this.AddSeedNodes(peersToDiscover); this.isSeedAndDnsAttempted = true; } } await peersToDiscover.ForEachAsync(5, this.nodeLifetime.ApplicationStopping, async (endPoint, cancellation) => { using (CancellationTokenSource connectTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellation)) { this.logger.LogTrace("Attempting to discover from : '{0}'", endPoint); connectTokenSource.CancelAfter(TimeSpan.FromSeconds(5)); INetworkPeer networkPeer = null; try { NetworkPeerConnectionParameters clonedParameters = this.currentParameters.Clone(); clonedParameters.ConnectCancellation = connectTokenSource.Token; PeerAddressManagerBehaviour addressManagerBehaviour = clonedParameters.TemplateBehaviors.OfType <PeerAddressManagerBehaviour>().FirstOrDefault(); clonedParameters.TemplateBehaviors.Clear(); clonedParameters.TemplateBehaviors.Add(addressManagerBehaviour); networkPeer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(endPoint, clonedParameters).ConfigureAwait(false); await networkPeer.VersionHandshakeAsync(connectTokenSource.Token).ConfigureAwait(false); await networkPeer.SendMessageAsync(new GetAddrPayload(), connectTokenSource.Token).ConfigureAwait(false); this.peerAddressManager.PeerDiscoveredFrom(endPoint, DateTimeProvider.Default.GetUtcNow()); connectTokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)); } catch { } finally { networkPeer?.Disconnect("Discovery job done"); networkPeer?.Dispose(); } this.logger.LogTrace("Discovery from '{0}' finished", endPoint); } }).ConfigureAwait(false); }