示例#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);
        }
示例#2
0
        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>());
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
            };
        }
示例#7
0
        /// <summary>
        /// In case of IN connection we don't know what is the port node is listening on until we receive the Hello message
        /// </summary>
        private void AddNodeToDiscovery(ISession session, P2PProtocolInitializedEventArgs eventArgs)
        {
            if (eventArgs.ListenPort == 0)
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Listen port is 0, node is not listening: {session}");
                }
                return;
            }

            if (session.Node.Port != eventArgs.ListenPort)
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Updating listen port for {session:s} to: {eventArgs.ListenPort}");
                }

                if (session.Node.AddedToDiscovery)
                {
                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"Discovery node already initialized with wrong port {session} - listen port: {eventArgs.ListenPort}");
                    }
                }

                session.Node.Port = eventArgs.ListenPort;
            }

            if (session.Node.AddedToDiscovery)
            {
                return;
            }

            //In case peer was initiated outside of discovery and discovery is enabled, we are adding it to discovery for future use (e.g. trusted peer)
            _discoveryApp.AddNodeToDiscovery(session.Node);
            session.Node.AddedToDiscovery = true;
        }
示例#8
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>());
        }
示例#9
0
        public bool DisconnectOnInvalid(string protocol, ISession session, ProtocolInitializedEventArgs eventArgs)
        {
            switch (protocol)
            {
            case Protocol.P2P:
                P2PProtocolInitializedEventArgs args = (P2PProtocolInitializedEventArgs)eventArgs;
                if (!ValidateP2PVersion(args.P2PVersion))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, incorrect P2PVersion: {args.P2PVersion}");
                    }
                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.P2PVersion);
                    Disconnect(session, DisconnectReason.IncompatibleP2PVersion, $"p2p.{args.P2PVersion}");
                    if (session.Node.IsStatic && _logger.IsWarn)
                    {
                        _logger.Warn($"Disconnected an invalid static node: {session.Node.Host}:{session.Node.Port}, reason: {DisconnectReason.IncompatibleP2PVersion}");
                    }
                    return(false);
                }

                if (!ValidateCapabilities(args.Capabilities))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, no Eth62 capability, supported capabilities: [{string.Join(",", args.Capabilities.Select(x => $"{x.ProtocolCode}v{x.Version}"))}]");
                    }
                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.Capabilities);
                    Disconnect(session, DisconnectReason.UselessPeer, "capabilities");
                    if (session.Node.IsStatic && _logger.IsWarn)
                    {
                        _logger.Warn($"Disconnected an invalid static node: {session.Node.Host}:{session.Node.Port}, reason: {DisconnectReason.UselessPeer} (capabilities)");
                    }
                    return(false);
                }

                break;

            case Protocol.Eth:
            case Protocol.Les:
                SyncPeerProtocolInitializedEventArgs syncPeerArgs = (SyncPeerProtocolInitializedEventArgs)eventArgs;
                if (!ValidateChainId(syncPeerArgs.ChainId))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, different chainId: {ChainId.GetChainName((int) syncPeerArgs.ChainId)}, our chainId: {ChainId.GetChainName(_blockTree.ChainId)}");
                    }
                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.ChainId);
                    Disconnect(session, DisconnectReason.UselessPeer, $"invalid chain id - {syncPeerArgs.ChainId}");
                    if (session.Node.IsStatic && _logger.IsWarn)
                    {
                        _logger.Warn($"Disconnected an invalid static node: {session.Node.Host}:{session.Node.Port}, reason: {DisconnectReason.UselessPeer} (invalid chain id - {syncPeerArgs.ChainId})");
                    }
                    return(false);
                }

                if (syncPeerArgs.GenesisHash != _blockTree.Genesis.Hash)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, different genesis hash: {syncPeerArgs.GenesisHash}, our: {_blockTree.Genesis.Hash}");
                    }
                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.DifferentGenesis);
                    Disconnect(session, DisconnectReason.BreachOfProtocol, "invalid genesis");
                    if (session.Node.IsStatic && _logger.IsWarn)
                    {
                        _logger.Warn($"Disconnected an invalid static node: {session.Node.Host}:{session.Node.Port}, reason: {DisconnectReason.BreachOfProtocol} (invalid genesis)");
                    }
                    return(false);
                }

                break;
            }

            return(true);
        }