Skip to content

test_access_list_slot_warmth_is_address_scoped()

Documentation for tests/amsterdam/eip8038_state_access_gas_cost_increase/test_access_list_gas.py::test_access_list_slot_warmth_is_address_scoped@c74f1a67.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8038_state_access_gas_cost_increase/test_access_list_gas.py::test_access_list_slot_warmth_is_address_scoped --fork Amsterdam

Access-list slot warmth is scoped to (address, slot).

Slot s of account A is listed in the access list. Reading slot s of A is warm (WARM_SLOAD); reading the same slot number of a different account B is cold (COLD_STORAGE_ACCESS).

Source code in tests/amsterdam/eip8038_state_access_gas_cost_increase/test_access_list_gas.py
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
@EIPChecklist.GasCostChanges.Test.GasUpdatesMeasurement()
def test_access_list_slot_warmth_is_address_scoped(
    state_test: StateTestFiller,
    env: Environment,
    pre: Alloc,
    fork: Fork,
) -> None:
    """
    Access-list slot warmth is scoped to ``(address, slot)``.

    Slot ``s`` of account ``A`` is listed in the access list. Reading
    slot ``s`` of ``A`` is warm (``WARM_SLOAD``); reading the same slot
    number of a different account ``B`` is cold (``COLD_STORAGE_ACCESS``).
    """
    slot = 0x42
    warm_gas = Op.SLOAD(key_warm=True).gas_cost(fork)
    cold_gas = Op.SLOAD(key_warm=False).gas_cost(fork)

    # Both accounts read their own slot ``s`` with the same wrapper, so the
    # overhead that strips the operand PUSH is identical for each.
    measured_read = Op.SLOAD(slot)
    overhead = measured_read.gas_cost(fork) - cold_gas

    # B reads its own slot ``s`` (cold), storing the result in B's slot 1.
    account_b = pre.deploy_contract(
        code=CodeGasMeasure(
            code=measured_read,
            overhead_cost=overhead,
            extra_stack_items=1,
            sstore_key=1,
        ),
        storage={slot: 1},
    )

    # A reads its own slot ``s`` (warm via the access list), then calls B.
    account_a = pre.deploy_contract(
        code=CodeGasMeasure(
            code=measured_read,
            overhead_cost=overhead,
            extra_stack_items=1,
            sstore_key=1,
        )
        + Op.POP(Op.CALL(gas=200_000, address=account_b)),
        storage={slot: 1},
    )

    tx = Transaction(
        to=account_a,
        sender=pre.fund_eoa(),
        # Only A's slot is listed; B's identical slot stays cold.
        access_list=[AccessList(address=account_a, storage_keys=[slot])],
    )

    post = {
        account_a: Account(storage={1: warm_gas, slot: 1}),
        account_b: Account(storage={1: cold_gas, slot: 1}),
    }
    state_test(env=env, pre=pre, post=post, tx=tx)

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.