diff --git a/src/ethereum/cancun/fork.py b/src/ethereum/cancun/fork.py index 56b53b7ebf..1f8dc3e102 100644 --- a/src/ethereum/cancun/fork.py +++ b/src/ethereum/cancun/fork.py @@ -45,7 +45,6 @@ from .state import ( State, TransientStorage, - account_exists_and_is_empty, destroy_account, get_account, increment_nonce, @@ -784,14 +783,11 @@ def process_transaction( coinbase_balance_after_mining_fee = get_account( block_env.state, block_env.coinbase ).balance + U256(transaction_fee) - if coinbase_balance_after_mining_fee != 0: - set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, - ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + set_account_balance( + block_env.state, + block_env.coinbase, + coinbase_balance_after_mining_fee, + ) for address in tx_output.accounts_to_delete: destroy_account(block_env.state, address) @@ -836,9 +832,6 @@ def increase_recipient_balance(recipient: Account) -> None: modify_state(block_env.state, wd.address, increase_recipient_balance) - if account_exists_and_is_empty(block_env.state, wd.address): - destroy_account(block_env.state, wd.address) - def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/cancun/state.py b/src/ethereum/cancun/state.py index b067ed2286..f144079c2b 100644 --- a/src/ethereum/cancun/state.py +++ b/src/ethereum/cancun/state.py @@ -425,33 +425,6 @@ def account_has_storage(state: State, address: Address) -> bool: return address in state._storage_tries -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code == b"" - and account.balance == 0 - ) - - def is_account_alive(state: State, address: Address) -> bool: """ Check whether is an account is both in the state and non empty. @@ -476,10 +449,20 @@ def modify_state( state: State, address: Address, f: Callable[[Account], None] ) -> None: """ - Modify an `Account` in the `State`. + Modify an `Account` in the `State`. If, after modification, the account + exists and has zero nonce, empty code, and zero balance, it is destroyed. """ set_account(state, address, modify(get_account(state, address), f)) - if account_exists_and_is_empty(state, address): + + account = get_account_optional(state, address) + account_exists_and_is_empty = ( + account is not None + and account.nonce == Uint(0) + and account.code == b"" + and account.balance == 0 + ) + + if account_exists_and_is_empty: destroy_account(state, address) diff --git a/src/ethereum/osaka/fork.py b/src/ethereum/osaka/fork.py index 22c07e0ae8..f44accb968 100644 --- a/src/ethereum/osaka/fork.py +++ b/src/ethereum/osaka/fork.py @@ -54,7 +54,6 @@ from .state import ( State, TransientStorage, - account_exists_and_is_empty, destroy_account, get_account, increment_nonce, @@ -960,14 +959,11 @@ def process_transaction( coinbase_balance_after_mining_fee = get_account( block_env.state, block_env.coinbase ).balance + U256(transaction_fee) - if coinbase_balance_after_mining_fee != 0: - set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, - ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + set_account_balance( + block_env.state, + block_env.coinbase, + coinbase_balance_after_mining_fee, + ) for address in tx_output.accounts_to_delete: destroy_account(block_env.state, address) @@ -1012,9 +1008,6 @@ def increase_recipient_balance(recipient: Account) -> None: modify_state(block_env.state, wd.address, increase_recipient_balance) - if account_exists_and_is_empty(block_env.state, wd.address): - destroy_account(block_env.state, wd.address) - def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/osaka/state.py b/src/ethereum/osaka/state.py index b067ed2286..f144079c2b 100644 --- a/src/ethereum/osaka/state.py +++ b/src/ethereum/osaka/state.py @@ -425,33 +425,6 @@ def account_has_storage(state: State, address: Address) -> bool: return address in state._storage_tries -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code == b"" - and account.balance == 0 - ) - - def is_account_alive(state: State, address: Address) -> bool: """ Check whether is an account is both in the state and non empty. @@ -476,10 +449,20 @@ def modify_state( state: State, address: Address, f: Callable[[Account], None] ) -> None: """ - Modify an `Account` in the `State`. + Modify an `Account` in the `State`. If, after modification, the account + exists and has zero nonce, empty code, and zero balance, it is destroyed. """ set_account(state, address, modify(get_account(state, address), f)) - if account_exists_and_is_empty(state, address): + + account = get_account_optional(state, address) + account_exists_and_is_empty = ( + account is not None + and account.nonce == Uint(0) + and account.code == b"" + and account.balance == 0 + ) + + if account_exists_and_is_empty: destroy_account(state, address) diff --git a/src/ethereum/paris/fork.py b/src/ethereum/paris/fork.py index 2651441b9b..6337daeaaa 100644 --- a/src/ethereum/paris/fork.py +++ b/src/ethereum/paris/fork.py @@ -39,7 +39,6 @@ from .fork_types import Address from .state import ( State, - account_exists_and_is_empty, destroy_account, get_account, increment_nonce, @@ -578,14 +577,11 @@ def process_transaction( coinbase_balance_after_mining_fee = get_account( block_env.state, block_env.coinbase ).balance + U256(transaction_fee) - if coinbase_balance_after_mining_fee != 0: - set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, - ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + set_account_balance( + block_env.state, + block_env.coinbase, + coinbase_balance_after_mining_fee, + ) for address in tx_output.accounts_to_delete: destroy_account(block_env.state, address) diff --git a/src/ethereum/paris/state.py b/src/ethereum/paris/state.py index bc80ff282e..d38c5130d7 100644 --- a/src/ethereum/paris/state.py +++ b/src/ethereum/paris/state.py @@ -391,33 +391,6 @@ def account_has_storage(state: State, address: Address) -> bool: return address in state._storage_tries -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code == b"" - and account.balance == 0 - ) - - def is_account_alive(state: State, address: Address) -> bool: """ Check whether is an account is both in the state and non empty. @@ -442,10 +415,20 @@ def modify_state( state: State, address: Address, f: Callable[[Account], None] ) -> None: """ - Modify an `Account` in the `State`. + Modify an `Account` in the `State`. If, after modification, the account + exists and has zero nonce, empty code, and zero balance, it is destroyed. """ set_account(state, address, modify(get_account(state, address), f)) - if account_exists_and_is_empty(state, address): + + account = get_account_optional(state, address) + account_exists_and_is_empty = ( + account is not None + and account.nonce == Uint(0) + and account.code == b"" + and account.balance == 0 + ) + + if account_exists_and_is_empty: destroy_account(state, address) diff --git a/src/ethereum/prague/fork.py b/src/ethereum/prague/fork.py index 14b9b401a7..2129c16baf 100644 --- a/src/ethereum/prague/fork.py +++ b/src/ethereum/prague/fork.py @@ -53,7 +53,6 @@ from .state import ( State, TransientStorage, - account_exists_and_is_empty, destroy_account, get_account, increment_nonce, @@ -945,14 +944,11 @@ def process_transaction( coinbase_balance_after_mining_fee = get_account( block_env.state, block_env.coinbase ).balance + U256(transaction_fee) - if coinbase_balance_after_mining_fee != 0: - set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, - ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + set_account_balance( + block_env.state, + block_env.coinbase, + coinbase_balance_after_mining_fee, + ) for address in tx_output.accounts_to_delete: destroy_account(block_env.state, address) @@ -997,9 +993,6 @@ def increase_recipient_balance(recipient: Account) -> None: modify_state(block_env.state, wd.address, increase_recipient_balance) - if account_exists_and_is_empty(block_env.state, wd.address): - destroy_account(block_env.state, wd.address) - def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/prague/state.py b/src/ethereum/prague/state.py index b067ed2286..f144079c2b 100644 --- a/src/ethereum/prague/state.py +++ b/src/ethereum/prague/state.py @@ -425,33 +425,6 @@ def account_has_storage(state: State, address: Address) -> bool: return address in state._storage_tries -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code == b"" - and account.balance == 0 - ) - - def is_account_alive(state: State, address: Address) -> bool: """ Check whether is an account is both in the state and non empty. @@ -476,10 +449,20 @@ def modify_state( state: State, address: Address, f: Callable[[Account], None] ) -> None: """ - Modify an `Account` in the `State`. + Modify an `Account` in the `State`. If, after modification, the account + exists and has zero nonce, empty code, and zero balance, it is destroyed. """ set_account(state, address, modify(get_account(state, address), f)) - if account_exists_and_is_empty(state, address): + + account = get_account_optional(state, address) + account_exists_and_is_empty = ( + account is not None + and account.nonce == Uint(0) + and account.code == b"" + and account.balance == 0 + ) + + if account_exists_and_is_empty: destroy_account(state, address) diff --git a/src/ethereum/shanghai/fork.py b/src/ethereum/shanghai/fork.py index e854502873..1cd59aa314 100644 --- a/src/ethereum/shanghai/fork.py +++ b/src/ethereum/shanghai/fork.py @@ -39,7 +39,6 @@ from .fork_types import Account, Address from .state import ( State, - account_exists_and_is_empty, destroy_account, get_account, increment_nonce, @@ -591,14 +590,11 @@ def process_transaction( coinbase_balance_after_mining_fee = get_account( block_env.state, block_env.coinbase ).balance + U256(transaction_fee) - if coinbase_balance_after_mining_fee != 0: - set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, - ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + set_account_balance( + block_env.state, + block_env.coinbase, + coinbase_balance_after_mining_fee, + ) for address in tx_output.accounts_to_delete: destroy_account(block_env.state, address) @@ -642,9 +638,6 @@ def increase_recipient_balance(recipient: Account) -> None: modify_state(block_env.state, wd.address, increase_recipient_balance) - if account_exists_and_is_empty(block_env.state, wd.address): - destroy_account(block_env.state, wd.address) - def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/shanghai/state.py b/src/ethereum/shanghai/state.py index bc80ff282e..d38c5130d7 100644 --- a/src/ethereum/shanghai/state.py +++ b/src/ethereum/shanghai/state.py @@ -391,33 +391,6 @@ def account_has_storage(state: State, address: Address) -> bool: return address in state._storage_tries -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code == b"" - and account.balance == 0 - ) - - def is_account_alive(state: State, address: Address) -> bool: """ Check whether is an account is both in the state and non empty. @@ -442,10 +415,20 @@ def modify_state( state: State, address: Address, f: Callable[[Account], None] ) -> None: """ - Modify an `Account` in the `State`. + Modify an `Account` in the `State`. If, after modification, the account + exists and has zero nonce, empty code, and zero balance, it is destroyed. """ set_account(state, address, modify(get_account(state, address), f)) - if account_exists_and_is_empty(state, address): + + account = get_account_optional(state, address) + account_exists_and_is_empty = ( + account is not None + and account.nonce == Uint(0) + and account.code == b"" + and account.balance == 0 + ) + + if account_exists_and_is_empty: destroy_account(state, address)