public ValidatorInfo?Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } var length = rlpStream.ReadSequenceLength(); int check = rlpStream.Position + length; var finalizingBlockNumber = rlpStream.DecodeLong(); var previousFinalizingBlockNumber = rlpStream.DecodeLong(); int addressesSequenceLength = rlpStream.ReadSequenceLength(); int addressesCheck = rlpStream.Position + addressesSequenceLength; Address[] addresses = new Address[addressesSequenceLength / Rlp.LengthOfAddressRlp]; int i = 0; while (rlpStream.Position < addressesCheck) { addresses[i++] = rlpStream.DecodeAddress(); } rlpStream.Check(addressesCheck); rlpStream.Check(check); return(new ValidatorInfo(finalizingBlockNumber, previousFinalizingBlockNumber, addresses)); }
public PendingValidators Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } var sequenceLength = rlpStream.ReadSequenceLength(); var pendingValidatorsCheck = rlpStream.Position + sequenceLength; var blockNumber = rlpStream.DecodeLong(); var blockHash = rlpStream.DecodeKeccak(); var addressSequenceLength = rlpStream.ReadSequenceLength(); var addressCheck = rlpStream.Position + addressSequenceLength; List <Address> addresses = new List <Address>(); while (rlpStream.Position < addressCheck) { addresses.Add(rlpStream.DecodeAddress()); } rlpStream.Check(addressCheck); var result = new PendingValidators(blockNumber, blockHash, addresses.ToArray()) { AreFinalized = rlpStream.DecodeBool() }; rlpStream.Check(pendingValidatorsCheck); return(result); }
/// <summary> /// We pay a high code quality tax for the performance optimization on RLP. /// Adding more RLP decoders is costly (time wise) but the path taken saves a lot of allocations and GC. /// Shall we consider code generation for this? We could potentially generate IL from attributes for each /// RLP serializable item and keep it as a compiled call available at runtime. /// It would be slightly slower but still much faster than what we would get from using dynamic serializers. /// </summary> public AccessList?Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } int length = rlpStream.PeekNextRlpLength(); int check = rlpStream.Position + length; rlpStream.SkipLength(); AccessListBuilder accessListBuilder = new(); while (rlpStream.Position < check) { rlpStream.SkipLength(); Address address = rlpStream.DecodeAddress(); if (address == null) { throw new RlpException("Invalid tx access list format - address is null"); } accessListBuilder.AddAddress(address); if (rlpStream.Position < check) { int storageCheck = rlpStream.Position + rlpStream.PeekNextRlpLength(); rlpStream.SkipLength(); while (rlpStream.Position < storageCheck) { UInt256 index = rlpStream.DecodeUInt256(); accessListBuilder.AddStorage(index); } } } if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(check); } return(accessListBuilder.ToAccessList()); }