Skip to content

Implement EIP-7907 #1231

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

Closed
Closed
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
1 change: 1 addition & 0 deletions src/ethereum/osaka/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ def process_system_transaction(
accessed_addresses=set(),
accessed_storage_keys=set(),
disable_precompiles=False,
warm_code_addresses=set(),
parent_evm=None,
)

Expand Down
4 changes: 2 additions & 2 deletions src/ethereum/osaka/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,14 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]:
InvalidBlock :
If the transaction is not valid.
"""
from .vm.interpreter import MAX_CODE_SIZE
from .vm.interpreter import MAX_INIT_CODE_SIZE

intrinsic_gas, calldata_floor_gas_cost = calculate_intrinsic_cost(tx)
if max(intrinsic_gas, calldata_floor_gas_cost) > tx.gas:
raise InvalidTransaction("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
raise InvalidTransaction("Code size too large")
if tx.gas > TX_MAX_GAS_LIMIT:
raise InvalidTransaction("Gas limit too high")
Expand Down
1 change: 1 addition & 0 deletions src/ethereum/osaka/utils/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,6 @@ def prepare_message(
accessed_addresses=accessed_addresses,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L71: wondering if we should add warm_code_addresses.add(current_target) to account for CREATE* addresses and tx.recipient given its considered warm automatically (?)

accessed_storage_keys=set(tx_env.access_list_storage_keys),
disable_precompiles=False,
warm_code_addresses=set(),
parent_evm=None,
)
3 changes: 3 additions & 0 deletions src/ethereum/osaka/vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class Message:
accessed_addresses: Set[Address]
accessed_storage_keys: Set[Tuple[Address, Bytes32]]
disable_precompiles: bool
warm_code_addresses: Set[Address]
parent_evm: Optional["Evm"]


Expand All @@ -156,6 +157,7 @@ class Evm:
error: Optional[EthereumException]
accessed_addresses: Set[Address]
accessed_storage_keys: Set[Tuple[Address, Bytes32]]
warm_code_addresses: Set[Address]


def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None:
Expand All @@ -175,6 +177,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None:
evm.accounts_to_delete.update(child_evm.accounts_to_delete)
evm.accessed_addresses.update(child_evm.accessed_addresses)
evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)
evm.warm_code_addresses.update(child_evm.warm_code_addresses)


def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None:
Expand Down
8 changes: 6 additions & 2 deletions src/ethereum/osaka/vm/eoa_delegation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from ..fork_types import Address, Authorization
from ..state import account_exists, get_account, increment_nonce, set_code
from ..utils.hexadecimal import hex_to_address
from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS
from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS, code_access_cost
from . import Evm, Message

SET_CODE_TX_MAGIC = b"\x05"
Expand Down Expand Up @@ -136,12 +136,16 @@ def access_delegation(
return False, address, code, Uint(0)

address = Address(code[EOA_DELEGATION_MARKER_LENGTH:])
code = get_account(state, address).code
if address in evm.accessed_addresses:
access_gas_cost = GAS_WARM_ACCESS
else:
evm.accessed_addresses.add(address)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
code = get_account(state, address).code

if address not in evm.warm_code_addresses:
evm.warm_code_addresses.add(address)
access_gas_cost += code_access_cost(code)

return True, address, code, access_gas_cost

Expand Down
30 changes: 30 additions & 0 deletions src/ethereum/osaka/vm/gas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from dataclasses import dataclass
from typing import List, Tuple

from ethereum_types.bytes import Bytes
from ethereum_types.numeric import U64, U256, Uint

from ethereum.trace import GasAndRefund, evm_trace
Expand Down Expand Up @@ -280,6 +281,35 @@ def init_code_cost(init_code_length: Uint) -> Uint:
return GAS_INIT_CODE_WORD_COST * ceil32(init_code_length) // Uint(32)


def code_access_cost(code: Bytes) -> Uint:
"""
Calculates the gas to be charged for loading contract code.

Parameters
----------
code :
The contract code.

Returns
-------
code_access_gas: `ethereum.base_types.Uint`
The gas to be charged for loading the code.
"""
from .interpreter import MAX_CODE_SIZE_WITH_NO_ACCESS_COST

excess_contract_size = max(
0, len(code) - MAX_CODE_SIZE_WITH_NO_ACCESS_COST
)
if excess_contract_size == 0:
return Uint(0)

return (
GAS_INIT_CODE_WORD_COST
* ceil32(Uint(excess_contract_size))
// Uint(32)
)


def calculate_excess_blob_gas(parent_header: Header) -> U64:
"""
Calculated the excess blob gas for the current block based
Expand Down
7 changes: 7 additions & 0 deletions src/ethereum/osaka/vm/instructions/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
calculate_blob_gas_price,
calculate_gas_extend_memory,
charge_gas,
code_access_cost,
)
from ..stack import pop, push

Expand Down Expand Up @@ -389,6 +390,12 @@ def extcodecopy(evm: Evm) -> None:
evm.accessed_addresses.add(address)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS

if address not in evm.warm_code_addresses:
evm.warm_code_addresses.add(address)
access_gas_cost += code_access_cost(
get_account(evm.message.block_env.state, address).code
)

charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost)

# OPERATION
Expand Down
31 changes: 29 additions & 2 deletions src/ethereum/osaka/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
calculate_gas_extend_memory,
calculate_message_call_gas,
charge_gas,
code_access_cost,
init_code_cost,
max_message_call_gas,
)
Expand All @@ -73,15 +74,15 @@ def generic_create(
# This import causes a circular import error
# if it's not moved inside this method
from ...vm.interpreter import (
MAX_CODE_SIZE,
MAX_INIT_CODE_SIZE,
STACK_DEPTH_LIMIT,
process_create_message,
)

call_data = memory_read_bytes(
evm.memory, memory_start_position, memory_size
)
if len(call_data) > 2 * MAX_CODE_SIZE:
if len(call_data) > MAX_INIT_CODE_SIZE:
raise OutOfGasError

create_message_gas = max_message_call_gas(Uint(evm.gas_left))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L107: wondering if we should add evm.message.warm_code_addresses.add(contract_address) to account for CREATE* invocations

Expand Down Expand Up @@ -132,6 +133,7 @@ def generic_create(
accessed_addresses=evm.accessed_addresses.copy(),
accessed_storage_keys=evm.accessed_storage_keys.copy(),
disable_precompiles=False,
warm_code_addresses=evm.warm_code_addresses.copy(),
parent_evm=evm,
)
child_evm = process_create_message(child_message)
Expand Down Expand Up @@ -322,6 +324,7 @@ def generic_call(
accessed_addresses=evm.accessed_addresses.copy(),
accessed_storage_keys=evm.accessed_storage_keys.copy(),
disable_precompiles=disable_precompiles,
warm_code_addresses=evm.warm_code_addresses.copy(),
parent_evm=evm,
)
child_evm = process_message(child_message)
Expand Down Expand Up @@ -376,6 +379,12 @@ def call(evm: Evm) -> None:
evm.accessed_addresses.add(to)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS

if to not in evm.warm_code_addresses:
evm.warm_code_addresses.add(to)
access_gas_cost += code_access_cost(
get_account(evm.message.block_env.state, to).code
)

code_address = to
(
disable_precompiles,
Expand Down Expand Up @@ -466,6 +475,12 @@ def callcode(evm: Evm) -> None:
evm.accessed_addresses.add(code_address)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS

if code_address not in evm.warm_code_addresses:
evm.warm_code_addresses.add(code_address)
access_gas_cost += code_access_cost(
get_account(evm.message.block_env.state, code_address).code
)

(
disable_precompiles,
code_address,
Expand Down Expand Up @@ -605,6 +620,12 @@ def delegatecall(evm: Evm) -> None:
evm.accessed_addresses.add(code_address)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS

if code_address not in evm.warm_code_addresses:
evm.warm_code_addresses.add(code_address)
access_gas_cost += code_access_cost(
get_account(evm.message.block_env.state, code_address).code
)

(
disable_precompiles,
code_address,
Expand Down Expand Up @@ -673,6 +694,12 @@ def staticcall(evm: Evm) -> None:
evm.accessed_addresses.add(to)
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS

if to not in evm.warm_code_addresses:
evm.warm_code_addresses.add(to)
access_gas_cost += code_access_cost(
get_account(evm.message.block_env.state, to).code
)

code_address = to
(
disable_precompiles,
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/osaka/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@
from .runtime import get_valid_jump_destinations

STACK_DEPTH_LIMIT = Uint(1024)
MAX_CODE_SIZE = 0x6000
MAX_CODE_SIZE_WITH_NO_ACCESS_COST = 0x6000
MAX_CODE_SIZE = 0x40000
MAX_INIT_CODE_SIZE = 0x80000


@dataclass
Expand Down Expand Up @@ -286,6 +288,7 @@ def execute_code(message: Message) -> Evm:
error=None,
accessed_addresses=message.accessed_addresses,
accessed_storage_keys=message.accessed_storage_keys,
warm_code_addresses=message.warm_code_addresses,
)
try:
if evm.message.code_address in PRE_COMPILED_CONTRACTS:
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy