/// <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"); } }
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); }
public NodeListener(NodeSet parent) { _Parent = parent; }