From 88772136813a02c5e5ab30d5f8c579f0ebf794be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Walter?= Date: Tue, 17 Dec 2024 14:01:16 +0100 Subject: [PATCH] Partial MPT: account trie (#260) --- cairo/ethereum/cancun/fork_types.cairo | 33 +++++++++++++++---- cairo/ethereum/cancun/trie.cairo | 16 +++++---- cairo/ethereum_types/bytes.cairo | 3 +- cairo/ethereum_types/numeric.cairo | 4 ++- .../tests/ethereum/cancun/test_fork_types.py | 6 ++++ cairo/tests/test_serde.py | 1 + cairo/tests/utils/args_gen.py | 3 ++ 7 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 cairo/tests/ethereum/cancun/test_fork_types.py diff --git a/cairo/ethereum/cancun/fork_types.cairo b/cairo/ethereum/cancun/fork_types.cairo index 608ee3d1..5ae20770 100644 --- a/cairo/ethereum/cancun/fork_types.cairo +++ b/cairo/ethereum/cancun/fork_types.cairo @@ -1,11 +1,9 @@ from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.math_cmp import is_le -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin -from starkware.cairo.common.memcpy import memcpy -from src.utils.bytes import felt_to_bytes_little, uint256_to_bytes32_little, felt_to_bytes20_little -from ethereum.crypto.hash import Hash32, keccak256 + from ethereum_types.bytes import Bytes20, Bytes256, Bytes, BytesStruct -from ethereum_types.numeric import Uint, U256 +from ethereum_types.numeric import Uint, U256, U256Struct +from ethereum.crypto.hash import Hash32 + using Address = Bytes20; using Root = Hash32; @@ -30,3 +28,26 @@ struct AccountStruct { struct Account { value: AccountStruct*, } + +struct AddressAccountDictAccess { + key: Address, + prev_value: Account, + new_value: Account, +} + +struct MappingAddressAccountStruct { + dict_ptr_start: AddressAccountDictAccess*, + dict_ptr: AddressAccountDictAccess*, +} + +struct MappingAddressAccount { + value: MappingAddressAccountStruct*, +} + +func EMPTY_ACCOUNT() -> Account { + tempvar balance = U256(new U256Struct(0, 0)); + let (data) = alloc(); + tempvar code = Bytes(new BytesStruct(data=data, len=0)); + tempvar account = Account(value=new AccountStruct(nonce=Uint(0), balance=balance, code=code)); + return account; +} diff --git a/cairo/ethereum/cancun/trie.cairo b/cairo/ethereum/cancun/trie.cairo index bceee27f..feef3ab8 100644 --- a/cairo/ethereum/cancun/trie.cairo +++ b/cairo/ethereum/cancun/trie.cairo @@ -22,7 +22,7 @@ from ethereum_types.bytes import ( TupleMappingBytesBytesStruct, ) from ethereum.cancun.blocks import Receipt, Withdrawal -from ethereum.cancun.fork_types import Account, Address, Root +from ethereum.cancun.fork_types import Account, MappingAddressAccount from ethereum.cancun.transactions import LegacyTransaction from ethereum.rlp import ( Extended, @@ -126,11 +126,15 @@ struct Node { value: NodeEnum*, } -// struct TrieStruct { -// secured: bool, -// default: V, -// _data: Dict[K, V], -// } +struct TrieAddressAccountStruct { + secured: bool, + default: Account, + _data: MappingAddressAccount, +} + +struct TrieAddressAccount { + value: TrieAddressAccountStruct*, +} func encode_internal_node{ range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin* diff --git a/cairo/ethereum_types/bytes.cairo b/cairo/ethereum_types/bytes.cairo index f53db106..b5a09a38 100644 --- a/cairo/ethereum_types/bytes.cairo +++ b/cairo/ethereum_types/bytes.cairo @@ -12,8 +12,9 @@ struct Bytes8 { struct Bytes20 { value: felt, } +using Bytes32Struct = Uint256; struct Bytes32 { - value: Uint256*, + value: Bytes32Struct*, } struct Bytes256 { value: U128*, diff --git a/cairo/ethereum_types/numeric.cairo b/cairo/ethereum_types/numeric.cairo index 3358d4ae..eb3a1705 100644 --- a/cairo/ethereum_types/numeric.cairo +++ b/cairo/ethereum_types/numeric.cairo @@ -14,8 +14,10 @@ struct U128 { struct Uint { value: felt, } + +using U256Struct = Uint256; struct U256 { - value: Uint256*, + value: U256Struct*, } struct SetUintDictAccess { diff --git a/cairo/tests/ethereum/cancun/test_fork_types.py b/cairo/tests/ethereum/cancun/test_fork_types.py new file mode 100644 index 00000000..be33a3de --- /dev/null +++ b/cairo/tests/ethereum/cancun/test_fork_types.py @@ -0,0 +1,6 @@ +from ethereum.cancun.fork_types import EMPTY_ACCOUNT + + +class TestForkTypes: + def test_account_default(self, cairo_run): + assert EMPTY_ACCOUNT == cairo_run("EMPTY_ACCOUNT") diff --git a/cairo/tests/test_serde.py b/cairo/tests/test_serde.py index 362f61a4..21f9fb2d 100644 --- a/cairo/tests/test_serde.py +++ b/cairo/tests/test_serde.py @@ -166,6 +166,7 @@ def test_type( Mapping[Bytes, Bytes], Tuple[Mapping[Bytes, Bytes], ...], Set[Uint], + Mapping[Address, Account], ], ): assume(no_empty_sequence(b)) diff --git a/cairo/tests/utils/args_gen.py b/cairo/tests/utils/args_gen.py index 9dc077ed..218bea2f 100644 --- a/cairo/tests/utils/args_gen.py +++ b/cairo/tests/utils/args_gen.py @@ -116,6 +116,9 @@ ("ethereum", "cancun", "trie", "BranchNode"): BranchNode, ("ethereum", "cancun", "trie", "InternalNode"): InternalNode, ("ethereum", "cancun", "trie", "Node"): Node, + ("ethereum", "cancun", "fork_types", "MappingAddressAccount"): Mapping[ + Address, Account + ], } # In the EELS, some functions are annotated with Sequence while it's actually just Bytes.