Skip to content

test_top_frame_new_account_charged_as_state_gas()

Documentation for tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py::test_top_frame_new_account_charged_as_state_gas@a9abd46e.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py::test_top_frame_new_account_charged_as_state_gas --fork Amsterdam

The top-frame NEW_ACCOUNT charge for a value transfer to an empty recipient is state gas, not regular gas. This pins the dimension via the block header gas_used, which the spec computes as max(block_regular_gas, block_state_gas).

Correctly attributed, the NEW_ACCOUNT state gas dominates the small regular intrinsic, so gas_used == NEW_ACCOUNT. A regression mis-classifying the charge as regular gas would instead yield intrinsic_regular + NEW_ACCOUNT.

state_test-based balance assertions (e.g. test_top_frame_state_charge) only observe the sum of the two dimensions, so they cannot distinguish this; a block-level gas_used assertion is required.

Source code in tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def test_top_frame_new_account_charged_as_state_gas(
    fork: Fork,
    pre: Alloc,
    blockchain_test: BlockchainTestFiller,
) -> None:
    """
    The top-frame ``NEW_ACCOUNT`` charge for a value transfer to an
    empty recipient is *state* gas, not regular gas. This pins the
    dimension via the block header ``gas_used``, which the spec
    computes as ``max(block_regular_gas, block_state_gas)``.

    Correctly attributed, the ``NEW_ACCOUNT`` state gas dominates the
    small regular intrinsic, so ``gas_used == NEW_ACCOUNT``. A
    regression mis-classifying the charge as regular gas would instead
    yield ``intrinsic_regular + NEW_ACCOUNT``.

    ``state_test``-based balance assertions (e.g.
    ``test_top_frame_state_charge``) only observe the *sum* of the two
    dimensions, so they cannot distinguish this; a block-level
    ``gas_used`` assertion is required.
    """
    sender = pre.fund_eoa(10**18)
    target = pre.fund_eoa(amount=0)
    value = 1

    intrinsic_regular = fork.transaction_intrinsic_cost_calculator()(
        sends_value=True,
        recipient_type=RecipientType.EMPTY_ACCOUNT,
        return_cost_deducted_prior_execution=True,
    )
    new_account_state_gas = fork.transaction_top_frame_state_gas(
        sends_value=True,
        recipient_type=RecipientType.EMPTY_ACCOUNT,
    )
    # The state charge must dominate the regular intrinsic for the
    # header ``gas_used`` to distinguish a state vs regular
    # mis-classification.
    assert new_account_state_gas > intrinsic_regular, (
        "test only distinguishes the dimension when NEW_ACCOUNT "
        f"({new_account_state_gas}) dominates the regular intrinsic "
        f"({intrinsic_regular})"
    )

    # No EVM bytecode runs (empty recipient), so the only regular gas
    # is the intrinsic and the only state gas is the top-frame
    # ``NEW_ACCOUNT`` charge.
    expected_gas_used = max(intrinsic_regular, new_account_state_gas)

    gas_price = 1_000_000_000
    tx = Transaction(
        sender=sender,
        to=target,
        value=value,
        gas_limit=intrinsic_regular + new_account_state_gas + 1000,
        gas_price=gas_price,
    )

    blockchain_test(
        pre=pre,
        blocks=[
            Block(
                txs=[tx],
                header_verify=Header(gas_used=expected_gas_used),
            ),
        ],
        post={
            sender: Account(nonce=1),
            target: Account(balance=value),
        },
    )

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.