Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
general/code_coverage/eels = EIP-7954 changes only MAX_CODE_SIZE and MAX_INIT_CODE_SIZE in src/ethereum/forks/amsterdam/vm/interpreter.py; the three lines that consume them (the code-deposit size check in process_create_message, the creation-transaction initcode check in transactions.validate_transaction, and the CREATE/CREATE2 initcode checks in vm/instructions/system.py) are each executed on both sides of the limit by the at_max/over_max cases
general/code_coverage/test_coverage = Run fill tests/amsterdam/eip7954_increase_max_contract_size --cov=tests/amsterdam/eip7954_increase_max_contract_size; the at_max/over_max, CREATE/CREATE2 and exact_gas/short_one_gas parametrizations take both arms of every post-state conditional and the suite has no unreachable guard lines
general/code_coverage/missed_lines = No EIP-7954 line is missed; the neighbouring lines in the same functions that a coverage report may show are other EIPs' scope (EIP-3541 0xEF prefix check, EIP-8037/EIP-2780 code-deposit keccak and state-gas charges in process_create_message)
opcode/test/gas_usage/normal = CREATE/CREATE2 gas is unchanged in formula but is now charged over a 128 KiB initcode / 64 KiB deposit. Opcode-level exact gas at the new bound on Amsterdam: tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_max_initcode_size_gas_metering_via_create[exact_gas] (CREATE and CREATE2, initcode_length=fork.max_initcode_size(), caller forwards exactly factory_code.gas_cost + initcode.e
opcode/test/gas_usage/memory_expansion = The expansion formula is untouched; what changed is that CREATE/CREATE2 may now legitimately expand memory by 128 KiB for initcode. Pinned at exactly that size on Amsterdam by tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_oversized_initcode_opcode_no_state_gas[at_max] (CREATE/CREATE2 itself expands memory by fork.max_initcode_size() with new_memory_size metadata; the caller f
opcode/test/gas_usage/out_of_gas_execution = Opcode-level one-gas-short and over-limit-input OOG at the new bounds on Amsterdam: tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_max_initcode_size_gas_metering_via_create[short_one_gas] (CREATE/CREATE2 with a 128 KiB initcode, factory one execution gas short of the exact sequence: no contract, factory slot stays 0) and ::test_oversized_initcode_opcode_no_state_gas[over_max]
opcode/test/gas_usage/order_of_operations/exact = CREATE/CREATE2 keep the same charge order (size check, then base + initcode word cost + memory expansion in the caller, 63/64 forward, initcode execution, code deposit in the child); only the constants moved. Exact-fit of the caller-side stipend at 128 KiB: tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_oversized_initcode_opcode_no_state_gas[at_max] (forwards exactly CREATE ba
opcode/test/gas_usage/order_of_operations/oog = One gas short of the whole CREATE/CREATE2 sequence at 128 KiB initcode on Amsterdam: tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_max_initcode_size_gas_metering_via_create[short_one_gas] (creation fails, no contract, factory slot 0). This is an aggregate one-short; the per-charge isolation at the new maxima (caller stipend -1 and 64 KiB deposit -1) does not exist anywhere an
opcode/test/exceptional_abort = An initcode longer than MAX_INITCODE_SIZE passed to CREATE/CREATE2 is an exceptional abort of the calling frame (all gas consumed), and the threshold is what EIP-7954 moves. Pinned at fork.max_initcode_size()+1 on Amsterdam by tests/shanghai/eip3860_initcode/test_initcode.py::TestCreateInitcode::test_create_opcode_initcode[over_limit_zeros|over_limit_ones x CREATE|CREATE2] (the wrapping CALL returns 0 and the creator
opcode/test/contract_creation/failure/oog = Creation-by-opcode out of gas at the new maxima on Amsterdam is pinned by tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_max_initcode_size_gas_metering_via_create[short_one_gas] (CREATE and CREATE2 over a max-size initcode, one gas short: no contract, factory slot stays 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
general/code_coverage/second_client = Optional
opcode/test/mem_exp = EIP does not add an opcode; CREATE/CREATE2 read initcode from memory exactly as before, only the accepted initcode length grows
opcode/test/stack_overflow = CREATE/CREATE2 stack semantics are unchanged, only the size constants move
opcode/test/stack_underflow = CREATE/CREATE2 stack semantics are unchanged, only the size constants move
opcode/test/stack_complex_operations = CREATE/CREATE2 have no data portion and perform only simple pop/push
opcode/test/execution_context/call = The initcode-size and code-deposit checks do not depend on the frame kind that runs CREATE/CREATE2
opcode/test/execution_context/staticcall = CREATE/CREATE2 have been banned in static context since EIP-214, untouched here
opcode/test/execution_context/delegatecall = CREATE/CREATE2 behaviour under DELEGATECALL is unchanged
opcode/test/execution_context/callcode = CREATE/CREATE2 behaviour under CALLCODE is unchanged
opcode/test/execution_context/initcode/reentry = No stateful behaviour is added; re-creation over the same initcode and address is unchanged
opcode/test/execution_context/set_code = EIP-7702 delegation designators are 23 bytes; delegated execution is untouched by the raised limits
opcode/test/execution_context/tx_context = The size limits do not depend on any transaction property
opcode/test/execution_context/block_context = The size limits do not depend on any block property; activation is tracked under opcode/test/fork_transition/at
opcode/test/return_data = Return-buffer behaviour of CREATE/CREATE2 is unchanged, an over-limit RETURN was already an exceptional halt
opcode/test/gas_usage/out_of_gas_memory = The memory-expansion out-of-gas rule is untouched; the moved size checks are tracked under out_of_bounds
opcode/test/terminating = CREATE/CREATE2 are not terminating opcodes and initcode RETURN/REVERT/halt semantics are unchanged
opcode/test/data_portion = CREATE/CREATE2 have no data portion
opcode/test/contract_creation/failure/insufficient_value = The value/balance check of CREATE/CREATE2 is untouched
opcode/test/contract_creation/failure/collision = The address-collision rule of CREATE/CREATE2 is untouched
opcode/test/contract_creation/recursive = Recursive creation behaviour is untouched
opcode/test/fork_transition/invalid = CREATE/CREATE2 are valid before and after the fork; only the limits change, tracked under fork_transition/at
precompile = EIP does not introduce a new precompile
removed_precompile = EIP does not remove a precompile
system_contract = EIP does not introduce a new system contract
transaction_type = EIP does not introduce a new transaction type; the raised initcode bound on create transactions is tracked under modified_transaction_validity_constraint
block_header_field = EIP does not add any new block header fields
block_body_field = EIP does not add any new block body fields
gas_cost_changes = EIP changes no gas schedule value, only MAX_CODE_SIZE and MAX_INITCODE_SIZE
gas_refunds_changes = EIP does not change any gas refund rule
blob_count_changes = EIP does not introduce any blob count changes
execution_layer_request = EIP does not introduce an execution layer request
new_transaction_validity_constraint = EIP introduces no new validity constraint, it raises the existing EIP-3860 initcode threshold (see modified_transaction_validity_constraint)
block_level_constraint = EIP introduces no block-level validation rule; both limits are checked per contract creation
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from execution_testing import (
Account,
Alloc,
EIPChecklist,
Fork,
Initcode,
Op,
Expand Down Expand Up @@ -55,6 +56,7 @@ def test_over_max_code_size_mainnet(

@pytest.mark.inclusion_test
@pytest.mark.exception_test
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedAfterFork()
def test_over_max_initcode_size_mainnet(
state_test: StateTestFiller,
pre: Alloc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
Alloc,
Block,
BlockchainTestFiller,
EIPChecklist,
Initcode,
Op,
Transaction,
Expand Down Expand Up @@ -82,6 +83,8 @@ def test_max_code_size_fork_transition(


@pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2])
@EIPChecklist.Opcode.Test.ForkTransition.At()
@EIPChecklist.Opcode.Test.ContractCreation.Address()
def test_max_code_size_via_create_fork_transition(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -163,6 +166,8 @@ def test_max_code_size_via_create_fork_transition(


@pytest.mark.exception_test
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedBeforeFork()
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.AcceptedAfterFork()
def test_max_initcode_size_fork_transition(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -217,6 +222,8 @@ def test_max_initcode_size_fork_transition(


@pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2])
@EIPChecklist.Opcode.Test.ForkTransition.At()
@EIPChecklist.Opcode.Test.ContractCreation.Address()
def test_max_initcode_size_via_create_fork_transition(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -301,6 +308,8 @@ def test_max_initcode_size_via_create_fork_transition(


@pytest.mark.exception_test
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedBeforeFork()
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.AcceptedAfterFork()
def test_max_code_size_with_max_initcode_fork_transition(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -400,3 +409,55 @@ def test_parent_max_code_size_across_fork(
}

blockchain_test(pre=pre, blocks=blocks, post=post)


@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.AcceptedBeforeFork() # noqa: E501
def test_parent_max_initcode_size_across_fork(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
fork: TransitionFork,
) -> None:
"""Ensure initcode at the previous max size is valid on both sides."""
parent = fork.transitions_from()
assert parent is not None, "Parent fork must be defined for this test"

initcode = Initcode(
deploy_code=Op.STOP,
initcode_length=parent.max_initcode_size(),
)

alice = pre.fund_eoa()
bob = pre.fund_eoa()

create_address_pre = compute_create_address(address=alice, nonce=0)
create_address_post = compute_create_address(address=bob, nonce=0)

blocks = [
Block(
timestamp=14_999,
txs=[
Transaction(
sender=alice,
to=None,
data=initcode,
)
],
),
Block(
timestamp=15_000,
txs=[
Transaction(
sender=bob,
to=None,
data=initcode,
)
],
),
]

post: dict[Any, Account | None] = {
create_address_pre: Account(code=Op.STOP),
create_address_post: Account(code=Op.STOP),
}

blockchain_test(pre=pre, blocks=blocks, post=post)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Alloc,
Bytecode,
CodeGasMeasure,
EIPChecklist,
Fork,
Initcode,
Op,
Expand Down Expand Up @@ -66,6 +67,11 @@ def test_max_code_size(

@pytest.mark.parametrize("deploy_code_size", DEPLOY_CODE_SIZE_PARAMS)
@pytest.mark.with_all_create_opcodes()
@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Opcode()
@EIPChecklist.Opcode.Test.GasUsage.ExtraGas()
@EIPChecklist.Opcode.Test.OutOfBounds.Verify.Max()
@EIPChecklist.Opcode.Test.OutOfBounds.Verify.MaxPlusOne()
@EIPChecklist.Opcode.Test.ContractCreation.Address()
def test_max_code_size_via_create(
state_test: StateTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -178,6 +184,8 @@ def test_max_code_size_deposit_gas(
state_test(pre=pre, tx=tx, post=post)


@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior()
@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Tx()
def test_max_code_size_with_max_initcode(
state_test: StateTestFiller,
pre: Alloc,
Expand Down Expand Up @@ -285,6 +293,7 @@ def test_max_code_size_self_opcodes(
pytest.param(Op.CREATE2, id="CREATE2"),
],
)
@EIPChecklist.Opcode.Test.OutOfBounds.Verify.MaxPlusOne()
def test_warm_after_failed_create_over_max_code_size(
state_test: StateTestFiller,
pre: Alloc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from execution_testing import (
Account,
Alloc,
EIPChecklist,
Fork,
Initcode,
Op,
Expand All @@ -34,11 +35,18 @@
]

TX_INITCODE_SIZE_PARAMS = [
pytest.param(lambda f: f.max_initcode_size(), id="at_max"),
pytest.param(
lambda f: f.max_initcode_size(),
id="at_max",
marks=EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Tx(),
),
pytest.param(
lambda f: f.max_initcode_size() + 1,
id="over_max",
marks=pytest.mark.exception_test,
marks=[
pytest.mark.exception_test,
EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedAfterFork(),
],
),
]

Expand Down Expand Up @@ -80,6 +88,11 @@ def test_max_initcode_size(

@pytest.mark.parametrize("initcode_size", INITCODE_SIZE_PARAMS)
@pytest.mark.with_all_create_opcodes()
@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Opcode()
@EIPChecklist.Opcode.Test.GasUsage.ExtraGas()
@EIPChecklist.Opcode.Test.OutOfBounds.Verify.Max()
@EIPChecklist.Opcode.Test.OutOfBounds.Verify.MaxPlusOne()
@EIPChecklist.Opcode.Test.ContractCreation.Address()
def test_max_initcode_size_via_create(
state_test: StateTestFiller,
pre: Alloc,
Expand Down