-
Notifications
You must be signed in to change notification settings - Fork 107
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
feat(tests): port ethereum/tests swap opcode tests #1163
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for implementing this.
There's a couple of comments I think should be addressed before merging, but overall it's a very good PR!
@@ -590,7 +590,7 @@ requires-dist = [ | |||
{ name = "pytest-metadata", specifier = ">=3,<4" }, | |||
{ name = "pytest-xdist", specifier = ">=3.3.1,<4" }, | |||
{ name = "pyyaml", specifier = ">=6.0.2,<7" }, | |||
{ name = "questionary", git = "/~https://github.com/tmbo/questionary?rev=ff22aeae1cd9c1c734f14329934e349bec7873bc#ff22aeae1cd9c1c734f14329934e349bec7873bc" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can leave this file out of the PR for the time being π
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like @bomanaps is using uv>=0.8.22
- this is due to:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bomanaps no action required regarding your uv version at the moment, I think everyone else needs to upgrade their uv.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
tests/frontier/opcodes/test_swap.py
Outdated
from ethereum_test_forks import Fork, Frontier, Homestead | ||
from ethereum_test_tools import Account, Alloc, Environment | ||
from ethereum_test_tools import Opcodes as Op | ||
from ethereum_test_tools import StateTestFiller, Storage, Transaction, Bytecode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from ethereum_test_tools import StateTestFiller, Storage, Transaction, Bytecode | |
from ethereum_test_tools import StateTestFiller, Transaction, Bytecode |
Storage
is unused.
contract_code += swap_opcode | ||
|
||
# Store the top of the stack in storage slot 0 | ||
contract_code += Op.PUSH1(0) + Op.SSTORE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could change the approach a bit here:
SSTORE(0,1)
at the start of the execution, just to have something that will revert when the underflow happens.- Fill the stack up to the
SWAP*
opcode's required minimum minus one. - Perform the
SWAP*
that should abort the execution because there's not enough values in the stack for it to operate. - Verify that the storage is empty since the
SSTORE(0,1)
reverts with the execution abort caused by the underflow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test as it is right now is producing an overflow that is accomplished by the opcode PUSH1
, and in that case, the SWAPn
opcode is not really used.
This is the last executed opcode in the trace:
Step 1025:
{ 'depth': 1,
'error': 'StackOverflowError',
'gas': '0x74315',
'gasCost': '0x3',
'memSize': 0,
'op': 96,
'opName': 'PUSH1',
'pc': 2049,
'refund': 0,
'returnData': '0x',
'stack': [ '0x0',
'0x1',
'0x2',
...
'0xfe',
'0xef']}
Step 1026:
{'error': 'StackOverflowError', 'gasUsed': '0x74f18', 'output': ''}
So we don't really need to push this many items into the stack for an underflow, the key is not having enough items for the SWAPn
opcode to try to fetch outside of the bounds of the stack.
For example, for SWAP1
, it requires at least two elements in the stack to work properly (see the min_stack_height
property of the opcode https://ethereum.github.io/execution-spec-tests/main/library/ethereum_test_vm/#ethereum_test_vm.Opcodes.SWAP1), because it swaps the first item for the second. Therefore, to create a stack underflow, we place a single item in the stack and then execute the SWAP1
.
sender=pre.fund_eoa(), | ||
to=contract, | ||
gas_limit=500_000, | ||
protected=False if fork in [Frontier, Homestead] else True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marioevz can we automate this thing? unless we specificly want to test this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One potential solution for this would be:
- feat(fill): make transaction a pytest fixtureΒ #1065
Then thetransaction
(ortx
fixture could made aware of the current value of thefork
fixture/parameter).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why uv.lock is deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More comments.
contract_code += swap_opcode | ||
|
||
# Store the top of the stack in storage slot 0 | ||
contract_code += Op.PUSH1(0) + Op.SSTORE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test as it is right now is producing an overflow that is accomplished by the opcode PUSH1
, and in that case, the SWAPn
opcode is not really used.
This is the last executed opcode in the trace:
Step 1025:
{ 'depth': 1,
'error': 'StackOverflowError',
'gas': '0x74315',
'gasCost': '0x3',
'memSize': 0,
'op': 96,
'opName': 'PUSH1',
'pc': 2049,
'refund': 0,
'returnData': '0x',
'stack': [ '0x0',
'0x1',
'0x2',
...
'0xfe',
'0xef']}
Step 1026:
{'error': 'StackOverflowError', 'gasUsed': '0x74f18', 'output': ''}
So we don't really need to push this many items into the stack for an underflow, the key is not having enough items for the SWAPn
opcode to try to fetch outside of the bounds of the stack.
For example, for SWAP1
, it requires at least two elements in the stack to work properly (see the min_stack_height
property of the opcode https://ethereum.github.io/execution-spec-tests/main/library/ethereum_test_vm/#ethereum_test_vm.Opcodes.SWAP1), because it swaps the first item for the second. Therefore, to create a stack underflow, we place a single item in the stack and then execute the SWAP1
.
ποΈ Description
Port test for
swap
opcode ported fromethereum/tests
.π Related Issues
Closes #1012
β Checklist
mkdocs serve
locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.