Skip to content

feat(tests): converting calldataload and calldatasize tests #1236

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

pacrob
Copy link
Contributor

@pacrob pacrob commented Feb 19, 2025

πŸ—’οΈ Description

πŸ”— Related Issues

βœ… 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: All converted JSON/YML tests from ethereum/tests have been added to converted-ethereum-tests.txt.
  • Tests: A PR with removal of converted JSON/YML tests from ethereum/tests have been opened.
  • remove calldataload and calldatasize testsΒ tests#1477
  • 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.
  • used geth version 1.15.2-stable-c8c62daf
  • Tests: Ran mkdocs serve locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.

@pacrob pacrob force-pushed the calldata-tests branch 4 times, most recently from 91c493a to f6a91be Compare March 19, 2025 21:44
@pacrob pacrob marked this pull request as ready for review March 19, 2025 21:45
Account(storage={0x00: 0x11}),
),
(
b"\x1a\x84Q\xe6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
Copy link
Contributor

Choose a reason for hiding this comment

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

is there better way to declare bytes ? more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

shortened and labeled!

@winsvega
Copy link
Contributor

evmone build script failing

@pacrob
Copy link
Contributor Author

pacrob commented Mar 21, 2025

OK, I think it's gtg. Still getting coverage loss though. How can I see what's lost , and is there a solution? I think my previous PR had the same issue.

===============
COVERAGE REPORT
/tests/DIFF/index.html
New covered Lines: 180
New covered function Paths: 77

ERROR: coverage is lost!
Lost coverage Lines: 26
Lost coverage function Paths: 5

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.

Hey, some comments which I think should make the test a bit more EEST-like, but we might lose irrelevant coverage (Like the SHA3 function which is IMO is out-of-scope for these tests) but that's ok.


Based on https://github.com/ethereum/tests/blob/ae4791077e8fcf716136e70fe8392f1a1f1495fb/src/GeneralStateTestsFiller/VMTests/vmTests/calldatacopyFiller.yml
"""
address_a = pre.deploy_contract(code_for_address_a)
Copy link
Member

Choose a reason for hiding this comment

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

It might be unnecessary to get the entire code as a parameter since it's very similar in all cases, so we could change it only having a calldataload_offset parameter and change this to:

Suggested change
address_a = pre.deploy_contract(code_for_address_a)
address_a = pre.deploy_contract(Op.SSTORE(0, Op.CALLDATALOAD(calldataload_offset)) + Op.STOP)

Comment on lines 14 to 15
(Op.MSTORE8(offset=0x0, value=0x25) + Op.MSTORE8(offset=0x1, value=0x60)),
0x2,
Copy link
Member

Choose a reason for hiding this comment

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

It might be better to change these two parameters to a single one called calldata, which could contain a bytes value as follows:

  • two_bytes: b'\x25\x60'
  • word_n_byte: b'\xff' * 32 + b'\x23'
  • 34_bytes: bytes.fromhex('123456789ABCDEF00000000000000000000000000000000000000000000000000024')

or something similar, then in the code we could use the Om.MSTORE(calldata, 0x00) (Macros can be imported by from ethereum_test_tools import Macros as Om) to put the call data in memory and args_size = len(calldata), then finally Op.CALL to the address_a.

Advantages to this method are:

  • IMO it makes it easier to understand what the test is trying to verify by showing exactly what the calldata is when calldataload is being called.
  • We can parametrize for generate a test where address_a is the entry point of the transaction and calldata is the data of the transaction.

)

tx = Transaction(
data=tx_data,
Copy link
Member

Choose a reason for hiding this comment

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

I think tx_data is not really used anywhere and could be safely removed.

But ideally it should be replaced by calldata as described in the previous comment πŸ‘

Comment on lines 18 to 20
Account(
storage={0x00: 0x2560000000000000000000000000000000000000000000000000000000000000}
),
Copy link
Member

Choose a reason for hiding this comment

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

Could be simplified to:

Suggested change
Account(
storage={0x00: 0x2560000000000000000000000000000000000000000000000000000000000000}
),
0x2560000000000000000000000000000000000000000000000000000000000000,

And then the function defines the Account(storage=... part.

@pytest.mark.parametrize(
"args_size,sha3_len,storage",
[
("0002", "01", Account(storage={0x00: 0x02})),
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
("0002", "01", Account(storage={0x00: 0x02})),
("0002", "01", 0x02),

Similar comment to previous file, Account(storage=... can be defined inside the function to make the parametrization more readable.

tx = Transaction(
data=tx_data,
gas_limit=100_000,
gas_price=0x0A,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
gas_price=0x0A,

Can be safely removed, so we can execute this same test in other environments.

protected=fork >= Byzantium,
sender=pre.fund_eoa(),
to=to,
value=0x01,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
value=0x01,

I think this can also be safely removed since it's not used anywhere.

)
)
)
tx_data = bytes.fromhex("1a8451e6" + "00" * 30 + args_size + "00" * 31 + sha3_len)
Copy link
Member

Choose a reason for hiding this comment

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

No need to encode this as call data to be decoded by the contract, args_size and sha3_len could be integers and they could be placed inside of the contract directly:

    to = pre.deploy_contract(
        code=(
            Op.MSTORE(offset=0x0, value=Op.SHA3(offset=0x0, size=sha3_len))
            + Op.CALL(
                gas=Op.SUB(Op.GAS(), 0x100),
                address=address,
                value=0x0,
                args_offset=0x0,
                args_size=args_size,
                ret_offset=0x0,
                ret_size=0x0,
            )
        )
    )

Although I'm having trouble understanding why the original test is using SHA3 in the first place since the memory contents are irrelevant, and my best guess is to just have a non-zero filled memory.

I think we should replace all of this with calldata just like the comment in test_calldataload.py, and also parametrize this function to test calldatasize at the top-level call (returns len(tx.data)) or a sub-level call (returns arg_size).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@marioevz I simplified it a bit, but I'm pretty sure it's still checking correctly. Anything I'm missing?

@pacrob pacrob force-pushed the calldata-tests branch 2 times, most recently from f21d975 to de67c5c Compare April 4, 2025 20:14
@winsvega
Copy link
Contributor

winsvega commented Apr 7, 2025

lets add push32, mstore8, add opcodes to default opcodes exempt from coverage check requirements.
it is in the file tests/homestead/coverage/test_coverage.py

@pacrob
Copy link
Contributor Author

pacrob commented Apr 8, 2025

lets add push32, mstore8, add opcodes to default opcodes exempt from coverage check requirements. it is in the file tests/homestead/coverage/test_coverage.py

Not all fixed, but better. Thanks!

before:

ERROR: coverage is lost!
Lost coverage Lines: 34
Lost coverage function Paths: 11

after:

ERROR: coverage is lost!
Lost coverage Lines: 33
Lost coverage function Paths: 3

@pacrob
Copy link
Contributor Author

pacrob commented Apr 9, 2025

Latest coverage fail:

Lost coverage Lines: 56
Lost coverage function Paths: 9

Looking into it:

expected:

  • Lost 22 lines and 6 functions from lib/evmone due to no longer using keccak or calldataload in the calldatasize test
  • Lost 7 lines test/state/host.cpp, 3 lines and one function in test/state/host.cpp due to not including a value in the transaction in the calldatasize test.

unknown:

  • Lost 2 lines in evmc/include/evmc, showing that the test is no longer checking Prague. Why might that be happening?
  • Leaving 22 lines and 2 functions across mpt.cpp, state.cpp, and system_contracts.cpp. Not sure of source.

I'll keep poking, but if you know whether the last 2 can be fixed or should be ignored, let me know!

@winsvega
Copy link
Contributor

About sha3

I don't get what are the inputs for call in Oris test.
I suggest we debug original test, derrive the inputs and reproduce in python.

@spencer-tb spencer-tb changed the title converting calldataload and calldatasize tests feat(tests): converting calldataload and calldatasize tests Apr 14, 2025
@spencer-tb spencer-tb added scope:tests Scope: Changes EL client test cases in `./tests` port Related to porting ethereum/tests to EEST type:feat type: Feature and removed port Related to porting ethereum/tests to EEST labels Apr 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
port Related to porting ethereum/tests to EEST scope:tests Scope: Changes EL client test cases in `./tests` type:feat type: Feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants