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