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); }
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)}."); } } }
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); }
public void TriggerProtocolInitialized(ProtocolInitializedEventArgs eventArgs) { ProtocolInitialized?.Invoke(this, eventArgs); //var task = Task.Delay(1000); //task.Wait(); }
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); }
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}"); } }