Skip to content

test_creation_tx_state_check_exceeded()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_reservoir.py::test_creation_tx_state_check_exceeded@c74f1a67.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_reservoir.py::test_creation_tx_state_check_exceeded --fork Amsterdam

Verify a creation tx is rejected by the state check.

A creation tx (to=None) goes through the per-dimension inclusion check like any other tx. A filler tx consumes state budget; the creation tx's tx.gas then exceeds the remaining state budget by one while its regular contribution still fits, pinning the rejection to the state dimension.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_reservoir.py
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
@pytest.mark.exception_test
@pytest.mark.valid_from("EIP8037")
def test_creation_tx_state_check_exceeded(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: Fork,
) -> None:
    """
    Verify a creation tx is rejected by the state check.

    A creation tx (`to=None`) goes through the per-dimension inclusion
    check like any other tx. A filler tx consumes state budget; the
    creation tx's `tx.gas` then exceeds the remaining state budget by
    one while its regular contribution still fits, pinning the
    rejection to the state dimension.
    """
    gas_limit_cap = fork.transaction_gas_limit_cap()
    assert gas_limit_cap is not None

    block_gas_limit = 100_000_000

    intrinsic_cost = fork.transaction_intrinsic_cost_calculator()

    num_sstores = 50
    tx1_code = Bytecode()
    for i in range(num_sstores):
        tx1_code = tx1_code + Op.SSTORE(i, 1)
    tx1_contract = pre.deploy_contract(code=tx1_code)

    tx1_state = tx1_code.state_cost(fork)
    tx1_regular = intrinsic_cost() + tx1_code.gas_cost(fork) - tx1_state
    tx1_gas = gas_limit_cap + tx1_state
    state_available = block_gas_limit - tx1_state

    # tx2: full tx.gas exceeds state_available by 1, so rejected.
    tx2_gas = state_available + 1

    # Regular check must pass so rejection is pinned to state.
    regular_available = block_gas_limit - tx1_regular
    assert min(gas_limit_cap, tx2_gas) < regular_available

    tx1 = Transaction(
        to=tx1_contract,
        gas_limit=tx1_gas,
        sender=pre.fund_eoa(),
    )
    tx2 = Transaction(
        to=None,
        gas_limit=tx2_gas,
        sender=pre.fund_eoa(),
        error=TransactionException.GAS_ALLOWANCE_EXCEEDED,
    )

    blockchain_test(
        genesis_environment=Environment(gas_limit=block_gas_limit),
        pre=pre,
        blocks=[
            Block(
                txs=[tx1, tx2],
                gas_limit=block_gas_limit,
                exception=TransactionException.GAS_ALLOWANCE_EXCEEDED,
            )
        ],
        post={},
    )

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.