Skip to content

feat(src): EIP-8024 tests added#2021

Merged
marioevz merged 22 commits intoethereum:eips/amsterdam/eip-8024from
felix314159:eip8024
Jan 23, 2026
Merged

feat(src): EIP-8024 tests added#2021
marioevz merged 22 commits intoethereum:eips/amsterdam/eip-8024from
felix314159:eip8024

Conversation

@felix314159
Copy link
Contributor

@felix314159 felix314159 commented Jan 14, 2026

🗒️ Description

uv run fill --clean -v -s tests/amsterdam/eip8024_dupn_swapn_exchange/ --fork=Amsterdam
We need to carefully ensure that the test logic is still correct after the port from EOF to EVM.

🔗 Related Issues or PRs

Solves #1877 and means #1873 can proceed to remove the EOF versions of this.

✅ Checklist

  • All: Ran fast tox checks to avoid unnecessary CI fails, see also Code Standards and Enabling Pre-commit Checks:
    uvx tox -e static
  • All: PR title adheres to the repo standard - it will be used as the squash commit message and should start type(scope):.
  • All: Considered adding an entry to CHANGELOG.md.
  • All: Considered updating the online docs in the ./docs/ directory.
  • All: Set appropriate labels for the changes (only maintainers can apply labels).
  • Tests: Ran mkdocs serve locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.
  • Tests: For PRs implementing a missed test case, update the post-mortem document to add an entry the list.
  • Ported Tests: All converted JSON/YML tests from ethereum/tests or tests/static have been assigned @ported_from marker.

Cute Animal Picture

@felix314159 felix314159 changed the base branch from forks/amsterdam to eips/amsterdam/eip-8024 January 14, 2026 11:13

"""
# STACK
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to check stack height for potential stack overflow/underflow. Similarly, this was guaranteed to be safe by EOF, now it's wild west again. You should also quickly realize that you are not able to follow regular scheme: stack, gas, operation. You have to decode the immediate data before checking the stack.

charge_gas(evm, GAS_VERY_LOW)

# OPERATION
immediate_data = evm.code[evm.pc + Uint(1)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i appreciate that u take the time to review this but the feedback would be more helpful if you explained why something is wrong + what the fix is. ty for your attention to this matter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was commuting... here you need to check if the immediate_data is even there (without EOF you don't have such guarantees).

@codecov
Copy link

codecov bot commented Jan 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.33%. Comparing base (3b9b018) to head (e7b2bb9).
⚠️ Report is 1 commits behind head on eips/amsterdam/eip-8024.

Additional details and impacted files
@@                     Coverage Diff                     @@
##           eips/amsterdam/eip-8024    #2021      +/-   ##
===========================================================
+ Coverage                    86.16%   86.33%   +0.16%     
===========================================================
  Files                          599      599              
  Lines                        39527    39578      +51     
  Branches                      3780     3789       +9     
===========================================================
+ Hits                         34059    34170     +111     
+ Misses                        4847     4817      -30     
+ Partials                       621      591      -30     
Flag Coverage Δ
unittests 86.33% <100.00%> (+0.16%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@spencer-tb spencer-tb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels good to me so far. Do we need to add the decode functions to packages/testings or import them from EELS:

def decode_single(x: int) -> int:
    """EIP-8024 decode for DUPN/SWAPN."""
    if not (0 <= x <= 90 or 128 <= x <= 255):
        return 0  # Invalid range
    if x <= 90:
        return x + 17
    else:
        return x - 20

def decode_pair(x: int) -> tuple[int, int]:
    """EIP-8024 decode for EXCHANGE."""
    if not (0 <= x <= 79 or 128 <= x <= 255):
        return 1, 2  # Invalid range fallback
    k = x if x <= 79 else x - 48
    q, r = divmod(k, 16)
    if q < r:
        return q + 1, r + 1
    else:
        return r + 1, 29 - q

Then use them within opcodes.py, updating the modifier functions:

def _dupn_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]:
    imm = int.from_bytes(data, "big")
    n = _decode_single(imm)  # Was: imm + 1
    min_stack_height = n
    return 0, 1, min_stack_height, min_stack_height + 1
...
def _exchange_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]:
    imm = int.from_bytes(data, "big")
    n, m = _decode_pair(imm)  # Was: nibble extraction
    min_stack_height = max(n, m) + 1
    return 0, 0, min_stack_height, min_stack_height

@spencer-tb spencer-tb added this to the amsterdam milestone Jan 14, 2026
Copy link
Member

@chfast chfast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comments apply to all new instructions.

charge_gas(evm, GAS_VERY_LOW)

# OPERATION
immediate_data = evm.code[evm.pc + Uint(1)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was commuting... here you need to check if the immediate_data is even there (without EOF you don't have such guarantees).


"""
# STACK
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to check stack height for potential stack overflow/underflow. Similarly, this was guaranteed to be safe by EOF, now it's wild west again. You should also quickly realize that you are not able to follow regular scheme: stack, gas, operation. You have to decode the immediate data before checking the stack.

@felix314159
Copy link
Contributor Author

Feels good to me so far. Do we need to add the decode functions to packages/testings or import them from EELS:

def decode_single(x: int) -> int:
    """EIP-8024 decode for DUPN/SWAPN."""
    if not (0 <= x <= 90 or 128 <= x <= 255):
        return 0  # Invalid range
    if x <= 90:
        return x + 17
    else:
        return x - 20

def decode_pair(x: int) -> tuple[int, int]:
    """EIP-8024 decode for EXCHANGE."""
    if not (0 <= x <= 79 or 128 <= x <= 255):
        return 1, 2  # Invalid range fallback
    k = x if x <= 79 else x - 48
    q, r = divmod(k, 16)
    if q < r:
        return q + 1, r + 1
    else:
        return r + 1, 29 - q

Then use them within opcodes.py, updating the modifier functions:

def _dupn_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]:
    imm = int.from_bytes(data, "big")
    n = _decode_single(imm)  # Was: imm + 1
    min_stack_height = n
    return 0, 1, min_stack_height, min_stack_height + 1
...
def _exchange_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]:
    imm = int.from_bytes(data, "big")
    n, m = _decode_pair(imm)  # Was: nibble extraction
    min_stack_height = max(n, m) + 1
    return 0, 0, min_stack_height, min_stack_height

IMO we should try to avoid duplication of logic. So keep it as is (implement once in EELS and then just import from there)

@felix314159
Copy link
Contributor Author

Previous commit is for testing this eip modifying pr

Copy link
Member

@marioevz marioevz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments on the tests, thanks!

@spencer-tb
Copy link
Contributor

@felix314159 felix314159 changed the title feat(src): EIP-8024 port from EOF to 'legacy' EVM feat(src): EIP-8024 tests added Jan 16, 2026
@fselmo fselmo changed the base branch from eips/amsterdam/eip-8024 to forks/amsterdam January 16, 2026 23:28
@fselmo fselmo changed the base branch from forks/amsterdam to eips/amsterdam/eip-8024 January 16, 2026 23:29
@marioevz marioevz modified the milestones: amsterdam, bal devnet-2 Jan 19, 2026
@felix314159 felix314159 changed the base branch from eips/amsterdam/eip-8024 to forks/amsterdam January 20, 2026 15:53
@felix314159 felix314159 changed the base branch from forks/amsterdam to eips/amsterdam/eip-8024 January 20, 2026 15:54
Copy link
Contributor

@spencer-tb spencer-tb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a small catch, added below. Can we confirm that these tests here are all implemented or take note?
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8024.md#test-cases

Assembly/Disassembly test vectors:

  • e6005b [DUPN 17, JUMPDEST]
  • e6605b [INVALID_DUPN, PUSH1 0x5b]
  • e7610000 [INVALID_SWAPN, PUSH2 0x0000]
  • e65f [INVALID_DUPN, PUSH0]
  • e812 [EXCHANGE 2 3]
  • e8d0 [EXCHANGE 1 19]
  • e850 [INVALID_EXCHANGE, POP]

Execution test vectors:

  • 60016000808080808080808080808080808080e6 18 stack items (DUPN at end of code)
  • 600160008080808080808080808080808080806002e7 18 stack items (SWAPN at end of code)
  • 600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060 006000600060016002e8 30 stack items, top=2, bottom=1

@marioevz marioevz requested a review from fselmo January 21, 2026 17:01
Copy link
Contributor

@fselmo fselmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass here. Other comments have addressed the immediate test cases that came to mind. I left some additional minor comments.

@felix314159
Copy link
Contributor Author

I think a small catch, added below. Can we confirm that these tests here are all implemented or take note? https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8024.md#test-cases

Assembly/Disassembly test vectors:

* `e6005b` [DUPN 17, JUMPDEST]

* `e6605b` [INVALID_DUPN, PUSH1 0x5b]

* `e7610000` [INVALID_SWAPN, PUSH2 0x0000]

* `e65f` [INVALID_DUPN, PUSH0]

* `e812` [EXCHANGE 2 3]

* `e8d0` [EXCHANGE 1 19]

* `e850` [INVALID_EXCHANGE, POP]

Execution test vectors:

* `60016000808080808080808080808080808080e6` 18 stack items (DUPN at end of code)

* `600160008080808080808080808080808080806002e7` 18 stack items (SWAPN at end of code)

* `600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060   006000600060016002e8` 30 stack items, top=2, bottom=1

thanks! adding them to test_eip_vectors.py in my next commit

@felix314159 felix314159 changed the base branch from eips/amsterdam/eip-8024 to forks/amsterdam January 22, 2026 11:15
@felix314159 felix314159 changed the base branch from forks/amsterdam to eips/amsterdam/eip-8024 January 22, 2026 11:15
@felix314159 felix314159 marked this pull request as ready for review January 22, 2026 11:15
Copy link
Contributor

@gurukamath gurukamath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just left some typing and readability observations from an EELS perspective

Copy link
Member

@marioevz marioevz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed SWAPN + DUPN portion of the tests and signing off for that part, leaving follow up tests in the appropriate tracking issue here: #1877 (comment)

Amazing work so far @felix314159! 🎉

Copy link
Member

@marioevz marioevz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two more comments.

@marioevz marioevz merged commit 1a231a6 into ethereum:eips/amsterdam/eip-8024 Jan 23, 2026
18 of 20 checks passed
fselmo pushed a commit to fselmo/execution-specs that referenced this pull request Jan 23, 2026
github-actions bot pushed a commit that referenced this pull request Jan 23, 2026
github-actions bot pushed a commit that referenced this pull request Jan 26, 2026
github-actions bot pushed a commit that referenced this pull request Jan 29, 2026
fselmo pushed a commit that referenced this pull request Feb 3, 2026
felix314159 added a commit to felix314159/execution-specs that referenced this pull request Feb 4, 2026
spencer-tb pushed a commit that referenced this pull request Feb 11, 2026
fselmo pushed a commit to fselmo/execution-specs that referenced this pull request Feb 12, 2026
fselmo pushed a commit that referenced this pull request Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants