コード例 #1
0
        /// <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());
        }