Skip to content

test_extcodesize_empty_account_returns_zero()

Documentation for tests/amsterdam/eip8038_state_access_gas_cost_increase/test_ext_code_opcodes_gas.py::test_extcodesize_empty_account_returns_zero@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8038_state_access_gas_cost_increase/test_ext_code_opcodes_gas.py::test_extcodesize_empty_account_returns_zero --fork Amsterdam

Pay the surcharge on an empty target while EXTCODESIZE returns 0.

The size returned for an empty/non-existent account is 0, which confirms the target genuinely has no code: the measured COLD_ACCOUNT_ACCESS + WARM_ACCESS (cold) / 2 * WARM_ACCESS (warm) cost is therefore unambiguously the surcharge applied to an empty account, not an artifact of the target accidentally holding code.

Source code in tests/amsterdam/eip8038_state_access_gas_cost_increase/test_ext_code_opcodes_gas.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
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
@EIPChecklist.GasCostChanges.Test.GasUpdatesMeasurement()
@pytest.mark.parametrize("warm", [False, True], ids=["cold", "warm"])
def test_extcodesize_empty_account_returns_zero(
    state_test: StateTestFiller,
    env: Environment,
    pre: Alloc,
    fork: Fork,
    warm: bool,
) -> None:
    """
    Pay the surcharge on an empty target while ``EXTCODESIZE`` returns 0.

    The size returned for an empty/non-existent account is ``0``, which
    confirms the target genuinely has no code: the measured
    ``COLD_ACCOUNT_ACCESS + WARM_ACCESS`` (cold) / ``2 * WARM_ACCESS``
    (warm) cost is therefore unambiguously the surcharge applied to an
    empty account, not an artifact of the target accidentally holding code.
    """
    # Never deployed: no code, no balance, non-existent account.
    empty_addr = pre.nonexistent_account()

    expected_gas = Op.EXTCODESIZE(address_warm=warm).gas_cost(fork)

    # Measure the access cost and, separately, store the returned size so
    # the empty-account 0 result is asserted alongside the pricing. The
    # measured opcode carries the runtime warmth so the overhead reduces to
    # the address PUSH alone.
    storage = Storage()
    measured_code = Op.EXTCODESIZE.with_metadata(address_warm=warm)(empty_addr)
    gas_slot = storage.store_next(expected_gas, "extcodesize_empty_gas")
    size_slot = storage.store_next(0, "extcodesize_empty_size")
    code = CodeGasMeasure(
        code=measured_code,
        overhead_cost=measured_code.gas_cost(fork)
        - Op.EXTCODESIZE(address_warm=warm).gas_cost(fork),
        extra_stack_items=1,
        sstore_key=gas_slot,
    ) + Op.SSTORE(size_slot, Op.EXTCODESIZE(empty_addr))
    measure_address = pre.deploy_contract(code=code)

    tx = Transaction(
        to=measure_address,
        sender=pre.fund_eoa(),
        access_list=[AccessList(address=empty_addr, storage_keys=[])]
        if warm
        else None,
    )

    post = {measure_address: Account(storage=storage)}
    state_test(env=env, pre=pre, post=post, tx=tx)

Parametrized Test Cases

This test generates 2 parametrized test cases across 1 fork.