Skip to content

test_code_deposit_state_gas_scales_with_size()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_code_deposit_state_gas_scales_with_size@622620d8.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_code_deposit_state_gas_scales_with_size --fork Amsterdam

Test code deposit state gas scales linearly with code size.

The code deposit charges len(code) * cost_per_state_byte of state gas. Larger deployed code requires proportionally more state gas. When code exceeds MAX_CODE_SIZE, the size check rejects before any gas is charged and the contract is not deployed.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
@pytest.mark.parametrize(
    "code_size",
    [
        pytest.param(1, id="tiny_code"),
        pytest.param(32, id="one_word"),
        pytest.param(256, id="small_contract"),
        pytest.param(1024, id="medium_contract"),
        pytest.param("max", id="max_code_size"),
        pytest.param("max+1", id="over_max_code_size"),
    ],
)
@pytest.mark.valid_from("EIP8037")
def test_code_deposit_state_gas_scales_with_size(
    state_test: StateTestFiller,
    pre: Alloc,
    code_size: int | str,
    fork: Fork,
) -> None:
    """
    Test code deposit state gas scales linearly with code size.

    The code deposit charges len(code) * cost_per_state_byte of state
    gas. Larger deployed code requires proportionally more state gas.
    When code exceeds MAX_CODE_SIZE, the size check rejects before
    any gas is charged and the contract is not deployed.
    """
    if code_size == "max":
        code_size = fork.max_code_size()
    elif code_size == "max+1":
        code_size = fork.max_code_size() + 1
    assert isinstance(code_size, int)

    # State gas: new account + code deposit
    total_state_gas = fork.create_state_gas(code_size=code_size)

    init_code = Op.RETURN(
        0, code_size, new_memory_size=code_size, code_deposit_size=code_size
    )

    total_execution_gas = fork.transaction_intrinsic_cost_calculator()(
        calldata=bytes(init_code), contract_creation=True
    ) + init_code.execution_cost(fork)

    sender = pre.fund_eoa()
    tx = Transaction(
        to=None,
        data=init_code,
        state_gas_reservoir=total_state_gas,
        sender=sender,
    )

    create_address = compute_create_address(address=sender, nonce=0)
    gas_limit_cap = fork.transaction_gas_limit_cap()
    assert gas_limit_cap is not None

    if code_size > fork.max_code_size():
        post = {create_address: Account.NONEXISTENT}
        # The halt rolls the reservoir back, so the sender pays the cap.
        expected_gas_used = gas_limit_cap
    else:
        post = {}
        assert total_state_gas > total_execution_gas, (
            "requires state gas > execution gas"
        )
        expected_gas_used = max(total_execution_gas, total_state_gas)

    state_test(
        pre=pre,
        post=post,
        tx=tx,
        blockchain_test_header_verify=Header(gas_used=expected_gas_used),
    )

Parametrized Test Cases

This test generates 6 parametrized test cases across 1 fork.