public NodeConnectionParameters(NodeConnectionParameters other) { Version = other.Version; IsRelay = other.IsRelay; Services = other.Services; ReceiveBufferSize = other.ReceiveBufferSize; SendBufferSize = other.SendBufferSize; ConnectCancellation = other.ConnectCancellation; UserAgent = other.UserAgent; AddressFrom = other.AddressFrom; Nonce = other.Nonce; Advertize = other.Advertize; PreferredTransactionOptions = other.PreferredTransactionOptions; foreach (var behavior in other.TemplateBehaviors) { TemplateBehaviors.Add(behavior.Clone()); } }
internal void DiscoverPeers(ProtocolData network, NodeConnectionParameters parameters, int peerToFind) { //TraceCorrelation traceCorrelation = new TraceCorrelation(NodeServerTrace.Trace, "Discovering nodes"); int found = 0; while (found < peerToFind) { parameters.ConnectCancellation.ThrowIfCancellationRequested(); //NodeServerTrace.PeerTableRemainingPeerToGet(-found + peerToFind); List <NetworkAddress> peers = new List <NetworkAddress>(); peers.AddRange(this.GetAddr()); CancellationTokenSource peerTableFull = new CancellationTokenSource(); CancellationToken loopCancel = CancellationTokenSource.CreateLinkedTokenSource(peerTableFull.Token, parameters.ConnectCancellation).Token; try { Parallel.ForEach(peers, new ParallelOptions() { MaxDegreeOfParallelism = 5, CancellationToken = loopCancel, }, p => { CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var cancelConnection = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, loopCancel); Node n = null; try { var param2 = parameters.Clone(); param2.ConnectCancellation = cancelConnection.Token; var addrman = param2.TemplateBehaviors.Find <AddressManagerBehavior>(); param2.TemplateBehaviors.Clear(); param2.TemplateBehaviors.Add(addrman); n = Node.Connect(network, p.Endpoint, param2); n.VersionHandshake(cancelConnection.Token); n.MessageReceived += (s, a) => { var addr = (a.Message.Payload as AddrPayload); if (addr != null) { Interlocked.Add(ref found, addr.Addresses.Length); if (found >= peerToFind) { peerTableFull.Cancel(); } } }; n.SendMessageAsync(new GetAddrPayload()); loopCancel.WaitHandle.WaitOne(2000); } catch { } finally { if (n != null) { n.DisconnectAsync(); } } if (found >= peerToFind) { peerTableFull.Cancel(); } //else // NodeServerTrace.Information("Need " + (-found + peerToFind) + " more peers"); }); } catch (OperationCanceledException) { if (parameters.ConnectCancellation.IsCancellationRequested) { throw; } } } }