Skip to content

test_tx_gas_above_cap_at_transition()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_fork_transition.py::test_tx_gas_above_cap_at_transition@5c024cbb.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_fork_transition.py::test_tx_gas_above_cap_at_transition --fork Amsterdam

Test tx.gas > TX_MAX_GAS_LIMIT validity at the EIP-8037 transition.

Before EIP-8037, EIP-7825 rejects any tx with gas > TX_MAX_GAS_LIMIT. After EIP-8037 it's allowed — the excess feeds the state gas reservoir. This test sends a tx at the cap (always valid) and one above the cap (rejected before, accepted after).

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_fork_transition.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.AcceptedBeforeFork()
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedBeforeFork()
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.AcceptedAfterFork()
@EIPChecklist.ModifiedTransactionValidityConstraint.Test.ForkTransition.RejectedAfterFork()
@pytest.mark.parametrize(
    "gas_above_cap",
    [
        pytest.param(False, id="at_cap"),
        pytest.param(
            True,
            id="above_cap",
            marks=pytest.mark.exception_test,
        ),
    ],
)
def test_tx_gas_above_cap_at_transition(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    gas_above_cap: bool,
    fork: Fork,
) -> None:
    """
    Test tx.gas > TX_MAX_GAS_LIMIT validity at the EIP-8037 transition.

    Before EIP-8037, EIP-7825 rejects any tx with gas > TX_MAX_GAS_LIMIT.
    After EIP-8037 it's allowed — the excess feeds the state gas
    reservoir. This test sends a tx at the cap (always valid) and one
    above the cap (rejected before, accepted after).
    """
    after_fork = fork.fork_at(timestamp=15_000)
    gas_limit_cap = after_fork.transaction_gas_limit_cap()
    assert gas_limit_cap is not None
    storage_before = Storage()
    contract_before = pre.deploy_contract(
        code=(Op.SSTORE(storage_before.store_next(1), 1)),
    )

    storage_after = Storage()
    contract_after = pre.deploy_contract(
        code=(Op.SSTORE(storage_after.store_next(1), 1)),
    )

    gas_limit = gas_limit_cap + 1 if gas_above_cap else gas_limit_cap

    # Before fork: above-cap tx is rejected by EIP-7825
    before_error = (
        TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM
        if gas_above_cap
        else None
    )

    blocks = [
        Block(
            timestamp=14_999,
            txs=[
                Transaction(
                    to=contract_before,
                    gas_limit=gas_limit,
                    sender=pre.fund_eoa(),
                    error=before_error,
                ),
            ],
            exception=before_error,
        ),
        # After fork: above-cap tx is now valid (excess feeds reservoir)
        Block(
            timestamp=15_000,
            txs=[
                Transaction(
                    to=contract_after,
                    gas_limit=gas_limit,
                    sender=pre.fund_eoa(),
                ),
            ],
        ),
    ]

    post = {
        contract_before: Account(
            storage=storage_before if not gas_above_cap else {0: 0},
        ),
        contract_after: Account(storage=storage_after),
    }

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

Parametrized Test Cases

This test generates 2 parametrized test cases across 1 fork.