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());
     }
 }
Пример #2
0
        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;
                    }
                }
            }
        }