Skip to content

Commit f069e08

Browse files
gurukamathSamWilsn
authored andcommitted
Implement EIP-7907
1 parent 96fed55 commit f069e08

File tree

6 files changed

+56
-7
lines changed

6 files changed

+56
-7
lines changed

src/ethereum/osaka/transactions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,14 +542,14 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]:
542542
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
543543
[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623
544544
"""
545-
from .vm.interpreter import MAX_CODE_SIZE
545+
from .vm.interpreter import MAX_INIT_CODE_SIZE
546546

547547
intrinsic_gas, calldata_floor_gas_cost = calculate_intrinsic_cost(tx)
548548
if max(intrinsic_gas, calldata_floor_gas_cost) > tx.gas:
549549
raise InvalidTransaction("Insufficient gas")
550550
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
551551
raise InvalidTransaction("Nonce too high")
552-
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
552+
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
553553
raise InvalidTransaction("Code size too large")
554554
if tx.gas > TX_MAX_GAS_LIMIT:
555555
raise InvalidTransaction("Gas limit too high")

src/ethereum/osaka/vm/eoa_delegation.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from ..fork_types import Address, Authorization
1717
from ..state import account_exists, get_account, increment_nonce, set_code
1818
from ..utils.hexadecimal import hex_to_address
19-
from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS
19+
from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS, code_access_cost
2020
from . import Evm, Message
2121

2222
SET_CODE_TX_MAGIC = b"\x05"
@@ -136,12 +136,13 @@ def access_delegation(
136136
return False, address, code, Uint(0)
137137

138138
address = Address(code[EOA_DELEGATION_MARKER_LENGTH:])
139+
code = get_account(state, address).code
139140
if address in evm.accessed_addresses:
140141
access_gas_cost = GAS_WARM_ACCESS
141142
else:
142143
evm.accessed_addresses.add(address)
143144
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
144-
code = get_account(state, address).code
145+
access_gas_cost += code_access_cost(code)
145146

146147
return True, address, code, access_gas_cost
147148

src/ethereum/osaka/vm/gas.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from dataclasses import dataclass
1515
from typing import List, Tuple
1616

17+
from ethereum_types.bytes import Bytes
1718
from ethereum_types.numeric import U64, U256, Uint
1819

1920
from ethereum.trace import GasAndRefund, evm_trace
@@ -65,6 +66,7 @@
6566
GAS_COLD_ACCOUNT_ACCESS = Uint(2600)
6667
GAS_WARM_ACCESS = Uint(100)
6768
GAS_INIT_CODE_WORD_COST = Uint(2)
69+
GAS_EXCESS_WORD_COST = Uint(2)
6870
GAS_BLOBHASH_OPCODE = Uint(3)
6971
GAS_POINT_EVALUATION = Uint(50000)
7072

@@ -280,6 +282,33 @@ def init_code_cost(init_code_length: Uint) -> Uint:
280282
return GAS_INIT_CODE_WORD_COST * ceil32(init_code_length) // Uint(32)
281283

282284

285+
def code_access_cost(code: Bytes) -> Uint:
286+
"""
287+
Calculates the gas to be charged for loading contract code.
288+
289+
Parameters
290+
----------
291+
code :
292+
The contract code.
293+
294+
Returns
295+
-------
296+
code_access_gas: `ethereum.base_types.Uint`
297+
The gas to be charged for loading the code.
298+
"""
299+
from .interpreter import MAX_CODE_SIZE_WITH_NO_ACCESS_COST
300+
301+
excess_contract_size = max(
302+
0, len(code) - MAX_CODE_SIZE_WITH_NO_ACCESS_COST
303+
)
304+
if excess_contract_size == 0:
305+
return Uint(0)
306+
307+
return (
308+
GAS_EXCESS_WORD_COST * ceil32(Uint(excess_contract_size)) // Uint(32)
309+
)
310+
311+
283312
def calculate_excess_blob_gas(parent_header: Header) -> U64:
284313
"""
285314
Calculated the excess blob gas for the current block based

src/ethereum/osaka/vm/instructions/environment.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
calculate_blob_gas_price,
3737
calculate_gas_extend_memory,
3838
charge_gas,
39+
code_access_cost,
3940
)
4041
from ..stack import pop, push
4142

@@ -388,6 +389,9 @@ def extcodecopy(evm: Evm) -> None:
388389
else:
389390
evm.accessed_addresses.add(address)
390391
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
392+
access_gas_cost += code_access_cost(
393+
get_account(evm.message.block_env.state, address).code
394+
)
391395

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

src/ethereum/osaka/vm/instructions/system.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
calculate_gas_extend_memory,
5454
calculate_message_call_gas,
5555
charge_gas,
56+
code_access_cost,
5657
init_code_cost,
5758
max_message_call_gas,
5859
)
@@ -73,15 +74,15 @@ def generic_create(
7374
# This import causes a circular import error
7475
# if it's not moved inside this method
7576
from ...vm.interpreter import (
76-
MAX_CODE_SIZE,
77+
MAX_INIT_CODE_SIZE,
7778
STACK_DEPTH_LIMIT,
7879
process_create_message,
7980
)
8081

8182
call_data = memory_read_bytes(
8283
evm.memory, memory_start_position, memory_size
8384
)
84-
if len(call_data) > 2 * MAX_CODE_SIZE:
85+
if len(call_data) > MAX_INIT_CODE_SIZE:
8586
raise OutOfGasError
8687

8788
create_message_gas = max_message_call_gas(Uint(evm.gas_left))
@@ -375,6 +376,9 @@ def call(evm: Evm) -> None:
375376
else:
376377
evm.accessed_addresses.add(to)
377378
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
379+
access_gas_cost += code_access_cost(
380+
get_account(evm.message.block_env.state, to).code
381+
)
378382

379383
code_address = to
380384
(
@@ -465,6 +469,9 @@ def callcode(evm: Evm) -> None:
465469
else:
466470
evm.accessed_addresses.add(code_address)
467471
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
472+
access_gas_cost += code_access_cost(
473+
get_account(evm.message.block_env.state, code_address).code
474+
)
468475

469476
(
470477
disable_precompiles,
@@ -604,6 +611,9 @@ def delegatecall(evm: Evm) -> None:
604611
else:
605612
evm.accessed_addresses.add(code_address)
606613
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
614+
access_gas_cost += code_access_cost(
615+
get_account(evm.message.block_env.state, code_address).code
616+
)
607617

608618
(
609619
disable_precompiles,
@@ -672,6 +682,9 @@ def staticcall(evm: Evm) -> None:
672682
else:
673683
evm.accessed_addresses.add(to)
674684
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
685+
access_gas_cost += code_access_cost(
686+
get_account(evm.message.block_env.state, to).code
687+
)
675688

676689
code_address = to
677690
(

src/ethereum/osaka/vm/interpreter.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@
6363
from .runtime import get_valid_jump_destinations
6464

6565
STACK_DEPTH_LIMIT = Uint(1024)
66-
MAX_CODE_SIZE = 0x6000
66+
MAX_CODE_SIZE_WITH_NO_ACCESS_COST = 0x6000
67+
MAX_CODE_SIZE = 0x40000
68+
MAX_INIT_CODE_SIZE = 0x80000
6769

6870

6971
@dataclass

0 commit comments

Comments
 (0)