|
| 1 | +""" |
| 2 | +abstract: Tests [EIP-663: SWAPN, DUPN and EXCHANGE instructions](https://eips.ethereum.org/EIPS/eip-663) |
| 3 | + Tests for the SWAPN instruction. |
| 4 | +""" # noqa: E501 |
| 5 | + |
| 6 | +import pytest |
| 7 | + |
| 8 | +from ethereum_test_tools import Account, Environment, StateTestFiller, TestAddress, Transaction |
| 9 | +from ethereum_test_tools.eof.v1 import Container, Section |
| 10 | +from ethereum_test_tools.eof.v1.constants import NON_RETURNING_SECTION |
| 11 | +from ethereum_test_tools.vm.opcode import Opcodes as Op |
| 12 | + |
| 13 | +from ..eip3540_eof_v1.spec import EOF_FORK_NAME |
| 14 | +from . import REFERENCE_SPEC_GIT_PATH, REFERENCE_SPEC_VERSION |
| 15 | + |
| 16 | +REFERENCE_SPEC_GIT_PATH = REFERENCE_SPEC_GIT_PATH |
| 17 | +REFERENCE_SPEC_VERSION = REFERENCE_SPEC_VERSION |
| 18 | + |
| 19 | + |
| 20 | +@pytest.mark.valid_from(EOF_FORK_NAME) |
| 21 | +def test_exchange_all_valid_immediates( |
| 22 | + tx: Transaction, |
| 23 | + state_test: StateTestFiller, |
| 24 | +): |
| 25 | + """ |
| 26 | + Test case for all valid SWAPN immediates. |
| 27 | + """ |
| 28 | + n = 256 |
| 29 | + s = 34 |
| 30 | + values = range(0x3E8, 0x3E8 + s) |
| 31 | + |
| 32 | + eof_code = Container( |
| 33 | + sections=[ |
| 34 | + Section.Code( |
| 35 | + code=b"".join(Op.PUSH2(v) for v in values) |
| 36 | + + b"".join(Op.EXCHANGE(x) for x in range(0, n)) |
| 37 | + + b"".join((Op.PUSH1(x) + Op.SSTORE) for x in range(0, s)) |
| 38 | + + Op.STOP, |
| 39 | + code_inputs=0, |
| 40 | + code_outputs=NON_RETURNING_SECTION, |
| 41 | + max_stack_height=s + 1, |
| 42 | + ) |
| 43 | + ], |
| 44 | + ) |
| 45 | + |
| 46 | + pre = { |
| 47 | + TestAddress: Account(balance=1_000_000_000), |
| 48 | + tx.to: Account(code=eof_code), |
| 49 | + } |
| 50 | + |
| 51 | + # this does the same full-loop exchange |
| 52 | + values_rotated = list(range(0x3E8, 0x3E8 + s)) |
| 53 | + for e in range(0, n): |
| 54 | + a = (e >> 4) + 1 |
| 55 | + b = (e & 0x0F) + 1 + a |
| 56 | + tmp = values_rotated[a] |
| 57 | + values_rotated[a] = values_rotated[b] |
| 58 | + values_rotated[b] = tmp |
| 59 | + |
| 60 | + post = {tx.to: Account(storage=dict(zip(range(0, s), reversed(values_rotated))))} |
| 61 | + |
| 62 | + state_test( |
| 63 | + env=Environment(), |
| 64 | + pre=pre, |
| 65 | + post=post, |
| 66 | + tx=tx, |
| 67 | + ) |
0 commit comments