Exemple #1
0
        public override void HandleMessage(ZeroPacket message)
        {
            if (message.PacketType != LesMessageCode.Status && !_statusReceived)
            {
                throw new SubprotocolException($"No {nameof(StatusMessage)} received prior to communication with {Session.Node:c}.");
            }

            int size = message.Content.ReadableBytes;

            switch (message.PacketType)
            {
            case LesMessageCode.Status:
                StatusMessage statusMessage = Deserialize <StatusMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, statusMessage.ToString());
                }
                Handle(statusMessage);
                break;

            case LesMessageCode.GetBlockHeaders:
                GetBlockHeadersMessage getBlockHeadersMessage = Deserialize <GetBlockHeadersMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, getBlockHeadersMessage.ToString());
                }
                Handle(getBlockHeadersMessage);
                break;

            case LesMessageCode.GetBlockBodies:
                GetBlockBodiesMessage getBlockBodiesMessage = Deserialize <GetBlockBodiesMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, getBlockBodiesMessage.ToString());
                }
                Handle(getBlockBodiesMessage);
                break;

            case LesMessageCode.GetReceipts:
                GetReceiptsMessage getReceiptsMessage = Deserialize <GetReceiptsMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, getReceiptsMessage.ToString());
                }
                Handle(getReceiptsMessage);
                break;

            case LesMessageCode.GetContractCodes:
                GetContractCodesMessage getContractCodesMessage = Deserialize <GetContractCodesMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, getContractCodesMessage.ToString());
                }
                Handle(getContractCodesMessage);
                break;

            case LesMessageCode.GetHelperTrieProofs:
                GetHelperTrieProofsMessage getHelperTrieProofsMessage = Deserialize <GetHelperTrieProofsMessage>(message.Content);
                if (NetworkDiagTracer.IsEnabled)
                {
                    NetworkDiagTracer.ReportIncomingMessage(Session.Node.Address, Name, getHelperTrieProofsMessage.ToString());
                }
                Handle(getHelperTrieProofsMessage);
                break;
            }
        }
        public void Handle(StatusMessage status)
        {
            Metrics.LesStatusesReceived++;

            // set defaults
            if (!status.AnnounceType.HasValue)
            {
                status.AnnounceType = 1;
            }

            if (_statusReceived)
            {
                throw new SubprotocolException($"{nameof(StatusMessage)} has already been received in the past");
            }

            _statusReceived = true;
            if (Logger.IsTrace)
            {
                Logger.Trace($"LES received status from {Session.Node:c} with" +
                             Environment.NewLine + $" prot version\t{status.ProtocolVersion}" +
                             Environment.NewLine + $" network ID\t{status.ChainId}," +
                             Environment.NewLine + $" genesis hash\t{status.GenesisHash}," +
                             Environment.NewLine + $" best hash\t{status.BestHash}," +
                             Environment.NewLine + $" head blockno\t{status.HeadBlockNo}," +
                             Environment.NewLine + $" difficulty\t{status.TotalDifficulty}" +
                             Environment.NewLine + $" announce type\t{status.AnnounceType}" +
                             Environment.NewLine + $" serve headers\t{status.ServeHeaders}" +
                             Environment.NewLine + $" serve chain since\t{status.ServeChainSince}" +
                             Environment.NewLine + $" serve recent chain\t{status.ServeRecentChain}" +
                             Environment.NewLine + $" serve state since\t{status.ServeStateSince}" +
                             Environment.NewLine + $" serve recent state\t{status.ServeRecentState}" +
                             Environment.NewLine + $" transaction relay\t{status.TxRelay}" +
                             Environment.NewLine + $" buffer limit\t{status.BufferLimit}" +
                             Environment.NewLine + $" max recharge\t{status.MaximumRechargeRate}");
            }
            // todo - log max request costs table

            _remoteHeadBlockHash = status.BestHash;


            ReceivedProtocolInitMsg(status);
            LesProtocolInitializedEventArgs eventArgs = new LesProtocolInitializedEventArgs(this)
            {
                Protocol            = status.Protocol,
                ProtocolVersion     = status.ProtocolVersion,
                ChainId             = (long)status.ChainId, // todo should these really be different data types?
                TotalDifficulty     = status.TotalDifficulty,
                BestHash            = status.BestHash,
                HeadBlockNo         = status.HeadBlockNo,
                GenesisHash         = status.GenesisHash,
                AnnounceType        = status.AnnounceType.Value,
                ServeHeaders        = status.ServeHeaders,
                ServeChainSince     = status.ServeChainSince,
                ServeRecentChain    = status.ServeRecentChain,
                ServeStateSince     = status.ServeStateSince,
                ServeRecentState    = status.ServeRecentState,
                TxRelay             = status.TxRelay,
                BufferLimit         = status.BufferLimit,
                MaximumRechargeRate = status.MaximumRechargeRate,
                MaximumRequestCosts = status.MaximumRequestCosts
            };

            if (status.BestHash == new Keccak("0x828f6e9967f75742364c7ab5efd6e64428e60ad38e218789aaf108fbd0232973"))
            {
                InitiateDisconnect(DisconnectReason.UselessPeer, "One of the Rinkeby nodes stuck at Constantinople transition");
            }

            TotalDifficulty       = status.TotalDifficulty;
            RequestedAnnounceType = status.AnnounceType.Value;

            ProtocolInitialized?.Invoke(this, eventArgs);
        }