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); }
/// <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); }