Esempio n. 1
0
        private async Task <bool> ValidateProtocol(string protocol, Peer peer, ProtocolInitializedEventArgs eventArgs)
        {
            //TODO add validation for clientId - e.g. get only ethereumJ clients
            switch (protocol)
            {
            case Protocol.P2P:
                var args = (P2PProtocolInitializedEventArgs)eventArgs;
                if (args.P2PVersion < 4 || args.P2PVersion > 5)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info($"Initiating disconnect, incorrect P2PVersion: {args.P2PVersion}, id: {peer.Node.Id.ToString(false)}");
                    }
                    await peer.Session.InitiateDisconnectAsync(DisconnectReason.IncompatibleP2PVersion);

                    return(false);
                }

                if (!args.Capabilities.Any(x => x.ProtocolCode == Protocol.Eth && x.Version == 62))
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info($"Initiating disconnect, no Eth62 capability, supported capabilities: [{string.Join(",", args.Capabilities.Select(x => $"{x.ProtocolCode}v{x.Version}"))}], id: {peer.Node.Id.ToString(false)}");
                    }
                    //TODO confirm disconnect reason
                    await peer.Session.InitiateDisconnectAsync(DisconnectReason.Other);

                    return(false);
                }

                //if (args.ClientId.Contains("Geth") || args.ClientId.Contains("Parity") || args.ClientId.Contains("Gnekonium"))
                //{
                //    if (_logger.IsInfoEnabled)
                //    {
                //        _logger.Info($"Initiating disconnect, rejecting client: {args.ClientId}, id: {peer.Node.Id.ToString(false)}");
                //    }
                //    await peer.Session.InitiateDisconnectAsync(DisconnectReason.Other);
                //    return false;
                //}
                break;

            case Protocol.Eth:
                var ethArgs = (Eth62ProtocolInitializedEventArgs)eventArgs;
                if (ethArgs.ChainId != _synchronizationManager.ChainId)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info($"Initiating disconnect, different chainId: {ethArgs.ChainId}, our chainId: {_synchronizationManager.ChainId}, peer id: {peer.Node.Id.ToString(false)}");
                    }
                    //TODO confirm disconnect reason
                    await peer.Session.InitiateDisconnectAsync(DisconnectReason.Other);

                    return(false);
                }
                break;
            }
            return(true);
        }
Esempio n. 2
0
        private async Task OnProtocolInitialized(object sender, ProtocolInitializedEventArgs e)
        {
            var session = (IP2PSession)sender;

            if (_activePeers.TryGetValue(session.RemoteNodeId, out var peer))
            {
                switch (e.ProtocolHandler)
                {
                case P2PProtocolHandler _:
                    //TODO test log
                    //_logger.Info($"ETH62TESTCLIENTID: {((P2PProtocolInitializedEventArgs)e).ClientId}");
                    peer.NodeStats.NodeDetails.ClientId = ((P2PProtocolInitializedEventArgs)e).ClientId;
                    var result = await ValidateProtocol(Protocol.P2P, peer, e);

                    if (!result)
                    {
                        return;
                    }
                    peer.NodeStats.AddNodeStatsEvent(NodeStatsEvent.P2PInitialized);
                    break;

                case Eth62ProtocolHandler ethProtocolhandler:
                    result = await ValidateProtocol(Protocol.Eth, peer, e);

                    if (!result)
                    {
                        return;
                    }
                    peer.NodeStats.AddNodeStatsEvent(NodeStatsEvent.Eth62Initialized);
                    peer.SynchronizationPeer = ethProtocolhandler;

                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info($"Eth62 initialized, adding sync peer: {peer.Node.Id.ToString(false)}");
                    }
                    //Add peer to the storage and to sync manager
                    _peerStorage.UpdatePeers(new [] { peer });
                    await _synchronizationManager.AddPeer(ethProtocolhandler);

                    break;
                }
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Protocol Initialized: {session.RemoteNodeId.ToString(false)}, {e.ProtocolHandler.GetType().Name}");
                }
            }
            else
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.Error($"Protocol initialized for peer not present in active collection, id: {session.RemoteNodeId.ToString(false)}.");
                }
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
 public void TriggerProtocolInitialized(ProtocolInitializedEventArgs eventArgs)
 {
     ProtocolInitialized?.Invoke(this, eventArgs);
     //var task = Task.Delay(1000);
     //task.Wait();
 }
Esempio n. 5
0
 public void TriggerProtocolInitialized(ProtocolInitializedEventArgs eventArgs)
 {
     ProtocolInitialized?.Invoke(this, eventArgs);
 }
        public bool DisconnectOnInvalid(string protocol, ISession session, ProtocolInitializedEventArgs eventArgs)
        {
            switch (protocol)
            {
            case Protocol.P2P:
                var 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);
                    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);
                    return(false);
                }

                break;

            case Protocol.Eth:
                var ethArgs = (EthProtocolInitializedEventArgs)eventArgs;
                if (!ValidateChainId(ethArgs.ChainId))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, different chainId: {ChainId.GetChainName((int) ethArgs.ChainId)}, our chainId: {ChainId.GetChainName(_blockTree.ChainId)}");
                    }

                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.ChainId);
                    Disconnect(session, DisconnectReason.UselessPeer);
                    return(false);
                }

                if (ethArgs.GenesisHash != _blockTree.Genesis.Hash)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Initiating disconnect with peer: {session.RemoteNodeId}, different genesis hash: {ethArgs.GenesisHash}, our: {_blockTree.Genesis.Hash}");
                    }

                    _nodeStatsManager.ReportFailedValidation(session.Node, CompatibilityValidationType.DifferentGenesis);
                    Disconnect(session, DisconnectReason.BreachOfProtocol);
                    return(false);
                }

                break;
            }

            return(true);
        }
Esempio n. 7
0
        private async Task OnProtocolInitialized(object sender, ProtocolInitializedEventArgs e)
        {
            var session = (IP2PSession)sender;

            if (session.ClientConnectionType == ClientConnectionType.In && e.ProtocolHandler is P2PProtocolHandler handler)
            {
                if (!await ProcessIncomingConnection(session, handler))
                {
                    return;
                }
            }

            if (!_activePeers.TryGetValue(session.RemoteNodeId, out var peer))
            {
                if (_candidatePeers.TryGetValue(session.RemoteNodeId, out var candidateNode))
                {
                    if (_logger.IsWarnEnabled)
                    {
                        var timeFromLastDisconnect = candidateNode.NodeStats.LastDisconnectTime.HasValue
                            ? DateTime.Now.Subtract(candidateNode.NodeStats.LastDisconnectTime.Value).TotalMilliseconds.ToString()
                            : "no disconnect";

                        _logger.Warn($"Protocol initialized for peer not present in active collection, id: {session.RemoteNodeId}, time from last disconnect: {timeFromLastDisconnect}.");
                    }
                }
                else
                {
                    if (_logger.IsErrorEnabled)
                    {
                        _logger.Error($"Protocol initialized for peer not present in active collection, id: {session.RemoteNodeId}, peer not in candidate collection.");
                    }
                }

                //Initializing disconnect if it hasnt been done already - in case of e.g. timeout earier and unexcepted further connection
                await session.InitiateDisconnectAsync(DisconnectReason.Other);

                return;
            }

            switch (e.ProtocolHandler)
            {
            case P2PProtocolHandler p2PProtocolHandler:
                peer.NodeStats.NodeDetails.ClientId = ((P2PProtocolInitializedEventArgs)e).ClientId;
                var result = await ValidateProtocol(Protocol.P2P, peer, e);

                if (!result)
                {
                    return;
                }
                peer.NodeStats.AddNodeStatsEvent(NodeStatsEvent.P2PInitialized);
                peer.P2PMessageSender = p2PProtocolHandler;
                break;

            case Eth62ProtocolHandler ethProtocolhandler:
                result = await ValidateProtocol(Protocol.Eth, peer, e);

                if (!result)
                {
                    return;
                }
                peer.NodeStats.AddNodeStatsEvent(NodeStatsEvent.Eth62Initialized);
                //TODO move this outside, so syncManager have access to NodeStats and NodeDetails
                ethProtocolhandler.ClientId = peer.NodeStats.NodeDetails.ClientId;
                peer.SynchronizationPeer    = ethProtocolhandler;

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Eth62 initialized, adding sync peer: {peer.Node.Id}");
                }
                //Add peer to the storage and to sync manager
                _peerStorage.UpdatePeers(new [] { peer });
                await _synchronizationManager.AddPeer(ethProtocolhandler);

                break;
            }
            if (_logger.IsInfoEnabled)
            {
                _logger.Info($"Protocol Initialized: {session.RemoteNodeId}, {e.ProtocolHandler.GetType().Name}");
            }
        }