Skip to content

Commit

Permalink
feat: destroy_storage, destroy_account (#439)
Browse files Browse the repository at this point in the history
destroy storage
destroy account

closes #406

---------

Co-authored-by: Mathieu <60658558+enitrat@users.noreply.github.com>
  • Loading branch information
Eikix and enitrat authored Jan 16, 2025
1 parent e023608 commit bbc2428
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
68 changes: 68 additions & 0 deletions cairo/ethereum/cancun/state.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ func get_storage{poseidon_ptr: PoseidonBuiltin*, state: State}(
return value;
}

func destroy_account{poseidon_ptr: PoseidonBuiltin*, state: State}(address: Address) {
destroy_storage(address);
let none_account = OptionalAccount(cast(0, AccountStruct*));
set_account(address, none_account);
return ();
}

func set_storage{poseidon_ptr: PoseidonBuiltin*, state: State}(
address: Address, key: Bytes32, value: U256
) {
Expand Down Expand Up @@ -305,6 +312,67 @@ func set_storage{poseidon_ptr: PoseidonBuiltin*, state: State}(
return ();
}

func destroy_storage{poseidon_ptr: PoseidonBuiltin*, state: State}(address: Address) {
alloc_locals;

let storage_tries = state.value._storage_tries;
let fp_and_pc = get_fp_and_pc();
local __fp__: felt* = fp_and_pc.fp_val;

let storage_tries_dict_ptr = cast(storage_tries.value.dict_ptr, DictAccess*);

// Use `hashdict_get` instead of `hashdict_read` because `MappingAddressTrieBytes32U256` is not a
// `default_dict`. Accessing a key that does not exist in the dict would have panicked for `hashdict_read`.
let (pointer) = hashdict_get{dict_ptr=storage_tries_dict_ptr}(1, &address.value);

if (pointer == 0) {
// rebind storage_tries
let new_storage_tries_dict_ptr = cast(
storage_tries_dict_ptr, AddressTrieBytes32U256DictAccess*
);
tempvar storage_tries = MappingAddressTrieBytes32U256(
new MappingAddressTrieBytes32U256Struct(
dict_ptr_start=storage_tries.value.dict_ptr_start,
dict_ptr=new_storage_tries_dict_ptr,
original_mapping=storage_tries.value.original_mapping,
),
);
tempvar state = State(
new StateStruct(
_main_trie=state.value._main_trie,
_storage_tries=storage_tries,
_snapshots=state.value._snapshots,
created_accounts=state.value.created_accounts,
),
);
return ();
}

// del state._storage_tries[address] is equivalent to setting the value to 0
hashdict_write{dict_ptr=storage_tries_dict_ptr}(1, &address.value, 0);

let new_storage_tries_dict_ptr = cast(
storage_tries_dict_ptr, AddressTrieBytes32U256DictAccess*
);
tempvar new_storage_tries = MappingAddressTrieBytes32U256(
new MappingAddressTrieBytes32U256Struct(
dict_ptr_start=storage_tries.value.dict_ptr_start,
dict_ptr=new_storage_tries_dict_ptr,
original_mapping=storage_tries.value.original_mapping,
),
);
tempvar state = State(
new StateStruct(
_main_trie=state.value._main_trie,
_storage_tries=new_storage_tries,
_snapshots=state.value._snapshots,
created_accounts=state.value.created_accounts,
),
);

return ();
}

func get_transient_storage{poseidon_ptr: PoseidonBuiltin*, transient_storage: TransientStorage}(
address: Address, key: Bytes32
) -> U256 {
Expand Down
16 changes: 16 additions & 0 deletions cairo/tests/ethereum/cancun/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from ethereum.cancun.state import (
account_exists,
account_has_code_or_nonce,
destroy_account,
destroy_storage,
get_account,
get_account_optional,
get_storage,
Expand Down Expand Up @@ -78,6 +80,13 @@ def test_set_account(self, cairo_run, data, account: Optional[Account]):
set_account(state, address, account)
assert state_cairo == state

@given(data=state_and_address_and_optional_key())
def test_destroy_account(self, cairo_run, data):
state, address = data
state_cairo = cairo_run("destroy_account", state, address)
destroy_account(state, address)
assert state_cairo == state

@given(data=state_and_address_and_optional_key())
def test_account_has_code_or_nonce(self, cairo_run, data):
state, address = data
Expand Down Expand Up @@ -134,6 +143,13 @@ def test_set_storage(self, cairo_run, data, value: U256):
set_storage(state, address, key, value)
assert state_cairo == state

@given(data=state_and_address_and_optional_key())
def test_destroy_storage(self, cairo_run, data):
state, address = data
state_cairo = cairo_run("destroy_storage", state, address)
destroy_storage(state, address)
assert state_cairo == state


class TestTransientStorage:
@given(
Expand Down

0 comments on commit bbc2428

Please sign in to comment.