Skip to content

Test Exchange

Documentation for tests/prague/eip7692_eof_v1/eip663_dupn_swapn_exchange/test_exchange.py.

Generate fixtures for these test cases for Prague with:

Prague only:

fill -v tests/prague/eip7692_eof_v1/eip663_dupn_swapn_exchange/test_exchange.py --fork=Prague --evm-bin=/path/to/evm-tool-dev-version
For all forks up to and including Prague:
fill -v tests/prague/eip7692_eof_v1/eip663_dupn_swapn_exchange/test_exchange.py --until=Prague --evm-bin=/path/to/evm-tool-dev-version

Tests EIP-663: SWAPN, DUPN and EXCHANGE instructions

Tests for the EXCHANGE instruction.

test_exchange_all_valid_immediates(eof_state_test)

Test case for all valid EXCHANGE immediates.

Source code in tests/prague/eip7692_eof_v1/eip663_dupn_swapn_exchange/test_exchange.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
@pytest.mark.valid_from(EOF_FORK_NAME)
def test_exchange_all_valid_immediates(eof_state_test: EOFStateTestFiller):
    """
    Test case for all valid EXCHANGE immediates.
    """
    n = 256
    s = 34
    values = range(0x3E8, 0x3E8 + s)

    eof_code = Container(
        sections=[
            Section.Code(
                code=sum(Op.PUSH2[v] for v in values)
                + sum(Op.EXCHANGE[x] for x in range(0, n))
                + sum((Op.PUSH1[x] + Op.SSTORE) for x in range(0, s))
                + Op.STOP,
            )
        ],
    )

    # this does the same full-loop exchange
    values_rotated = list(range(0x3E8, 0x3E8 + s))
    for e in range(0, n):
        a = (e >> 4) + 1
        b = (e & 0x0F) + 1 + a
        temp = values_rotated[a]
        values_rotated[a] = values_rotated[b]
        values_rotated[b] = temp

    post = Account(storage=dict(zip(range(0, s), reversed(values_rotated))))

    eof_state_test(
        tx_sender_funding_amount=1_000_000_000,
        data=eof_code,
        container_post=post,
    )

test_exchange_all_invalid_immediates(eof_test, stack_height, x, y)

Test case for all invalid EXCHANGE immediates.

Source code in tests/prague/eip7692_eof_v1/eip663_dupn_swapn_exchange/test_exchange.py
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
93
94
95
@pytest.mark.parametrize(
    "stack_height,x,y",
    [
        # 2 and 3 are the lowest valid values for x and y, which translates to a
        # zero immediate value.
        pytest.param(0, 2, 3, id="stack_height=0_n=1_m=1"),
        pytest.param(1, 2, 3, id="stack_height=1_n=1_m=1"),
        pytest.param(2, 2, 3, id="stack_height=2_n=1_m=1"),
        pytest.param(17, 2, 18, id="stack_height=17_n=1_m=16"),
        pytest.param(17, 17, 18, id="stack_height=17_n=16_m=1"),
        pytest.param(32, 17, 33, id="stack_height=32_n=16_m=16"),
    ],
)
@pytest.mark.valid_from(EOF_FORK_NAME)
def test_exchange_all_invalid_immediates(
    eof_test: EOFTestFiller,
    stack_height: int,
    x: int,
    y: int,
):
    """
    Test case for all invalid EXCHANGE immediates.
    """
    eof_code = Container(
        sections=[
            Section.Code(
                code=sum(Op.PUSH2[v] for v in range(stack_height))
                + Op.EXCHANGE[x, y]
                + Op.POP * stack_height
                + Op.STOP,
                max_stack_height=stack_height,
            )
        ],
    )

    eof_test(
        data=eof_code,
        expect_exception=EOFException.STACK_UNDERFLOW,
    )