public NodeServer(Network network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { this.AllowLocalPeers = true; this.InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; this.localEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); this.MaxConnections = 125; this.Network = network; this.externalEndpoint = new IPEndPoint(this.localEndpoint.Address, this.Network.DefaultPort); this.Version = version; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); this.messageProducer.AddMessageListener(listener); this.OwnResource(listener); this.ConnectedNodes = new NodesCollection(); this.ConnectedNodes.Added += Nodes_NodeAdded; this.ConnectedNodes.Removed += Nodes_NodeRemoved; this.ConnectedNodes.MessageProducer.AddMessageListener(listener); this.AllMessages = new MessageProducer <IncomingMessage>(); this.trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + this.LocalEndpoint); }
public UPnPLease(int[] bitcoinPorts, int internalPort, string ruleName) { RuleName = ruleName; _BitcoinPorts = bitcoinPorts; _InternalPort = internalPort; Trace = new TraceCorrelation(NodeServerTrace.Trace, "UPNP external address and port detection"); }
/// <summary> /// Initializes instance of a network peer server. /// </summary> /// <param name="network">Specification of the network the node runs on - regtest/testnet/mainnet.</param> /// <param name="version">Version of the network protocol that the server should run.</param> /// <param name="internalPort">Port on which the server will listen, or -1 to use the default port for the selected network.</param> /// <param name="dateTimeProvider">Provider of time functions.</param> /// <param name="loggerFactory">Factory for creating loggers.</param> /// <param name="networkPeerFactory">Factory for creating P2P network peers.</param> public NetworkPeerServer(Network network, ProtocolVersion version, int internalPort, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, INetworkPeerFactory networkPeerFactory) { internalPort = internalPort == -1 ? network.DefaultPort : internalPort; this.logger = loggerFactory.CreateLogger(this.GetType().FullName, $"[{internalPort}] "); this.dateTimeProvider = dateTimeProvider; this.networkPeerFactory = networkPeerFactory; this.AllowLocalPeers = true; this.InboundNetworkPeerConnectionParameters = new NetworkPeerConnectionParameters(); this.localEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); this.MaxConnections = 125; this.Network = network; this.externalEndpoint = new IPEndPoint(this.localEndpoint.Address, this.Network.DefaultPort); this.Version = version; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); this.messageProducer.AddMessageListener(listener); this.OwnResource(listener); this.ConnectedNetworkPeers = new NetworkPeerCollection(); this.ConnectedNetworkPeers.Added += Peers_PeerAdded; this.ConnectedNetworkPeers.Removed += Peers_PeerRemoved; this.ConnectedNetworkPeers.MessageProducer.AddMessageListener(listener); this.AllMessages = new MessageProducer <IncomingMessage>(); this.trace = new TraceCorrelation(NodeServerTrace.Trace, "Network peer server listening on " + this.LocalEndpoint); }
public UPnPLease(int[] bitcoinPorts, int internalPort, string ruleName) { RuleName = ruleName; _BitcoinPorts = bitcoinPorts; _InternalPort = internalPort; Trace = new TraceCorrelation(NodeServerTrace.Trace, "UPNP external address and port detection"); }
public async Task <string> Service1Method1(string param1) { try { var x = 1; var y = 0; if (y == 0) { return((x / y).ToString()); } var correlationId = TraceCorrelation.GetCurrentActivityId(); ServiceEventSource.Current.ServiceRequestStart("Service1Method1", correlationId); ServiceEventSource.Current.ServiceRequestStart1(correlationId, "Service1Method1"); var proxy = _statelessService2ProxyFactory.CreateSingletonServiceProxy(); var result = await proxy.Service2Method1(param1); ServiceEventSource.Current.ServiceRequestStop("Service1Method1", correlationId); return(result); } catch (Exception e) { Console.WriteLine(e); throw; } }
public void DisconnectAsync(string reason, Exception exception = null) { if (!IsConnected) { return; } if (Interlocked.CompareExchange(ref _Disconnecting, 1, 0) == 1) { return; } using (TraceCorrelation.Open()) { NodeServerTrace.Information("Disconnection request " + reason); State = NodeState.Disconnecting; _Connection.Cancel.Cancel(); if (DisconnectReason == null) { DisconnectReason = new NodeDisconnectReason() { Reason = reason, Exception = exception } } ; } }
public void VersionHandshake(CancellationToken cancellationToken = default(CancellationToken)) { using (var listener = CreateListener() .Where(p => p.Message.Payload is VersionPayload || p.Message.Payload is RejectPayload || p.Message.Payload is VerAckPayload)) { using (TraceCorrelation.Open()) { SendMessage(MyVersion); var payload = listener.ReceivePayload <Payload>(cancellationToken); if (payload is RejectPayload) { throw new InvalidOperationException("Handshake rejected : " + ((RejectPayload)payload).Reason); } var version = (VersionPayload)payload; _PeerVersion = version; Version = version.Version; if (!version.AddressReceiver.Address.Equals(MyVersion.AddressFrom.Address)) { NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReceiver.Address + " instead of " + MyVersion.AddressFrom.Address); } if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION) { NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting"); Disconnect(); return; } SendMessage(new VerAckPayload()); listener.ReceivePayload <VerAckPayload>(cancellationToken); State = NodeState.HandShaked; } } }
internal static TraceCorrelation NewCorrelation(string activityName) { var correlation = new TraceCorrelation(_Trace, activityName); _Trace.TraceInformation(activityName); return(correlation); }
public Chain BuildChain(Chain chain, CancellationToken cancellationToken = default(CancellationToken)) { AssertState(NodeState.HandShaked, cancellationToken); using (TraceCorrelation.Open()) { NodeServerTrace.Information("Building chain"); if (FullVersion.StartHeight <= chain.Height) { NodeServerTrace.Information("Local chain already ahead"); return(chain); } while (chain.Height < FullVersion.StartHeight) { NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + FullVersion.StartHeight); SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); var headers = this.RecieveMessage <HeadersPayload>(cancellationToken); foreach (var header in headers.Headers) { var prev = chain.GetBlock(header.HashPrevBlock); if (prev == null || prev.Height != chain.Height) { NodeServerTrace.Error("Block Header received out of order " + header.GetHash(), null); throw new InvalidOperationException("Block Header received out of order"); } var chained = chain.CreateChainedBlock(header); chain.SetTip(chained); } } } return(chain); }
public async Task <string> Service2Method1(string param1) { var correlationId = TraceCorrelation.GetCurrentActivityId(); ServiceEventSource.Current.ServiceRequestStart("Service2 Method1 - Start; PARAM1: " + param1 + "; " + correlationId, correlationId); await Service2PrivateMethod1(); ServiceEventSource.Current.ServiceRequestStop("Service2 Method1 - End; PARAM1: " + param1 + "; " + correlationId, correlationId); return("Result from Service 2, Method 1"); }
public TK DoAction <T, TK>(T input) { var result = default(TK); var correlationId = TraceCorrelation.GetCurrentActivityId(); ServiceEventSource.Current.ServiceRequestStart("Handler1 - Start; " + correlationId, correlationId); Thread.Sleep(1000); ServiceEventSource.Current.ServiceRequestStop("Handler1 - Stop; " + correlationId, correlationId); return(result); }
private async Task <string> Service2PrivateMethod1() { var correlationId = TraceCorrelation.GetCurrentActivityId(); ServiceEventSource.Current.ServiceRequestStart("Service2 Private Method1 - Start" + correlationId, correlationId); Thread.Sleep(2000); var result = Task.Run( () => _commandContext.DoAction <int, bool>("Handler1", 5)); ServiceEventSource.Current.ServiceRequestStop("Service2 Private Method1 - End;" + correlationId, correlationId); return("Result from Service 2, Method 1"); }
private void OnDisconnected() { if (Disconnected != null) { try { Disconnected(this); } catch (Exception ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while Disconnected event raised", ex)); } } }
private void OnStateChanged(NodeState previous) { if (StateChanged != null) { try { StateChanged(this, previous); } catch (Exception ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while Disconnected event raised", ex)); } } }
protected void OnMessageReceived(IncomingMessage message) { message.IfPayloadIs <VersionPayload>(version => { if (State == NodeState.HandShaked) { if (message.Node.Version >= ProtocolVersion.REJECT_VERSION) { message.Node.SendMessageAsync(new RejectPayload() { Code = RejectCode.DUPLICATE }); } } }); //if(version != null) //{ // if((version.Services & NodeServices.NODE_WITNESS) != 0) // _SupportedTransactionOptions |= TransactionOptions.Witness; //} //var havewitness = message.Message.Payload as HaveWitnessPayload; //if(havewitness != null) // _SupportedTransactionOptions |= TransactionOptions.Witness; var last = new ActionFilter((m, n) => { MessageProducer.PushMessage(m); var messageReceived = MessageReceived; if (messageReceived != null) { foreach (var handler in messageReceived.GetInvocationList().Cast <NodeEventMessageIncoming>()) { try { handler.DynamicInvoke(this, m); } catch (TargetInvocationException ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while OnMessageReceived event raised", ex.InnerException), false); } } } }); var enumerator = Filters.Concat(new[] { last }).GetEnumerator(); FireFilters(enumerator, message); }
public void RespondToHandShake(CancellationToken cancellation = default(CancellationToken)) { using (TraceCorrelation.Open()) { var listener = new PollMessageListener <IncomingMessage>(); using (MessageProducer.AddMessageListener(listener)) { NodeServerTrace.Information("Responding to handshake"); SendMessage(MyVersion); listener.ReceiveMessage().AssertPayload <VerAckPayload>(); SendMessage(new VerAckPayload()); _State = NodeState.HandShaked; } } }
private void FireFilters(IEnumerator <INodeFilter> enumerator, IncomingMessage message) { if (enumerator.MoveNext()) { var filter = enumerator.Current; try { filter.OnReceivingMessage(message, () => FireFilters(enumerator, message)); } catch (Exception ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Unhandled exception raised by a node filter (OnReceivingMessage)", ex.InnerException), false); } } }
internal Node(Peer peer, NodeServer nodeServer, Socket socket, VersionPayload version) { _Peer = peer; _NodeServer = nodeServer; _Connection = new NodeConnection(this, socket); _FullVersion = version; Version = version.Version; LastSeen = peer.NetworkAddress.Time; TraceCorrelation.LogInside(() => { NodeServerTrace.Information("Connected to advertised node " + _Peer.NetworkAddress.Endpoint); State = NodeState.Connected; }); _Connection.BeginListen(); }
public async Task <IHttpActionResult> MethodQueue(string param1) { var correlationId = TraceCorrelation.RetrieveCorrelationInfo(); var absoluteUrl = Request?.RequestUri?.AbsoluteUri; //var requestTypeToLog = absoluteUrl + "; Param1: " + param1 +"; " + correlationId; WebApiEventSource.Current.ServiceRequestStart(absoluteUrl, correlationId, "One"); var serviceProxy = _queueProxy.CreateSingletonServiceProxy(); await serviceProxy.StartScheduledMaterializedViewProcessing(param1); WebApiEventSource.Current.ServiceRequestStop(absoluteUrl, correlationId); return(Ok("Return from API method 1")); }
private void FireFilters(IEnumerator <INodeFilter> enumerator, Object payload) { if (enumerator.MoveNext()) { var filter = enumerator.Current; try { filter.OnSendingMessage(this, payload, () => FireFilters(enumerator, payload)); } catch (Exception ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Unhandled exception raised by a node filter (OnSendingMessage)", ex.InnerException), false); } } }
public void Disconnect() { if (State < NodeState.Connected) { _Connection.Disconnected.WaitOne(); return; } using (TraceCorrelation.Open()) { NodeServerTrace.Information("Disconnection request"); State = NodeState.Disconnecting; _Connection.Cancel.Cancel(); _Connection.Disconnected.WaitOne(); } }
public Chain BuildChain(ObjectStream <ChainChange> changes = null, CancellationToken cancellationToken = default(CancellationToken)) { if (changes == null) { changes = new StreamObjectStream <ChainChange>(); } var chain = new Chain(Network, changes); TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Build chain"); using (trace.Open()) { using (var pool = CreateNodeSet(3)) { int height = pool.GetNodes().Max(o => o.FullVersion.StartHeight); var listener = new PollMessageListener <IncomingMessage>(); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); using (pool.MessageProducer.AddMessageListener(listener)) { while (chain.Height != height) { var before = chain.Tip; var headers = listener.RecieveMessage(cancellationToken).Message.Payload as HeadersPayload; if (headers != null) { foreach (var header in headers.Headers) { chain.GetOrAdd(header); } if (before.HashBlock != chain.Tip.HashBlock) { NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + height); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); } } } } } } return(chain); }
public IEnumerable <Block> GetBlocks(IEnumerable <uint256> neededBlocks, CancellationToken cancellationToken = default(CancellationToken)) { AssertState(NodeState.HandShaked, cancellationToken); using (TraceCorrelation.Open()) { NodeServerTrace.Information("Downloading blocks"); int simultaneous = 70; PerformanceSnapshot lastSpeed = null; using (var listener = CreateListener() .OfType <BlockPayload>()) { foreach (var invs in neededBlocks .Select(b => new InventoryVector() { Type = InventoryType.MSG_BLOCK, Hash = b }) .Partition(simultaneous)) { NodeServerTrace.Information("Speed " + lastSpeed); var begin = Counter.Snapshot(); var invsByHash = invs.ToDictionary(k => k.Hash); this.SendMessage(new GetDataPayload(invs.ToArray())); Block[] downloadedBlocks = new Block[invs.Count]; while (invsByHash.Count != 0) { var block = listener.ReceivePayload <BlockPayload>(cancellationToken).Object; var thisHash = block.GetHash(); if (invsByHash.ContainsKey(thisHash)) { downloadedBlocks[invs.IndexOf(invsByHash[thisHash])] = block; invsByHash.Remove(thisHash); } } var end = Counter.Snapshot(); lastSpeed = end - begin; foreach (var downloadedBlock in downloadedBlocks) { yield return(downloadedBlock); } } } } }
/// <summary> /// Handles the exception /// </summary> /// <param name="context"></param> public override void Handle(ExceptionHandlerContext context) { var exception = context.Exception; if (context.Handle(exception)) { return; } var correlationId = TraceCorrelation.RetrieveCorrelationInfo(); if (exception.InnerException != null) { var errorMessage = exception.InnerException.Message; var stackTrace = exception.InnerException.StackTrace ?? "No stack trace available"; } }
public NodeServer(Network network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AdvertizeMyself = true; internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6(), internalPort); _Network = network; _ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); _Version = version; var listener = new EventLoopMessageListener<IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); RegisterPeerTableRepository(_PeerTable); _Nodes = new NodeSet(); _Nodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
public bool AdvertiseMyself() { if (NodeServer.IsListening && NodeServer.ExternalEndpoint.Address.IsRoutable(NodeServer.AllowLocalPeers)) { TraceCorrelation.LogInside(() => NodeServerTrace.Information("Advertizing myself")); SendMessage(new AddrPayload(new NetworkAddress() { Ago = TimeSpan.FromSeconds(0), Endpoint = NodeServer.ExternalEndpoint })); return(true); } else { return(false); } }
void ProcessMessage(IncomingMessage message) { AllMessages.PushMessage(message); TraceCorrelation trace = null; if (message.Node != null) { trace = message.Node.TraceCorrelation; } else { trace = new TraceCorrelation(NodeServerTrace.Trace, "Processing inbound message " + message.Message); } using (trace.Open(false)) { ProcessMessageCore(message); } }
public NodeServer(Network network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AdvertizeMyself = false; internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6(), internalPort); _Network = network; _ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); _Version = version; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); RegisterPeerTableRepository(_PeerTable); _Nodes = new NodeSet(); _Nodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
public NodeServer(NetworkInfo network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AllowLocalPeers = true; InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); _Network = network; //_ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); //TODO _Version = version; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); _ConnectedNodes = new NodesCollection(); _ConnectedNodes.Added += _Nodes_NodeAdded; _ConnectedNodes.Removed += _Nodes_NodeRemoved; _ConnectedNodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
/// <summary> /// /// </summary> /// <param name="cancellation"></param> public void RespondToHandShake(CancellationToken cancellation = default(CancellationToken)) { using (TraceCorrelation.Open()) { using (var list = CreateListener().Where(m => m.IsPayloadTypeOf(typeof(VerAckPayload), typeof(RejectPayload)))) { NodeServerTrace.Information("Responding to handshake"); SendMessageAsync(MyVersion); var message = list.ReceiveMessage(cancellation); message.IfPayloadIs <RejectPayload>(reject => { throw new ProtocolException("Version rejected " + reject.Code + " : " + reject.Reason); }); SendMessageAsync(new VerAckPayload()); State = NodeState.HandShaked; } } }
private void OnStateChanged(NodeState previous) { var stateChanged = StateChanged; if (stateChanged != null) { foreach (var handler in stateChanged.GetInvocationList().Cast <NodeStateEventHandler>()) { try { handler.DynamicInvoke(this, previous); } catch (TargetInvocationException ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while StateChanged event raised", ex.InnerException)); } } } }
private void OnDisconnected() { var disconnected = Disconnected; if (disconnected != null) { foreach (var handler in disconnected.GetInvocationList().Cast <NodeEventHandler>()) { try { handler.DynamicInvoke(this); } catch (TargetInvocationException ex) { TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while Disconnected event raised", ex.InnerException)); } } } }
public NodeServer(Network network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AllowLocalPeers = true; InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); _Network = network; _ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); _Version = version; var listener = new EventLoopMessageListener<IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); _ConnectedNodes = new NodesCollection(); _ConnectedNodes.Added += _Nodes_NodeAdded; _ConnectedNodes.Removed += _Nodes_NodeRemoved; _ConnectedNodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
internal static TraceCorrelation NewCorrelation(string activityName) { var correlation = new TraceCorrelation(_Trace, activityName); _Trace.TraceInformation(activityName); return correlation; }
internal void DiscoverPeers(Network network, NodeConnectionParameters parameters) { int peerToFind = 1000; TraceCorrelation traceCorrelation = new TraceCorrelation(NodeServerTrace.Trace, "Discovering nodes"); int found = 0; using(traceCorrelation.Open()) { while(found < peerToFind) { parameters.ConnectCancellation.ThrowIfCancellationRequested(); NodeServerTrace.PeerTableRemainingPeerToGet(-found + peerToFind); List<NetworkAddress> peers = new List<NetworkAddress>(); peers.AddRange(this.GetAddr()); if(peers.Count == 0) { PopulateTableWithDNSNodes(network, peers); PopulateTableWithHardNodes(network, peers); peers = new List<NetworkAddress>(peers.OrderBy(a => RandomUtils.GetInt32())); } 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; } } } }
public Chain BuildChain(ObjectStream<ChainChange> changes = null, CancellationToken cancellationToken = default(CancellationToken)) { if(changes == null) changes = new StreamObjectStream<ChainChange>(); var chain = new Chain(Network, changes); TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Build chain"); using(trace.Open()) { using(var pool = CreateNodeSet(3)) { int height = pool.GetNodes().Max(o => o.FullVersion.StartHeight); var listener = new PollMessageListener<IncomingMessage>(); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); using(pool.MessageProducer.AddMessageListener(listener)) { while(chain.Height != height) { var before = chain.Tip; var headers = listener.RecieveMessage(cancellationToken).Message.Payload as HeadersPayload; if(headers != null) { foreach(var header in headers.Headers) { chain.GetOrAdd(header); } if(before.HashBlock != chain.Tip.HashBlock) { NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + height); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); } } } } } } return chain; }
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; }
/// <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"); } }
void ProcessMessage(IncomingMessage message) { AllMessages.PushMessage(message); TraceCorrelation trace = null; if(message.Node != null) { trace = message.Node.TraceCorrelation; } else { trace = new TraceCorrelation(NodeServerTrace.Trace, "Processing inbound message " + message.Message); } using(trace.Open(false)) { ProcessMessageCore(message); } }