Skip to content

Commit

Permalink
Implement EIP-7610
Browse files Browse the repository at this point in the history
  • Loading branch information
gurukamath committed Sep 24, 2024
1 parent a6f5eae commit 7b15c68
Show file tree
Hide file tree
Showing 52 changed files with 443 additions and 52 deletions.
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

0 comments on commit 7b15c68

Please sign in to comment.