Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement EIP-7610 #999

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/ethereum/arrow_glacier/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,13 +362,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/arrow_glacier/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -88,7 +89,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/arrow_glacier/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -107,7 +108,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/berlin/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,13 +362,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/berlin/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -89,7 +90,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/berlin/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -106,7 +107,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/byzantium/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/byzantium/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -95,7 +96,9 @@ def create(evm: Evm) -> None:
):
push(evm.stack, U256(0))
evm.gas_left += create_message_gas
elif account_has_code_or_nonce(evm.env.state, contract_address):
elif account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
else:
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/byzantium/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -105,7 +106,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/cancun/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/cancun/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -101,7 +102,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/cancun/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -107,7 +108,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/constantinople/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/constantinople/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -86,7 +87,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/constantinople/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -105,7 +106,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/dao_fork/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def modify_state(
state: State, address: Address, f: Callable[[Account], None]
) -> None:
Expand Down
Loading
Loading