Beispiel #1
0
        /// <summary>
        /// Fill the PeerTable with fresh addresses
        /// </summary>
        public void DiscoverPeers(int peerToFind = 990)
        {
            TraceCorrelation traceCorrelation = new TraceCorrelation(NodeServerTrace.Trace, "Discovering nodes");
            List <Task>      tasks            = new List <Task>();

            using (traceCorrelation.Open())
            {
                while (CountPeerRequired(peerToFind) != 0)
                {
                    NodeServerTrace.PeerTableRemainingPeerToGet(CountPeerRequired(peerToFind));
                    CancellationTokenSource cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(40));
                    var peers = PeerTable.GetActivePeers(1000);
                    if (peers.Length == 0)
                    {
                        PopulateTableWithDNSNodes();
                        PopulateTableWithHardNodes();
                        peers = PeerTable.GetActivePeers(1000);
                    }


                    CancellationTokenSource peerTableFull = new CancellationTokenSource();
                    NodeSet connected = new NodeSet();
                    try
                    {
                        Parallel.ForEach(peers, new ParallelOptions()
                        {
                            MaxDegreeOfParallelism = 5,
                            CancellationToken      = peerTableFull.Token,
                        }, p =>
                        {
                            Node n = null;
                            try
                            {
                                n = GetNodeByPeer(p, cancellation.Token);
                                if (n.State < NodeState.HandShaked)
                                {
                                    connected.AddNode(n);
                                    n.VersionHandshake(cancellation.Token);
                                }
                                n.SendMessage(new GetAddrPayload());
                                Thread.Sleep(2000);
                            }
                            catch (Exception)
                            {
                                if (n != null)
                                {
                                    n.Disconnect();
                                }
                            }
                            if (CountPeerRequired(peerToFind) == 0)
                            {
                                peerTableFull.Cancel();
                            }
                            else
                            {
                                NodeServerTrace.Information("Need " + CountPeerRequired(peerToFind) + " more peers");
                            }
                        });
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    finally
                    {
                        connected.DisconnectAll();
                    }
                }
                NodeServerTrace.Trace.TraceInformation("Peer table is now full");
            }
        }
Beispiel #2
0
        public NodeSet CreateNodeSet(int size)
        {
            if (size > 1000)
            {
                throw new ArgumentOutOfRangeException("size", "size should be less than 1000");
            }
            TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Creating node set of size " + size);
            NodeSet          set   = new NodeSet();

            using (trace.Open())
            {
                while (set.Count() < size)
                {
                    var peerToGet   = size - set.Count();
                    var activePeers = PeerTable.GetActivePeers(1000);
                    activePeers = activePeers.Where(p => !set.Contains(p.NetworkAddress.Endpoint)).ToArray();
                    if (activePeers.Length < peerToGet)
                    {
                        DiscoverPeers(size);
                        continue;
                    }
                    NodeServerTrace.Information("Need " + peerToGet + " more nodes");

                    BlockingCollection <Node> handshakedNodes = new BlockingCollection <Node>(peerToGet);
                    CancellationTokenSource   handshakedFull  = new CancellationTokenSource();

                    try
                    {
                        Parallel.ForEach(activePeers,
                                         new ParallelOptions()
                        {
                            MaxDegreeOfParallelism = 10,
                            CancellationToken      = handshakedFull.Token
                        }, p =>
                        {
                            if (set.Contains(p.NetworkAddress.Endpoint))
                            {
                                return;
                            }
                            Node node = null;
                            try
                            {
                                node = GetNodeByPeer(p, handshakedFull.Token);
                                node.VersionHandshake(handshakedFull.Token);
                                if (node != null && node.State != NodeState.HandShaked)
                                {
                                    node.Disconnect();
                                }
                                if (!handshakedNodes.TryAdd(node))
                                {
                                    handshakedFull.Cancel();
                                    node.Disconnect();
                                }
                                else
                                {
                                    var remaining = (size - set.Count() - handshakedNodes.Count);
                                    if (remaining == 0)
                                    {
                                        handshakedFull.Cancel();
                                    }
                                    else
                                    {
                                        NodeServerTrace.Information("Need " + remaining + " more nodes");
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                if (node != null)
                                {
                                    node.Disconnect();
                                }
                            }
                        });
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    set.AddNodes(handshakedNodes.ToArray());
                }
            }
            return(set);
        }
Beispiel #3
0
 public NodeListener(NodeSet parent)
 {
     _Parent = parent;
 }