Skip to content

test_slotnum_at_fork_transition()

Documentation for tests/amsterdam/eip7843_slotnum/test_fork_transition.py::test_slotnum_at_fork_transition@9c2813ee.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip7843_slotnum/test_fork_transition.py::test_slotnum_at_fork_transition --fork Amsterdam

Test SLOTNUM behavior across the EIP-7843 fork transition.

Before EIP-7843, opcode 0x4B is undefined: execution halts with an invalid-opcode exception and consumes all gas, so no SSTORE is observed.

From EIP-7843 onward, SLOTNUM pushes the block's slot number provided by the consensus layer and the SSTORE succeeds.

The contract keys storage by block number so each block's outcome is independently visible in the final post-state:

  • block 1 (pre-fork): slot 1 stays 0 — execution halted before SSTORE.
  • block 2 (transition): slot 2 == at_fork_slot.
  • block 3 (post-fork): slot 3 == post_fork_slot.
Source code in tests/amsterdam/eip7843_slotnum/test_fork_transition.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@pytest.mark.valid_at_transition_to("EIP7843")
def test_slotnum_at_fork_transition(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
) -> None:
    """
    Test SLOTNUM behavior across the EIP-7843 fork transition.

    Before EIP-7843, opcode 0x4B is undefined: execution halts with an
    invalid-opcode exception and consumes all gas, so no SSTORE is observed.

    From EIP-7843 onward, SLOTNUM pushes the block's slot number provided
    by the consensus layer and the SSTORE succeeds.

    The contract keys storage by block number so each block's outcome is
    independently visible in the final post-state:

    * block 1 (pre-fork): slot 1 stays 0 — execution halted before SSTORE.
    * block 2 (transition): slot 2 == ``at_fork_slot``.
    * block 3 (post-fork): slot 3 == ``post_fork_slot``.
    """
    sender = pre.fund_eoa()
    contract = pre.deploy_contract(Op.SSTORE(Op.NUMBER, Op.SLOTNUM) + Op.STOP)

    at_fork_slot = 200
    post_fork_slot = 201

    blocks = [
        Block(
            timestamp=ts,
            slot_number=slot,
            txs=[Transaction(sender=sender, to=contract, gas_limit=100_000)],
        )
        for ts, slot in [
            (14_999, None),
            (15_000, at_fork_slot),
            (15_001, post_fork_slot),
        ]
    ]
    post = {
        contract: Account(
            storage={
                1: 0,
                2: at_fork_slot,
                3: post_fork_slot,
            },
        ),
    }

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

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.