Skip to content

test_intrinsic_execution_gas_exceeds_cap_with_floor_below_cap()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_pricing.py::test_intrinsic_execution_gas_exceeds_cap_with_floor_below_cap@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_pricing.py::test_intrinsic_execution_gas_exceeds_cap_with_floor_below_cap --fork Amsterdam

Reject when intrinsic execution gas exceeds the cap while the calldata floor stays below it, isolating the execution operand of max(intrinsic_execution, calldata_floor).

A large access list with no calldata pushes the execution intrinsic over the cap while the floor stays well below it, and gas_limit covers the total intrinsic so the sufficiency check passes. The explicit floor < cap assertion guarantees the rejection comes from the execution operand, so a client that compares only the calldata floor against the cap would wrongly accept the transaction.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_pricing.py
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
@pytest.mark.inclusion_test
@pytest.mark.exception_test
@pytest.mark.valid_from("EIP8037")
def test_intrinsic_execution_gas_exceeds_cap_with_floor_below_cap(
    state_test: StateTestFiller,
    pre: Alloc,
    fork: Fork,
) -> None:
    """
    Reject when intrinsic *execution* gas exceeds the cap while the calldata
    floor stays below it, isolating the execution operand of
    ``max(intrinsic_execution, calldata_floor)``.

    A large access list with no calldata pushes the execution intrinsic over
    the cap while the floor stays well below it, and ``gas_limit`` covers
    the total intrinsic so the sufficiency check passes. The explicit
    ``floor < cap`` assertion guarantees the rejection comes from the
    execution operand, so a client that compares only the calldata floor
    against the cap would wrongly accept the transaction.
    """
    cap = fork.transaction_gas_limit_cap()
    assert cap is not None
    floor_cost = fork.transaction_data_floor_cost_calculator()
    intrinsic = fork.transaction_intrinsic_cost_calculator()

    access_list = _access_list_over_execution_cap(
        fork, cap, margin_num=5, margin_den=4
    )
    execution = intrinsic(
        access_list=access_list,
        return_cost_deducted_prior_execution=True,
    )
    floor = floor_cost(data=b"", access_list=access_list)
    tx_gas = execution + 1_000_000

    assert execution > cap, "execution operand must exceed the cap"
    assert floor < cap, "calldata floor must stay below the cap"
    assert execution <= tx_gas, "sufficiency check must not fire"

    tx = Transaction(
        ty=1,
        to=pre.deploy_contract(code=Op.STOP),
        gas_limit=tx_gas,
        access_list=access_list,
        sender=pre.fund_eoa(),
        error=TransactionException.INTRINSIC_GAS_TOO_LOW,
    )
    state_test(pre=pre, post={}, tx=tx)

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.