Skip to content

test_top_level_failure_zeros_block_state_gas()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_reservoir.py::test_top_level_failure_zeros_block_state_gas@5c024cbb.

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_top_level_failure_zeros_block_state_gas --fork Amsterdam

Verify the block header reflects zero execution state gas after a top level failure.

With state_gas_used zeroed on failure, block_state_gas_used excludes any state gas consumed during the failed transaction and the block header gas_used falls back to the regular gas component alone.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_reservoir.py
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
@pytest.mark.parametrize(
    "failure_mode",
    [
        pytest.param("revert", id="revert"),
        pytest.param("halt", id="halt"),
        pytest.param("oog", id="oog"),
    ],
)
@pytest.mark.valid_from("EIP8037")
def test_top_level_failure_zeros_block_state_gas(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: Fork,
    failure_mode: str,
) -> None:
    """
    Verify the block header reflects zero execution state gas after a
    top level failure.

    With `state_gas_used` zeroed on failure, `block_state_gas_used`
    excludes any state gas consumed during the failed transaction and
    the block header `gas_used` falls back to the regular gas
    component alone.
    """
    gas_limit_cap = fork.transaction_gas_limit_cap()
    assert gas_limit_cap is not None
    sstore_state_gas = Op.SSTORE(new_value=1).state_cost(fork)
    intrinsic_cost = fork.transaction_intrinsic_cost_calculator()()

    if failure_mode == "revert":
        code = Op.SSTORE(0, 1) + Op.REVERT(0, 0)
    elif failure_mode == "halt":
        code = Op.SSTORE(0, 1) + Op.INVALID
    else:
        code = Op.SSTORE(0, 1) + Om.OOG
    contract = pre.deploy_contract(code=code)

    tx_gas = gas_limit_cap + sstore_state_gas
    tx = Transaction(
        to=contract,
        state_gas_reservoir=sstore_state_gas,
        sender=pre.fund_eoa(),
    )

    if failure_mode == "revert":
        expected_block_regular = (
            intrinsic_cost + code.gas_cost(fork) - sstore_state_gas
        )
    else:
        # Exceptional halt and out of gas zero gas_left.
        expected_block_regular = tx_gas - sstore_state_gas

    blockchain_test(
        pre=pre,
        blocks=[
            Block(
                txs=[tx],
                header_verify=Header(gas_used=expected_block_regular),
            ),
        ],
        post={contract: Account(storage={})},
    )

Parametrized Test Cases

This test generates 3 parametrized test cases across 1 fork.