diff --git a/src/ethereum/arrow_glacier/transactions.py b/src/ethereum/arrow_glacier/transactions.py index d11bc88219..2cf502b768 100644 --- a/src/ethereum/arrow_glacier/transactions.py +++ b/src/ethereum/arrow_glacier/transactions.py @@ -45,6 +45,13 @@ class LegacyTransaction: s: U256 +@slotted_freezable +@dataclass +class Access: + account: Address + slots: Tuple[Bytes32, ...] + + @slotted_freezable @dataclass class AccessListTransaction: @@ -59,7 +66,7 @@ class AccessListTransaction: to: Union[Bytes0, Address] value: U256 data: Bytes - access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...] + access_list: Tuple[Access, ...] y_parity: U256 r: U256 s: U256 @@ -80,12 +87,34 @@ class FeeMarketTransaction: to: Union[Bytes0, Address] value: U256 data: Bytes - access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...] + access_list: Tuple[Access, ...] y_parity: U256 r: U256 s: U256 +# Helper function to handle the RLP encoding of the Access class instances. +def encode_access_list( + access_list: Tuple[Access, ...] +) -> Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...]: + """ + Encode the Access list for RLP encoding. + """ + return tuple((access.account, access.slots) for access in access_list) + + +# Helper function to handle the RLP decoding of the Access class instances. +def decode_access_list( + encoded_access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...] +) -> Tuple[Access, ...]: + """ + Decode the Access list from RLP encoding. + """ + return tuple( + Access(account=encoded[0], slots=encoded[1] + ) for encoded in encoded_access_list) + + Transaction = Union[ LegacyTransaction, AccessListTransaction, FeeMarketTransaction ] @@ -98,9 +127,13 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: if isinstance(tx, LegacyTransaction): return tx elif isinstance(tx, AccessListTransaction): - return b"\x01" + rlp.encode(tx) + encoded_access_list = encode_access_list(tx.access_list) + return b"\x01" + rlp.encode(tx._replace( + access_list=encoded_access_list)) elif isinstance(tx, FeeMarketTransaction): - return b"\x02" + rlp.encode(tx) + encoded_access_list = encode_access_list(tx.access_list) + return b"\x02" + rlp.encode(tx._replace( + access_list=encoded_access_list)) else: raise Exception(f"Unable to encode transaction of type {type(tx)}") @@ -111,9 +144,13 @@ def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: """ if isinstance(tx, Bytes): if tx[0] == 1: - return rlp.decode_to(AccessListTransaction, tx[1:]) + decoded_tx = rlp.decode_to(AccessListTransaction, tx[1:]) + decoded_access_list = decode_access_list(decoded_tx.access_list) + return decoded_tx._replace(access_list=decoded_access_list) elif tx[0] == 2: - return rlp.decode_to(FeeMarketTransaction, tx[1:]) + decoded_tx = rlp.decode_to(FeeMarketTransaction, tx[1:]) + decoded_access_list = decode_access_list(decoded_tx.access_list) + return decoded_tx._replace(access_list=decoded_access_list) else: raise InvalidBlock else: