Ejemplo n.º 1
0
        public NetworkNode Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            rlpStream.ReadSequenceLength();

            PublicKey publicKey = new PublicKey(rlpStream.DecodeByteArray());
            string    ip        = rlpStream.DecodeString();
            int       port      = (int)rlpStream.DecodeByteArraySpan().ReadEthUInt64();

            rlpStream.SkipItem();
            long reputation = 0L;

            try
            {
                reputation = rlpStream.DecodeLong();
            }
            catch (RlpException)
            {
                // regression - old format
            }

            NetworkNode networkNode = new NetworkNode(publicKey, ip != string.Empty ? ip : null, port, reputation);

            return(networkNode);
        }
        private static StatusMessage Deserialize(RlpStream rlpStream)
        {
            StatusMessage statusMessage = new StatusMessage();

            (int prefixLength, int contentLength) = rlpStream.PeekPrefixAndContentLength();
            var totalLength = contentLength;

            rlpStream.Position += prefixLength;
            var readLength = prefixLength;

            while (totalLength > readLength)
            {
                (prefixLength, contentLength) = rlpStream.PeekPrefixAndContentLength();
                readLength         += prefixLength + contentLength;
                rlpStream.Position += prefixLength;
                string key = rlpStream.DecodeString();
                switch (key)
                {
                case StatusMessage.KeyNames.ProtocolVersion:
                    statusMessage.ProtocolVersion = rlpStream.DecodeByte();
                    break;

                case StatusMessage.KeyNames.ChainId:
                    statusMessage.ChainId = rlpStream.DecodeUInt256();
                    break;

                case StatusMessage.KeyNames.TotalDifficulty:
                    statusMessage.TotalDifficulty = rlpStream.DecodeUInt256();
                    break;

                case StatusMessage.KeyNames.BestHash:
                    statusMessage.BestHash = rlpStream.DecodeKeccak();
                    break;

                case StatusMessage.KeyNames.HeadBlockNo:
                    statusMessage.HeadBlockNo = rlpStream.DecodeLong();
                    break;

                case StatusMessage.KeyNames.GenesisHash:
                    statusMessage.GenesisHash = rlpStream.DecodeKeccak();
                    break;

                case StatusMessage.KeyNames.AnnounceType:
                    statusMessage.AnnounceType = rlpStream.DecodeByte();
                    break;

                case StatusMessage.KeyNames.ServeHeaders:
                    statusMessage.ServeHeaders = true;
                    rlpStream.SkipItem();
                    break;

                case StatusMessage.KeyNames.ServeChainSince:
                    statusMessage.ServeChainSince = rlpStream.DecodeLong();
                    break;

                case StatusMessage.KeyNames.ServeRecentChain:
                    statusMessage.ServeRecentChain = rlpStream.DecodeLong();
                    break;

                case StatusMessage.KeyNames.ServeStateSince:
                    statusMessage.ServeStateSince = rlpStream.DecodeLong();
                    break;

                case StatusMessage.KeyNames.ServeRecentState:
                    statusMessage.ServeRecentState = rlpStream.DecodeLong();
                    break;

                case StatusMessage.KeyNames.TxRelay:
                    statusMessage.TxRelay = true;
                    rlpStream.SkipItem();
                    break;

                case StatusMessage.KeyNames.BufferLimit:
                    statusMessage.BufferLimit = rlpStream.DecodeInt();
                    break;

                case StatusMessage.KeyNames.MaximumRechargeRate:
                    statusMessage.MaximumRechargeRate = rlpStream.DecodeInt();
                    break;

                case StatusMessage.KeyNames.MaximumRequestCosts:
                // todo
                default:
                    // Ignore unknown keys
                    rlpStream.Position = readLength;
                    break;
                }
            }

            return(statusMessage);
        }
Ejemplo n.º 3
0
    /// <summary>
    /// Deserializes a <see cref="NodeRecord"/> from an <see cref="RlpStream"/>.
    /// </summary>
    /// <param name="rlpStream">A stream to read the serialized data from.</param>
    /// <returns>A deserialized <see cref="NodeRecord"/></returns>
    public NodeRecord Deserialize(RlpStream rlpStream)
    {
        int startPosition   = rlpStream.Position;
        int recordRlpLength = rlpStream.ReadSequenceLength();

        NodeRecord nodeRecord = new();

        ReadOnlySpan <byte> sigBytes  = rlpStream.DecodeByteArraySpan();
        Signature           signature = new(sigBytes, 0);

        bool canVerify   = true;
        long enrSequence = rlpStream.DecodeLong();

        while (rlpStream.Position < startPosition + recordRlpLength)
        {
            string key = rlpStream.DecodeString();
            switch (key)
            {
            case EnrContentKey.Eth:
                _ = rlpStream.ReadSequenceLength();
                _ = rlpStream.ReadSequenceLength();
                byte[] forkHash  = rlpStream.DecodeByteArray();
                long   nextBlock = rlpStream.DecodeLong();
                nodeRecord.SetEntry(new EthEntry(forkHash, nextBlock));
                break;

            case EnrContentKey.Id:
                rlpStream.SkipItem();
                nodeRecord.SetEntry(IdEntry.Instance);
                break;

            case EnrContentKey.Ip:
                ReadOnlySpan <byte> ipBytes = rlpStream.DecodeByteArraySpan();
                IPAddress           address = new(ipBytes);
                nodeRecord.SetEntry(new IpEntry(address));
                break;

            case EnrContentKey.Tcp:
                int tcpPort = rlpStream.DecodeInt();
                nodeRecord.SetEntry(new TcpEntry(tcpPort));
                break;

            case EnrContentKey.Udp:
                int udpPort = rlpStream.DecodeInt();
                nodeRecord.SetEntry(new UdpEntry(udpPort));
                break;

            case EnrContentKey.Secp256K1:
                ReadOnlySpan <byte> keyBytes    = rlpStream.DecodeByteArraySpan();
                CompressedPublicKey reportedKey = new(keyBytes);
                nodeRecord.SetEntry(new Secp256K1Entry(reportedKey));
                break;

            // snap
            default:
                canVerify = false;
                rlpStream.SkipItem();
                nodeRecord.Snap = true;
                break;
            }
        }

        if (!canVerify)
        {
            rlpStream.Position = startPosition;
            rlpStream.ReadSequenceLength();
            rlpStream.SkipItem(); // signature
            int       noSigContentLength    = rlpStream.Length - rlpStream.Position;
            int       noSigSequenceLength   = Rlp.LengthOfSequence(noSigContentLength);
            byte[]    originalContent       = new byte[noSigSequenceLength];
            RlpStream originalContentStream = new (originalContent);
            originalContentStream.StartSequence(noSigContentLength);
            originalContentStream.Write(rlpStream.Read(noSigContentLength));
            rlpStream.Position            = startPosition;
            nodeRecord.OriginalContentRlp = originalContentStream.Data !;
        }

        nodeRecord.EnrSequence = enrSequence;
        nodeRecord.Signature   = signature;

        return(nodeRecord);
    }