Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precompile modexp test cases #364

Merged
merged 28 commits into from
Jan 17, 2024

Conversation

jochem-brouwer
Copy link
Member

@jochem-brouwer jochem-brouwer commented Dec 20, 2023

πŸ—’οΈ Description

This adds a few test cases for the ModExp precompile introduced in Byzantium.

Tested with: evm version 1.13.4-stable-3f907d6a, solc version 0.8.23+commit.f704f362.Linux.gpp

πŸ”— Related Issues

Part of these test cases where consensus bugs found in EthereumJS, see the issue: ethereumjs/ethereumjs-monorepo#3168 and the PR: ethereumjs/ethereumjs-monorepo#3169

βœ… Checklist

  • All: Set appropriate labels for the changes.
  • All: Considered squashing commits to improve commit history.
  • All: Added an entry to CHANGELOG.md.
  • All: Considered updating the online docs in the ./docs/ directory.
  • Tests: Included the type and version of evm t8n tool used to locally execute test cases: e.g., ref with commit hash or geth 1.13.1-stable-3f40e65.
  • Tests: Ran mkdocs serve locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.

@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Dec 20, 2023

I need some help starting with the Tox validation. Is there a way to auto-fix my files?

Fixed!

@jochem-brouwer jochem-brouwer marked this pull request as draft December 20, 2023 18:13
Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

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

Hey @jochem-brouwer, thanks for contributing!

Despite draft status, I think it's worth mentioning that a test can't call state_test multiple times within one test function execution (the framework should really test for this and raise an error if this condition is violated - I just created #365 to address this).

Instead, you can parametrize the test using pytest with the test vectors defined in data. Then the test function will get executed multiple times, once for each test vector. See jochem-brouwer#1.

@jochem-brouwer
Copy link
Member Author

@danceratopz Thanks for the follow-up PR πŸ˜„

Although I have not added all cases from the EIP test file, I think this is ready for review. If you want, I can also add the remaining tests from the EIP.

@jochem-brouwer jochem-brouwer marked this pull request as ready for review December 21, 2023 16:50
@jochem-brouwer
Copy link
Member Author

Note: I can not set labels for the PR, and I am assuming that if this gets merged, it will be merged via a squash-and-merge. I have not yet ticked those boxes.

@danceratopz danceratopz added scope:tests Scope: Test cases type:feat type: Feature labels Dec 22, 2023
@jochem-brouwer
Copy link
Member Author

I have updated and also added the 2 remaining cases in the EIP.

@jochem-brouwer
Copy link
Member Author

Happy new years everyone πŸ˜„

Could someone take a look at this PR? I think it is ready-to-merge, except this spell issue (see my comment here: #364 (comment))

CC @danceratopz @marioevz

@danceratopz
Copy link
Member

Happy new years everyone πŸ˜„

Could someone take a look at this PR? I think it is ready-to-merge, except this spell issue (see my comment here: #364 (comment))

CC @danceratopz @marioevz

Happy New Years @jochem-brouwer! Yup, will do!

Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

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

Hey @jochem-brouwer sorry for the delay!

This is looking really good, below are a few suggestions.

After you've looked at these comments, I might make a suggestion how to change the test IDs to make them more compact and re-usable in the console. Currently, they're a little bit messy to copy-paste and use them in the console due to the single quotes and spaces:

tests/byzantium/precompiles/test_05_modexp.py::test_modexp[fork_Byzantium-input_['', '', '02']-output_['0x01', '0x01']]
tests/byzantium/precompiles/test_05_modexp.py::test_modexp[fork_Byzantium-input_['', '', '0002']-output_['0x01', '0x0001']]
tests/byzantium/precompiles/test_05_modexp.py::test_modexp[fork_Byzantium-input_['00', '00', '02']-output_['0x01', '0x01']]

This is very pytest specific though, so happy to take care of that, if that's ok.

The other suggestion I'd make would be to move the tests:

  • From: tests/byzantium/precompiles/test_05_modexp.py
  • To: tests/byzantium/eip198_modexp_precompile/test_modexp.py

as precompiles were introduced over several forks, for consistency in our repo, I think it's better to organize by the EIP that they were added. We can make discovering and executing precompiles more convenient by adding pytest marks to the tests (e.g., @pytest.mark.precompile_test, see fill --markers, if you you're interested, it's like tagging tests with metadata).

tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
docs/CHANGELOG.md Outdated Show resolved Hide resolved
tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
tests/byzantium/precompiles/test_05_modexp.py Outdated Show resolved Hide resolved
@jochem-brouwer
Copy link
Member Author

Regarding the test names, do you mean something like this?: 460bf35

(I am resolving the latest comment as we speak πŸ˜„ )

@jochem-brouwer
Copy link
Member Author

I'm not sure, how do I run evm_bytes_to_python? I can run fill, or order_fixtures, but if I try evm_bytes_to_python then I get command not found. (I have updated my branch to latest main)

@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Jan 10, 2024

If I rename to fe4c0a8

tests/byzantium/eip198_modexp_precompile/test_modexp.py then I have to add

REFERENCE_SPEC_GIT_PATH = "EIPS/eip-198.md"
REFERENCE_SPEC_VERSION = "9e393a79d9937f579acbdcb234a67869259d5a96"

To the test (which I did). However now the documentation fails to build and I don't know why (just checked, CI passes if I rename it back https://github.com/ethereum/execution-spec-tests/actions/runs/7480915178/job/20361369965?pr=364 ). How should I fix this? It seems it can't find some files

ERROR   -  mkdocstrings: tests.byzantium.eip198_modexp_precompile.test_modexp could not be found

Aborted with a BuildError!
ERROR   -  Error reading page 'tests/byzantium/eip198_modexp_precompile/test_modexp/index.md':
ERROR   -  Could not collect 'tests.byzantium.eip198_modexp_precompile.test_modexp'

But I don't see anything in the other EIP tests which gives me a hunch what the problem could be πŸ€”

Besides this I think the PR is done :) Have addressed all feedback.

@jochem-brouwer
Copy link
Member Author

Never mind, I forgot to rename the __index__.py to the right folder.

@danceratopz ready for re-review πŸ˜„

Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

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

Amazing! This looks really nice! Thanks for all your work on this.

Regarding the test names, do you mean something like this?: 460bf35
Yes that's one approach (and I like it a lot), but I was originally hoping to use auto-generated names, but make them more compact.

In the end I decided to refactor how we write the parameter values using dataclasses in the hopes of making the code more readable. What do you think?

I made two PRs, one with manual ids only (closer to this PR as it currently stands) and one which generates ids from the parameters. We should pick the one we like most and merge that 😺 - let me know what you think.
cc @marioevz @spencer-tb please also say which of the following you like more... I'm really torn πŸ˜† And what do you think about the dataclass usage? I think the overhead makes sense for these tests.

tests/byzantium/eip198_modexp_precompile/test_modexp.py Outdated Show resolved Hide resolved
@jochem-brouwer
Copy link
Member Author

I personally like this one better jochem-brouwer#2 since it is more descriptive. (I had thought of creating those manually, but indeed creating those using autogen is better πŸ˜„ )

Let me know if you need anything from my side πŸ˜„ πŸ‘

@jochem-brouwer
Copy link
Member Author

Also regarding the new classes: that definitely makes it more readable!

@spencer-tb
Copy link
Collaborator

Big fan of 2) for the maintainability :D - will be a nice structure to follow for similar tests in the future

Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

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

Thanks again @jochem-brouwer! Nice edition.

Can you just check the comment below? Otherwise, LGTM!

tests/byzantium/eip198_modexp_precompile/test_modexp.py Outdated Show resolved Hide resolved
Co-authored-by: danceratopz <danceratopz@gmail.com>
@jochem-brouwer
Copy link
Member Author

@danceratopz I have just manually checked, the EIP has 5 test cases. I manually also checked that the test cases from the EIP match the test cases as written down in this PR. So from my side also: go ahead and merge, thanks a lot πŸ˜„ πŸ‘

@danceratopz danceratopz merged commit 8c7cb87 into ethereum:main Jan 17, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope:tests Scope: Test cases type:feat type: Feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants