Exemple #1
0
        public void DisconnectOnTooManyPeersTest()
        {
            var node = _nodeFactory.CreateNode("192.1.1.1", 3333);

            ((NetworkConfig)_configurationProvider.GetConfig <NetworkConfig>()).ActivePeersMaxCount = 0;

            //trigger connection initialized
            var p2pSession = new TestP2PSession();

            p2pSession.RemoteNodeId         = node.Id;
            p2pSession.ClientConnectionType = ClientConnectionType.In;
            _localPeer.TriggerConnectionInitialized(p2pSession, ClientConnectionType.In);

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager);
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 1,
                Capabilities = new[] { new Capability(Protocol.Eth, 62) }.ToList()
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            Assert.IsTrue(p2pSession.Disconected);
            Assert.AreEqual(DisconnectReason.TooManyPeers, p2pSession.DisconnectReason);
        }
Exemple #2
0
        public void Pongs_to_ping()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            p2PProtocolHandler.HandleMessage(CreatePacket(PingMessage.Instance));
            _session.Received(1).DeliverMessage(Arg.Any <PongMessage>());
        }
        public void Pongs_to_ping()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            p2PProtocolHandler.HandleMessage(CreatePacket(PingMessage.Instance));
            _session.Received(1).DeliverMessage(Arg.Is <Packet>(p => p.PacketType == P2PMessageCode.Pong));
        }
        private IDictionary <string, Func <ISession, int, IProtocolHandler> > GetProtocolFactories()
        => new Dictionary <string, Func <ISession, int, IProtocolHandler> >
        {
            [Protocol.P2P] = (session, _) =>
            {
                var handler = new P2PProtocolHandler(session, _localPeer.LocalNodeId, _stats, _serializer,
                                                     _perfService, _logManager);
                session.PingSender = handler;
                InitP2PProtocol(session, handler);

                return(handler);
            },
            [Protocol.Eth] = (session, version) =>
            {
                if (version < 62 || version > 63)
                {
                    throw new NotSupportedException($"Eth protocol version {version} is not supported.");
                }

                var handler = version == 62
                        ? new Eth62ProtocolHandler(session, _serializer, _stats, _syncServer, _logManager, _perfService,
                                                   _txPool)
                        : new Eth63ProtocolHandler(session, _serializer, _stats, _syncServer, _logManager, _perfService,
                                                   _txPool);
                InitEthProtocol(session, handler);

                return(handler);
            }
        };
        public void On_init_sends_a_hello_message()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            p2PProtocolHandler.Init();

            _session.Received(1).DeliverMessage(Arg.Is <Packet>(p => p.PacketType == P2PMessageCode.Hello));
        }
Exemple #6
0
        public void On_init_sends_a_hello_message()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            p2PProtocolHandler.Init();

            _session.Received(1).DeliverMessage(Arg.Any <HelloMessage>());
        }
        public void InPeerBecomesActiveAndDisconnectTest()
        {
            var node = _nodeFactory.CreateNode("192.1.1.1", 3333);

            //trigger connection initialized
            var p2pSession = new TestP2PSession();

            p2pSession.RemoteNodeId        = node.Id;
            p2pSession.RemoteHost          = node.Host;
            p2pSession.RemotePort          = node.Port;
            p2pSession.ConnectionDirection = ConnectionDirection.In;
            _localPeer.TriggerSessionCreated(p2pSession);
            p2pSession.TriggerHandshakeComplete();

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager, new PerfService(_logManager));
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 4,
                Capabilities = new[] { new Capability(Protocol.Eth, 62), new Capability(Protocol.Eth, 63) }.ToList()
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            AssertTrue(() => _peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.P2PInitialized), 5000);
            //Assert.IsTrue(_peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.P2PInitialized));

            //trigger eth62 initialization
            var eth62 = new Eth62ProtocolHandler(p2pSession, new MessageSerializationService(), _synchronizationManager, _logManager, new PerfService(_logManager), _blockTree, _transactionPool, _timestamp);
            var args  = new EthProtocolInitializedEventArgs(eth62)
            {
                ChainId = _synchronizationManager.ChainId
            };

            p2pSession.TriggerProtocolInitialized(args);
            AssertTrue(() => _peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.Eth62Initialized), 5000);

            Assert.AreEqual(1, _peerManager.CandidatePeers.Count);
            Assert.AreEqual(1, _peerManager.ActivePeers.Count);
            //Assert.IsTrue(_peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.Eth62Initialized));
            AssertTrue(() => _peerManager.ActivePeers.First().SynchronizationPeer != null, 5000);
            //Assert.NotNull(_peerManager.ActivePeers.First().SynchronizationPeer);

            //verify active peer was added to synch manager
            _synchronizationManager.Received(1).AddPeer(Arg.Any <ISynchronizationPeer>());

            //trigger disconnect
            p2pSession.TriggerPeerDisconnected();
            AssertTrue(() => _peerManager.ActivePeers.Count == 0, 5000);
            Assert.AreEqual(1, _peerManager.CandidatePeers.Count);
            //Assert.AreEqual(0, _peerManager.ActivePeers.Count);

            //verify active peer was removed from synch manager
            _synchronizationManager.Received(1).RemovePeer(Arg.Any <ISynchronizationPeer>());
        }
Exemple #8
0
        public void On_init_sends_a_hello_message_with_capabilities()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            p2PProtocolHandler.AddSupportedCapability(new Capability(Protocol.Wit, 0));
            p2PProtocolHandler.Init();

            string[] expectedCapabilities = { "eth62", "eth63", "eth64", "eth65", "wit0" };
            _session.Received(1).DeliverMessage(
                Arg.Is <HelloMessage>(m => m.Capabilities.Select(c => c.ToString()).SequenceEqual(expectedCapabilities)));
        }
Exemple #9
0
        public void DisconnectOnAlreadyConnectedTest()
        {
            var p2pSession = InitializeNode(ClientConnectionType.In);

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager);
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 1,
                Capabilities = new[] { new Capability(Protocol.Eth, 62) }.ToList()
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            Assert.IsTrue(p2pSession.Disconected);
            Assert.AreEqual(DisconnectReason.AlreadyConnected, p2pSession.DisconnectReason);
        }
Exemple #10
0
        public void DisconnectOnNoEth62SupportTest()
        {
            var p2pSession = InitializeNode();

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager, new PerfService(_logManager));
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 5,
                Capabilities = new[] { new Capability(Protocol.Eth, 60) }.ToList()
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            Assert.IsTrue(p2pSession.Disconected);
            Assert.AreEqual(DisconnectReason.Other, p2pSession.DisconnectReason);
        }
        public void DisconnectOnWrongP2PVersionTest()
        {
            var p2pSession = InitializeNode();

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager, new PerfService(_logManager));
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 1,
                Capabilities = new[] { new Capability(Protocol.Eth, 62), new Capability(Protocol.Eth, 63) }.ToList()
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            AssertTrue(() => p2pSession.Disconected, 5000);
            //Assert.IsTrue(p2pSession.Disconected);
            Assert.AreEqual(DisconnectReason.IncompatibleP2PVersion, p2pSession.DisconnectReason);
        }
        private void InitP2PProtocol(ISession session, P2PProtocolHandler handler)
        {
            handler.ProtocolInitialized += (sender, args) =>
            {
                P2PProtocolInitializedEventArgs typedArgs = (P2PProtocolInitializedEventArgs)args;
                if (!RunBasicChecks(session, Protocol.P2P, handler.ProtocolVersion))
                {
                    return;
                }

                if (handler.ProtocolVersion >= 5)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"{handler.ProtocolCode}.{handler.ProtocolVersion} established on {session} - enabling snappy");
                    }
                    session.EnableSnappy();
                }
                else
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"{handler.ProtocolCode}.{handler.ProtocolVersion} established on {session} - disabling snappy");
                    }
                }

                _stats.ReportP2PInitializationEvent(session.Node, new P2PNodeDetails
                {
                    ClientId     = typedArgs.ClientId,
                    Capabilities = typedArgs.Capabilities.ToArray(),
                    P2PVersion   = typedArgs.P2PVersion,
                    ListenPort   = typedArgs.ListenPort
                });

                AddNodeToDiscovery(session, typedArgs);

                _protocolValidator.DisconnectOnInvalid(Protocol.P2P, session, args);

                if (_logger.IsTrace)
                {
                    _logger.Trace($"Finalized P2P protocol initialization on {session}");
                }
                P2PProtocolInitialized?.Invoke(this, typedArgs);
            };
        }
Exemple #13
0
        private void InitProtocol(ISession session, string protocolCode, int version)
        {
            if (session.State < SessionState.Initialized)
            {
                throw new InvalidOperationException($"{nameof(InitProtocol)} called on {session}");
            }

            if (session.State != SessionState.Initialized)
            {
                return;
            }

            protocolCode = protocolCode.ToLowerInvariant();
            IProtocolHandler protocolHandler;

            switch (protocolCode)
            {
            case Protocol.P2P:
                P2PProtocolHandler handler = new P2PProtocolHandler(session, _localPeer.LocalNodeId, _stats, _serializer, _perfService, _logManager);
                session.PingSender = handler;
                InitP2PProtocol(session, handler);
                protocolHandler = handler;
                break;

            case Protocol.Eth:
                if (version < 62 || version > 63)
                {
                    throw new NotSupportedException($"Eth protocol version {version} is not supported.");
                }

                Eth62ProtocolHandler ethHandler = version == 62
                        ? new Eth62ProtocolHandler(session, _serializer, _stats, _syncManager, _logManager, _perfService, _transactionPool)
                        : new Eth63ProtocolHandler(session, _serializer, _stats, _syncManager, _logManager, _perfService, _transactionPool);
                InitEthProtocol(session, ethHandler);
                protocolHandler = ethHandler;
                break;

            default:
                throw new NotSupportedException($"Protocol {protocolCode} {version} is not supported");
            }

            protocolHandler.SubprotocolRequested += (sender, args) => InitProtocol(session, args.ProtocolCode, args.Version);
            session.AddProtocolHandler(protocolHandler);
            protocolHandler.Init();
        }
Exemple #14
0
        public void OurPeerBecomesActiveAndDisconnectTest()
        {
            var p2pSession = InitializeNode();

            //trigger p2p initialization
            var p2pProtocol = new P2PProtocolHandler(p2pSession, new MessageSerializationService(), p2pSession.RemoteNodeId, p2pSession.RemotePort ?? 0, _logManager, new PerfService(_logManager));
            var p2pArgs     = new P2PProtocolInitializedEventArgs(p2pProtocol)
            {
                P2PVersion   = 4,
                Capabilities = new[] { new Capability(Protocol.Eth, 62) }.ToList(),
            };

            p2pSession.TriggerProtocolInitialized(p2pArgs);
            Assert.IsTrue(_peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.P2PInitialized));

            //trigger eth62 initialization
            var eth62 = new Eth62ProtocolHandler(p2pSession, new MessageSerializationService(), _synchronizationManager, _logManager, new PerfService(_logManager));
            var args  = new Eth62ProtocolInitializedEventArgs(eth62)
            {
                ChainId = _synchronizationManager.ChainId
            };

            p2pSession.TriggerProtocolInitialized(args);
            Assert.IsTrue(_peerManager.ActivePeers.First().NodeStats.DidEventHappen(NodeStatsEventType.Eth62Initialized));
            Assert.NotNull(_peerManager.ActivePeers.First().SynchronizationPeer);

            //verify active peer was added to synch manager
            _synchronizationManager.Received(1).AddPeer(Arg.Any <ISynchronizationPeer>());

            //trigger disconnect
            p2pSession.TriggerPeerDisconnected();
            Assert.AreEqual(1, _peerManager.CandidatePeers.Count);
            Assert.AreEqual(0, _peerManager.ActivePeers.Count);

            //verify active peer was removed from synch manager
            _synchronizationManager.Received(1).RemovePeer(Arg.Any <ISynchronizationPeer>());
        }
        public void Sets_local_node_id_from_constructor()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            Assert.AreEqual(p2PProtocolHandler.LocalNodeId, NetTestVectors.StaticKeyA.PublicKey);
        }
Exemple #16
0
        public void Sets_local_node_id_from_constructor()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            Assert.AreEqual(p2PProtocolHandler.LocalNodeId, TestItem.PublicKeyA);
        }
Exemple #17
0
        private async Task <bool> ProcessIncomingConnection(IP2PSession session, P2PProtocolHandler protocolHandler)
        {
            //if we have already initiated connection before
            if (_activePeers.ContainsKey(session.RemoteNodeId))
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Initiating disconnect, node is already connected: {session.RemoteNodeId}");
                }
                await session.InitiateDisconnectAsync(DisconnectReason.AlreadyConnected);

                return(false);
            }

            //if we have too many acive peers
            if (_activePeers.Count >= _configurationProvider.ActivePeersMaxCount)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Initiating disconnect, we have too many peers: {session.RemoteNodeId}");
                }
                await session.InitiateDisconnectAsync(DisconnectReason.TooManyPeers);

                return(false);
            }

            //it is possible we already have this node as a candidate
            if (_candidatePeers.TryGetValue(session.RemoteNodeId, out var peer))
            {
                peer.Session              = session;
                peer.P2PMessageSender     = protocolHandler;
                peer.ClientConnectionType = session.ClientConnectionType;
            }
            else
            {
                peer = new Peer(_nodeFactory.CreateNode(session.RemoteNodeId, session.RemoteHost, session.RemotePort ?? 0), _nodeStatsProvider.GetNodeStats(session.RemoteNodeId))
                {
                    ClientConnectionType = session.ClientConnectionType,
                    Session          = session,
                    P2PMessageSender = protocolHandler
                };
            }

            if (_activePeers.TryAdd(session.RemoteNodeId, peer))
            {
                //add subsripton for disconnect for new active peer
                //peer.Session.PeerDisconnected += async (s, e) => await OnPeerDisconnected(s, e);

                //we also add this node to candidates for future connection (if we dont have it yet)
                _candidatePeers.TryAdd(session.RemoteNodeId, peer);

                if (_isDiscoveryEnabled && peer.NodeLifecycleManager == null)
                {
                    //In case peer was initiated outside of discovery and discovery is enabled, we are adding it to discovery for future use
                    var manager = _discoveryManager.GetNodeLifecycleManager(peer.Node);
                    peer.NodeLifecycleManager = manager;
                }

                return(true);
            }

            //if we have already initiated connection before (threding safeguard - it means another thread added this node to active collection after our contains key key check above)
            if (_logger.IsInfoEnabled)
            {
                _logger.Info($"Initiating disconnect, node is already connected: {session.RemoteNodeId}");
            }
            await session.InitiateDisconnectAsync(DisconnectReason.AlreadyConnected);

            return(false);
        }
Exemple #18
0
        public void Sets_port_from_constructor()
        {
            P2PProtocolHandler p2PProtocolHandler = CreateSession();

            Assert.AreEqual(ListenPort, p2PProtocolHandler.ListenPort);
        }