diff --git a/cairo/ethereum/cancun/vm/instructions/system.cairo b/cairo/ethereum/cancun/vm/instructions/system.cairo index 6d735744..264c82ae 100644 --- a/cairo/ethereum/cancun/vm/instructions/system.cairo +++ b/cairo/ethereum/cancun/vm/instructions/system.cairo @@ -73,7 +73,11 @@ from starkware.cairo.common.alloc import alloc from legacy.utils.dict import hashdict_read from cairo_core.comparison import is_zero -from ethereum.utils.hash_dicts import set_address_contains, set_address_contains_or_add +from ethereum.utils.hash_dicts import ( + set_address_contains, + set_address_contains_or_add, + set_address_add, +) func generic_call{ process_message_label: felt*, @@ -1473,15 +1477,8 @@ func selfdestruct{ // Add to accounts to delete let accounts_to_delete = evm.value.accounts_to_delete; - let accounts_to_delete_end = cast(accounts_to_delete.value.dict_ptr, DictAccess*); - hashdict_write{dict_ptr=accounts_to_delete_end}(1, &originator, 1); - tempvar new_accounts_to_delete = SetAddress( - new SetAddressStruct( - accounts_to_delete.value.dict_ptr_start, - cast(accounts_to_delete_end, SetAddressDictAccess*), - ), - ); - EvmImpl.set_accounts_to_delete(new_accounts_to_delete); + set_address_add{set_address=accounts_to_delete}(originator); + EvmImpl.set_accounts_to_delete(accounts_to_delete); tempvar evm = evm; tempvar state = state; tempvar poseidon_ptr = poseidon_ptr; @@ -1496,15 +1493,8 @@ func selfdestruct{ let is_empty = account_exists_and_is_empty{state=state}(beneficiary); if (is_empty.value != 0) { let touched_accounts = evm.value.touched_accounts; - let touched_accounts_end = cast(touched_accounts.value.dict_ptr, DictAccess*); - hashdict_write{dict_ptr=touched_accounts_end}(1, &beneficiary.value, 1); - tempvar new_touched_accounts = SetAddress( - new SetAddressStruct( - touched_accounts.value.dict_ptr_start, - cast(touched_accounts_end, SetAddressDictAccess*), - ), - ); - EvmImpl.set_touched_accounts(new_touched_accounts); + set_address_add{set_address=touched_accounts}(beneficiary); + EvmImpl.set_touched_accounts(touched_accounts); tempvar evm = evm; tempvar state = state; tempvar poseidon_ptr = poseidon_ptr; diff --git a/cairo/ethereum/utils/hash_dicts.cairo b/cairo/ethereum/utils/hash_dicts.cairo index 36a886b9..09317477 100644 --- a/cairo/ethereum/utils/hash_dicts.cairo +++ b/cairo/ethereum/utils/hash_dicts.cairo @@ -25,6 +25,24 @@ func set_address_contains{range_check_ptr, poseidon_ptr: PoseidonBuiltin*, set: return value; } +func set_address_add{poseidon_ptr: PoseidonBuiltin*, set_address: SetAddress}(address: Address) { + alloc_locals; + + let fp_and_pc = get_fp_and_pc(); + local __fp__: felt* = fp_and_pc.fp_val; + + let dict_ptr = cast(set_address.value.dict_ptr, DictAccess*); + hashdict_write{dict_ptr=dict_ptr}(1, &address.value, 1); + tempvar new_set_address = SetAddress( + new SetAddressStruct( + set_address.value.dict_ptr_start, cast(dict_ptr, SetAddressDictAccess*) + ), + ); + + return (); +} + +// Returns a boolean indicating if the value was present in the set before the update. func set_address_contains_or_add{poseidon_ptr: PoseidonBuiltin*, set_address: SetAddress}( address: Address ) -> felt {