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);
        }
Beispiel #2
0
 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");
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 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;
            }
        }
Beispiel #6
0
 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
             }
         }
         ;
     }
 }
Beispiel #7
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #12
0
        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");
        }
Beispiel #13
0
 private void OnDisconnected()
 {
     if (Disconnected != null)
     {
         try
         {
             Disconnected(this);
         }
         catch (Exception ex)
         {
             TraceCorrelation.LogInside(() => NodeServerTrace.Error("Error while Disconnected event raised", ex));
         }
     }
 }
Beispiel #14
0
 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));
         }
     }
 }
Beispiel #15
0
        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);
        }
Beispiel #16
0
 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;
         }
     }
 }
Beispiel #17
0
 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);
         }
     }
 }
Beispiel #18
0
 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();
 }
Beispiel #19
0
        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"));
        }
Beispiel #20
0
 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);
         }
     }
 }
Beispiel #21
0
 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();
     }
 }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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";
            }
        }
Beispiel #25
0
 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);
 }
Beispiel #26
0
 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);
     }
 }
Beispiel #27
0
        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);
            }
        }
Beispiel #28
0
        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);
        }
Beispiel #29
0
        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);
        }
Beispiel #30
0
        /// <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;
                }
            }
        }
Beispiel #31
0
        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));
                    }
                }
            }
        }
Beispiel #32
0
        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));
                    }
                }
            }
        }
Beispiel #33
0
		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;
 }
Beispiel #35
0
		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;
					}
				}
			}
		}
Beispiel #36
0
        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;
        }
Beispiel #37
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 #38
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 #39
0
 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);
     }
 }