private IDictionary <string, Func <ISession, int, IProtocolHandler> > GetProtocolFactories() => new Dictionary <string, Func <ISession, int, IProtocolHandler> > { [Protocol.P2P] = (session, _) => { P2PProtocolHandler handler = new P2PProtocolHandler(session, _localPeer.LocalNodeId, _stats, _serializer, _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."); } Eth62ProtocolHandler handler = version == 62 ? new Eth62ProtocolHandler(session, _serializer, _stats, _syncServer, _logManager, _txPool) : new Eth63ProtocolHandler(session, _serializer, _stats, _syncServer, _logManager, _txPool); InitEthProtocol(session, handler); return(handler); } };
public void Setup() { _svc = Build.A.SerializationService().WithEth().TestObject; NetworkDiagTracer.IsEnabled = true; _session = Substitute.For <ISession>(); Node node = new Node(TestItem.PublicKeyA, new IPEndPoint(IPAddress.Broadcast, 30303)); _session.Node.Returns(node); _syncManager = Substitute.For <ISyncServer>(); _transactionPool = Substitute.For <ITxPool>(); _genesisBlock = Build.A.Block.Genesis.TestObject; _syncManager.Head.Returns(_genesisBlock.Header); _syncManager.Genesis.Returns(_genesisBlock.Header); ITimerFactory timerFactory = Substitute.For <ITimerFactory>(); _handler = new Eth62ProtocolHandler( _session, _svc, new NodeStatsManager(timerFactory, LimboLogs.Instance), _syncManager, _transactionPool, LimboLogs.Instance); _handler.Init(); }
public void Get_headers_from_genesis() { var svc = Build.A.SerializationService().WithEth().TestObject; var session = Substitute.For <IP2PSession>(); var syncManager = Substitute.For <ISynchronizationManager>(); var blockTree = Substitute.For <IBlockTree>(); var transactionPool = Substitute.For <ITransactionPool>(); var timestamp = Substitute.For <ITimestamp>(); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler(session, svc, syncManager, LimboLogs.Instance, new PerfService(LimboLogs.Instance), blockTree, transactionPool, timestamp); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockHash = TestObject.KeccakA; msg.MaxHeaders = 3; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; handler.HandleMessage(new Packet(Protocol.Eth, statusMsg.PacketType, svc.Serialize(statusMsg))); handler.HandleMessage(new Packet(Protocol.Eth, msg.PacketType, svc.Serialize(msg))); syncManager.Received().Find(TestObject.KeccakA, 3, 1, true); }
public void Get_headers_when_blocks_are_missing() { var svc = Build.A.SerializationService().WithEth().TestObject; var session = Substitute.For <IP2PSession>(); var syncManager = Substitute.For <ISynchronizationManager>(); var blockTree = Substitute.For <IBlockTree>(); var transactionPool = Substitute.For <ITransactionPool>(); var timestamp = Substitute.For <ITimestamp>(); syncManager.Find(null, Arg.Any <int>(), Arg.Any <int>(), Arg.Any <bool>()).Throws(new ArgumentNullException()); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler(session, svc, syncManager, LimboLogs.Instance, new PerfService(LimboLogs.Instance), blockTree, transactionPool, timestamp); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockNumber = 1920000; msg.MaxHeaders = 3; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; handler.HandleMessage(new Packet(Protocol.Eth, statusMsg.PacketType, svc.Serialize(statusMsg))); handler.HandleMessage(new Packet(Protocol.Eth, msg.PacketType, svc.Serialize(msg))); syncManager.Received().Find(1920000); }
private void InitEthProtocol(ISession session, Eth62ProtocolHandler handler) { handler.ProtocolInitialized += (sender, args) => { if (!RunBasicChecks(session, handler.ProtocolCode, handler.ProtocolVersion)) { return; } var typedArgs = (EthProtocolInitializedEventArgs)args; _stats.ReportEthInitializeEvent(session.Node, new EthNodeDetails { ChainId = typedArgs.ChainId, BestHash = typedArgs.BestHash, GenesisHash = typedArgs.GenesisHash, ProtocolVersion = typedArgs.ProtocolVersion, TotalDifficulty = typedArgs.TotalDifficulty }); bool isValid = _protocolValidator.DisconnectOnInvalid(Protocol.Eth, session, args); if (isValid) { handler.ClientId = session.Node.ClientId; if (_syncPeers.TryAdd(session.SessionId, handler)) { _syncManager.AddPeer(handler); _transactionPool.AddPeer(handler); if (_logger.IsDebug) { _logger.Debug($"{handler.ClientId} sync peer {session} created."); } } else { if (_logger.IsTrace) { _logger.Trace($"Not able to add a sync peer on {session} for {session.Node:s}"); } session.InitiateDisconnect(DisconnectReason.AlreadyConnected, "sync peer"); } if (_logger.IsTrace) { _logger.Trace($"Finalized ETH protocol initialization on {session} - adding sync peer {session.Node:s}"); } //Add/Update peer to the storage and to sync manager _peerStorage.UpdateNodes(new[] { new NetworkNode(session.Node.Id, session.Node.Host, session.Node.Port, _stats.GetOrAdd(session.Node).NewPersistedNodeReputation) }); } else { if (_logger.IsTrace) { _logger.Trace($"|NetworkTrace| {handler.ProtocolCode}{handler.ProtocolVersion} is invalid on {session}"); } } }; }
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>()); }
public void Setup() { _session = Substitute.For <ISession>(); _handler = new Eth62ProtocolHandler( _session, Substitute.For <IMessageSerializationService>(), Substitute.For <INodeStatsManager>(), Substitute.For <ISyncServer>(), Substitute.For <ITxPool>(), LimboLogs.Instance); _controller = new TxFloodController(_handler, LimboNoErrorLogger.Instance); }
public void Get_headers_from_genesis() { var svc = Build.A.SerializationService().WithEth().TestObject; var session = Substitute.For <ISession>(); var syncManager = Substitute.For <ISyncServer>(); var transactionPool = Substitute.For <ITxPool>(); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler( session, svc, new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), syncManager, LimboLogs.Instance, transactionPool); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockHash = TestItem.KeccakA; msg.MaxHeaders = 3; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; IByteBuffer statusPacket = svc.ZeroSerialize(statusMsg); statusPacket.ReadByte(); IByteBuffer getBlockHeadersPacket = svc.ZeroSerialize(msg); getBlockHeadersPacket.ReadByte(); handler.HandleMessage(new ZeroPacket(statusPacket) { PacketType = 0 }); handler.HandleMessage(new ZeroPacket(getBlockHeadersPacket) { PacketType = Eth62MessageCode.GetBlockHeaders }); syncManager.Received().FindHeaders(TestItem.KeccakA, 3, 1, true); }
public void Get_headers_when_blocks_are_missing_in_the_middle() { var svc = Build.A.SerializationService().WithEth().TestObject; var headers = new BlockHeader[5]; headers[0] = Build.A.BlockHeader.TestObject; headers[1] = Build.A.BlockHeader.TestObject; headers[2] = null; headers[3] = Build.A.BlockHeader.TestObject; headers[4] = Build.A.BlockHeader.TestObject; var session = Substitute.For <ISession>(); var syncManager = Substitute.For <ISyncServer>(); var transactionPool = Substitute.For <ITxPool>(); syncManager.FindHash(1920000).Returns(TestItem.KeccakA); syncManager.FindHeaders(TestItem.KeccakA, 5, 1, true) .Returns(headers); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler( session, svc, new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), syncManager, LimboLogs.Instance, new PerfService(LimboLogs.Instance), transactionPool); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockNumber = 1920000; msg.MaxHeaders = 5; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; handler.HandleMessage(new Packet(Protocol.Eth, statusMsg.PacketType, svc.Serialize(statusMsg))); handler.HandleMessage(new Packet(Protocol.Eth, msg.PacketType, svc.Serialize(msg))); session.Received().DeliverMessage(Arg.Is <BlockHeadersMessage>(bhm => bhm.BlockHeaders.Length == 5)); syncManager.Received().FindHash(1920000); }
public void SetUp() { Console.WriteLine("AAA"); Session session = new Session(8545, Substitute.For <IChannel>(), Substitute.For <IDisconnectsAnalyzer>(), LimboLogs.Instance); session.RemoteNodeId = TestItem.PublicKeyA; session.RemoteHost = "127.0.0.1"; session.RemotePort = 30303; _ser = new MessageSerializationService(); _ser.Register(new TransactionsMessageSerializer()); _ser.Register(new StatusMessageSerializer()); NodeStatsManager stats = new NodeStatsManager(TimerFactory.Default, LimboLogs.Instance); var ecdsa = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance); var tree = Build.A.BlockTree().TestObject; var stateProvider = new StateProvider(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance); var specProvider = MainnetSpecProvider.Instance; TxPool.TxPool txPool = new TxPool.TxPool( ecdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(MainnetSpecProvider.Instance), tree, stateProvider), new TxPoolConfig(), new TxValidator(ChainId.Mainnet), LimboLogs.Instance, new TransactionComparerProvider(specProvider, tree).GetDefaultComparer()); ISyncServer syncSrv = Substitute.For <ISyncServer>(); BlockHeader head = Build.A.BlockHeader.WithNumber(1).TestObject; syncSrv.Head.Returns(head); _handler = new Eth62ProtocolHandler(session, _ser, stats, syncSrv, txPool, ShouldGossip.Instance, LimboLogs.Instance); _handler.DisableTxFiltering(); StatusMessage statusMessage = new StatusMessage(); statusMessage.ProtocolVersion = 63; statusMessage.BestHash = Keccak.Compute("1"); statusMessage.GenesisHash = Keccak.Compute("0"); statusMessage.TotalDifficulty = 131200; statusMessage.ChainId = 1; IByteBuffer bufStatus = _ser.ZeroSerialize(statusMessage); _zeroPacket = new ZeroPacket(bufStatus); _zeroPacket.PacketType = bufStatus.ReadByte(); _handler.HandleMessage(_zeroPacket); Transaction tx = Build.A.Transaction.SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; _txMsg = new TransactionsMessage(new[] { tx }); }
public void DisconnectOnWrongChainIdTest() { var p2pSession = InitializeNode(); //trigger eth62 initialization var eth62 = new Eth62ProtocolHandler(p2pSession, new MessageSerializationService(), _synchronizationManager, _logManager, new PerfService(_logManager)); var args = new Eth62ProtocolInitializedEventArgs(eth62) { ChainId = 100 }; p2pSession.TriggerProtocolInitialized(args); Assert.IsTrue(p2pSession.Disconected); Assert.AreEqual(DisconnectReason.Other, p2pSession.DisconnectReason); }
public void Should_stop_notifying_about_new_blocks_and_new_block_hashes_if_in_PoS() { _gossipPolicy.CanGossipBlocks.Returns(false); _handler = new Eth62ProtocolHandler( _session, _svc, new NodeStatsManager(Substitute.For <ITimerFactory>(), LimboLogs.Instance), _syncManager, _transactionPool, _gossipPolicy, LimboLogs.Instance); _syncManager.Received().StopNotifyingPeersAboutNewBlocks(); }
private void InitEthProtocol(ISession session, Eth62ProtocolHandler handler) { handler.ProtocolInitialized += (sender, args) => { if (!RunBasicChecks(session, handler.ProtocolCode, handler.ProtocolVersion)) { return; } var typedArgs = (EthProtocolInitializedEventArgs)args; _stats.ReportEthInitializeEvent(session.Node, new EthNodeDetails { ChainId = typedArgs.ChainId, BestHash = typedArgs.BestHash, GenesisHash = typedArgs.GenesisHash, ProtocolVersion = typedArgs.ProtocolVersion, TotalDifficulty = typedArgs.TotalDifficulty }); bool isValid = _protocolValidator.DisconnectOnInvalid(Protocol.Eth, session, args); if (isValid) { if (_syncPeers.TryAdd(session.SessionId, handler)) { _syncManager.AddPeer(handler); _transactionPool.AddPeer(handler); } else { session.InitiateDisconnect(DisconnectReason.ClientQuitting); } handler.ClientId = session.Node.ClientId; if (_logger.IsTrace) { _logger.Trace($"Eth version {handler.ProtocolVersion} initialized, adding sync peer: {session.Node.Id}"); } //Add/Update peer to the storage and to sync manager _peerStorage.UpdateNodes(new[] { new NetworkNode(session.Node.Id, session.Node.Host, session.Node.Port, _stats.GetOrAdd(session.Node).NewPersistedNodeReputation) }); } if (_logger.IsTrace) { _logger.Trace($"ETH Protocol Initialized: {session.RemoteNodeId}"); } }; }
public void Setup() { _session = Substitute.For <ISession>(); _handler = new Eth62ProtocolHandler( _session, Substitute.For <IMessageSerializationService>(), Substitute.For <INodeStatsManager>(), Substitute.For <ISyncServer>(), Substitute.For <ITxPool>(), Substitute.For <IGossipPolicy>(), LimboLogs.Instance); _timestamper = Substitute.For <ITimestamper>(); _timestamper.UtcNow.Returns(c => DateTime.UtcNow); _controller = new TxFloodController(_handler, _timestamper, LimboNoErrorLogger.Instance); }
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(); }
public void Hardcoded_1920000_works_fine() { var svc = Build.A.SerializationService().WithEth().TestObject; var headers = new BlockHeader[5]; headers[0] = Build.A.BlockHeader.TestObject; headers[1] = Build.A.BlockHeader.TestObject; headers[2] = Build.A.BlockHeader.TestObject; var session = Substitute.For <ISession>(); var syncManager = Substitute.For <ISyncServer>(); var transactionPool = Substitute.For <ITxPool>(); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler( session, svc, new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), syncManager, LimboLogs.Instance, transactionPool); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockNumber = 1920000; msg.MaxHeaders = 1; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; handler.HandleMessage(new Packet(Protocol.Eth, statusMsg.PacketType, svc.Serialize(statusMsg))); handler.HandleMessage(new Packet(Protocol.Eth, msg.PacketType, svc.Serialize(msg))); session.Received().DeliverMessage(Arg.Is <BlockHeadersMessage>(bhm => bhm.BlockHeaders.Length == 1)); }
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 Get_headers_when_blocks_are_missing_at_the_end() { var svc = Build.A.SerializationService().WithEth().TestObject; var headers = new BlockHeader[5]; headers[0] = Build.A.BlockHeader.TestObject; headers[1] = Build.A.BlockHeader.TestObject; headers[2] = Build.A.BlockHeader.TestObject; var session = Substitute.For <ISession>(); var syncManager = Substitute.For <ISyncServer>(); var transactionPool = Substitute.For <ITxPool>(); syncManager.FindHash(100).Returns(TestItem.KeccakA); syncManager.FindHeaders(TestItem.KeccakA, 5, 1, true) .Returns(headers); Block genesisBlock = Build.A.Block.Genesis.TestObject; syncManager.Head.Returns(genesisBlock.Header); syncManager.Genesis.Returns(genesisBlock.Header); var handler = new Eth62ProtocolHandler( session, svc, new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), syncManager, LimboLogs.Instance, transactionPool); handler.Init(); var msg = new GetBlockHeadersMessage(); msg.StartingBlockNumber = 100; msg.MaxHeaders = 5; msg.Skip = 1; msg.Reverse = 1; var statusMsg = new StatusMessage(); statusMsg.GenesisHash = genesisBlock.Hash; IByteBuffer statusPacket = svc.ZeroSerialize(statusMsg); statusPacket.ReadByte(); IByteBuffer getBlockHeadersPacket = svc.ZeroSerialize(msg); getBlockHeadersPacket.ReadByte(); handler.HandleMessage(new ZeroPacket(statusPacket) { PacketType = 0 }); handler.HandleMessage(new ZeroPacket(getBlockHeadersPacket) { PacketType = Eth62MessageCode.GetBlockHeaders }); session.Received().DeliverMessage(Arg.Is <BlockHeadersMessage>(bhm => bhm.BlockHeaders.Length == 3)); syncManager.Received().FindHash(100); }
public Eth62ProtocolInitializedEventArgs(Eth62ProtocolHandler protocolHandler) : base(protocolHandler) { }