Skip to content

test_opcode_at_fork_transition()

Documentation for tests/amsterdam/eip8024_dupn_swapn_exchange/test_fork_transition.py::test_opcode_at_fork_transition@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8024_dupn_swapn_exchange/test_fork_transition.py::test_opcode_at_fork_transition --fork Amsterdam

Test DUPN/SWAPN/EXCHANGE behavior across the EIP-8024 fork transition.

Before the fork, opcodes 0xE6-0xE8 are undefined: execution halts with an invalid-opcode exception and no storage write happens.

From the fork onward, the opcode executes and stores its marker. Storage is keyed 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.
  • block 2 (transition): slot 2 == marker.
  • block 3 (post-fork): slot 3 == marker.
Source code in tests/amsterdam/eip8024_dupn_swapn_exchange/test_fork_transition.py
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@EIPChecklist.Opcode.Test.ForkTransition.Invalid()
@EIPChecklist.Opcode.Test.ForkTransition.At()
@pytest.mark.valid_at_transition_to("EIP8024")
@pytest.mark.parametrize("opcode", [Op.DUPN, Op.SWAPN, Op.EXCHANGE])
def test_opcode_at_fork_transition(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    opcode: Op,
) -> None:
    """
    Test DUPN/SWAPN/EXCHANGE behavior across the EIP-8024 fork transition.

    Before the fork, opcodes 0xE6-0xE8 are undefined: execution halts
    with an invalid-opcode exception and no storage write happens.

    From the fork onward, the opcode executes and stores its marker.
    Storage is keyed 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.
    * block 2 (transition): slot 2 == marker.
    * block 3 (post-fork): slot 3 == marker.
    """
    sender = pre.fund_eoa()
    code, marker = marker_storing_code(opcode)
    contract = pre.deploy_contract(code)

    blocks = [
        Block(
            timestamp=ts,
            txs=[Transaction(sender=sender, to=contract)],
        )
        for ts in (
            FORK_TIMESTAMP - 1,
            FORK_TIMESTAMP,
            FORK_TIMESTAMP + 1,
        )
    ]

    post = {
        contract: Account(
            storage={
                1: 0,
                2: marker,
                3: marker,
            },
        ),
    }

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

Parametrized Test Cases

This test generates 3 parametrized test cases across 1 fork.