Skip to content

Commit

Permalink
Updates based on non-returning sections
Browse files Browse the repository at this point in the history
Update tests to conform with besu
* sample code needs non-returning and data
* all codesection zeros need to be non-returning
* RETF is not valid in non-returning sections
* CALL is not in EOF, use EXTCALL
*
  • Loading branch information
shemnon committed Apr 19, 2024
1 parent e7d677b commit a0b9a5c
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 39 deletions.
107 changes: 107 additions & 0 deletions src/ethereum_test_tools/vm/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -5261,6 +5261,79 @@ class Opcodes(Opcode, Enum):
Source: [evm.codes/#F5](https://www.evm.codes/#F5)
"""

EXTCALL = Opcode(0xF8, popped_stack_items=4, pushed_stack_items=1)
"""
EXTCALL(target_address, input_offset, input_size, value) = address
----
Description
----
Message-call into an account
Inputs
----
- target_address: the account which context to execute
- input_offset: byte offset in the memory in bytes, the calldata of the sub context
- input_size: byte size to copy (size of the calldata)
- value: value in wei to send to the account
Outputs
----
- success:
- `0` if the call was successful.
- `1` if the call has reverted (also can be pushed earlier in a light failure scenario).
- `2` if the call has failed.
Fork
----
Prague
Gas
----
```
static_gas = 0
dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost
+ positive_value_cost + value_to_empty_account_cost
```
Source: [EIP-7069](https://eips.ethereum.org/EIPS/eip-7069)
"""

EXTDELEGATECALL = Opcode(0xF9, popped_stack_items=3, pushed_stack_items=1)
"""
EXTDELEGATECALL(target_address, input_offset, input_size) = address
----
Description
----
Message-call into this account with an alternative account's code, but persisting the current
values for sender and value
Inputs
----
- target_address: the account which context to execute
- input_offset: byte offset in the memory in bytes, the calldata of the sub context
- input_size: byte size to copy (size of the calldata)
Outputs
----
- success:
- `0` if the call was successful.
- `1` if the call has reverted (also can be pushed earlier in a light failure scenario).
- `2` if the call has failed.
Fork
----
Prague
Gas
----
- static_gas = 0
- dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost
Source: [EIP-7069](https://eips.ethereum.org/EIPS/eip-7069)
"""

STATICCALL = Opcode(0xFA, popped_stack_items=6, pushed_stack_items=1)
"""
STATICCALL(gas, address, argsOffset, argsSize, retOffset, retSize) = success
Expand Down Expand Up @@ -5297,6 +5370,40 @@ class Opcodes(Opcode, Enum):
Source: [evm.codes/#FA](https://www.evm.codes/#FA)
"""

EXTSTATICCALL = Opcode(0xFB, popped_stack_items=4, pushed_stack_items=1)
"""
EXTSTATICCALL(target_address, input_offset, input_size) = address
----
Description
----
Static message-call into an account
Inputs
----
- target_address: the account which context to execute
- input_offset: byte offset in the memory in bytes, the calldata of the sub context
- input_size: byte size to copy (size of the calldata)
Outputs
----
- success:
- `0` if the call was successful.
- `1` if the call has reverted (also can be pushed earlier in a light failure scenario).
- `2` if the call has failed.
Fork
----
Prague
Gas
----
- static_gas = 0
- dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost
Source: [EIP-7069](https://eips.ethereum.org/EIPS/eip-7069)
"""

CREATE4 = Opcode(0xF7, popped_stack_items=5, pushed_stack_items=1)
"""
!!! Note: This opcode is under development
Expand Down
9 changes: 5 additions & 4 deletions tests/prague/eip3540_eof_v1/test_eof_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

from .spec import EOF_FORK_NAME

REFERENCE_SPEC_GIT_PATH = "EIPS/eip-3540.md"
REFERENCE_SPEC_VERSION = "8dcb0a8c1c0102c87224308028632cc986a61183"
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7692.md"
# TODO change this when EIP merges - https://github.com/ethereum/EIPs/pull/8448
REFERENCE_SPEC_VERSION = "0000000000000000000000000000000000000000"

pytestmark = pytest.mark.valid_from(EOF_FORK_NAME)

Expand Down Expand Up @@ -63,8 +64,8 @@ def test_eof_example(eof_test: EOFTestFiller):

# This will construct a valid EOF container with these bytes
assert bytes(eof_code) == bytes.fromhex(
"ef0001010010020004000500060008000204000000008000010100000100010003020300035fe300010050"
"e3000250e43080e300035050e480e4"
"ef0001010010020004000500060008000204000100008000010100000100010003020300035fe300010050"
"e3000250e43080e300035050e480e4ef"
)

eof_test(
Expand Down
96 changes: 61 additions & 35 deletions tests/prague/eip3540_eof_v1/test_execution_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@
Transaction,
)
from ethereum_test_tools.eof.v1 import Container, Section
from ethereum_test_tools.eof.v1.constants import MAX_CODE_SECTIONS, MAX_RETURN_STACK_HEIGHT
from ethereum_test_tools.eof.v1.constants import (
MAX_CODE_SECTIONS,
MAX_RETURN_STACK_HEIGHT,
NON_RETURNING_SECTION,
)
from ethereum_test_tools.vm.opcode import Opcodes as Op

from .spec import EOF_FORK_NAME

REFERENCE_SPEC_GIT_PATH = "EIPS/eip-2930.md"
REFERENCE_SPEC_VERSION = "c9db53a936c5c9cbe2db32ba0d1b86c4c6e73534"

# List all containers used within execution tests, since they will need to be
# valid EOF V1 containers too

Expand All @@ -28,15 +35,23 @@
contract_call_within_deep_nested_callf = Container(
name="contract_call_within_deep_nested_callf",
sections=[
Section.Code(
code=(Op.CALLF[1] + Op.PUSH1(1) + Op.PUSH0 + Op.SSTORE + Op.STOP),
code_inputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
)
]
+ [
# All sections call next section and on return, store a 1
# to their call stack height key
Section.Code(
code=(Op.CALLF[i + 1] + Op.PUSH1(1) + Op.PUSH2(i) + Op.SSTORE + Op.RETF),
code=(Op.CALLF[i] + Op.PUSH1(1) + Op.PUSH2(i - 1) + Op.SSTORE + Op.RETF),
code_inputs=0,
code_outputs=0,
max_stack_height=2,
)
for i in range(MAX_CODE_SECTIONS - 1)
for i in range(2, MAX_CODE_SECTIONS)
]
+ [
# Last section makes external contract call
Expand All @@ -45,18 +60,16 @@
Op.PUSH0
+ Op.PUSH0
+ Op.PUSH0
+ Op.PUSH0
+ Op.PUSH0
+ Op.PUSH2(0x200)
+ Op.GAS
+ Op.CALL
+ Op.EXTCALL
+ Op.ISZERO
+ Op.PUSH2(MAX_CODE_SECTIONS - 1)
+ Op.SSTORE
+ Op.RETF
),
code_inputs=0,
code_outputs=0,
max_stack_height=7,
max_stack_height=4,
)
],
)
Expand All @@ -67,9 +80,9 @@
# All sections call next section and on return, store a 1
# to their call stack height key
Section.Code(
code=(Op.CALLF[i + 1] + Op.PUSH1(1) + Op.PUSH2(i) + Op.SSTORE + Op.RETF),
code=(Op.CALLF[i + 1] + Op.PUSH1(1) + Op.PUSH2(i) + Op.SSTORE + Op.STOP),
code_inputs=0,
code_outputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
)
for i in range(MAX_CODE_SECTIONS - 1)
Expand Down Expand Up @@ -98,28 +111,17 @@
)

CALL_SUCCEED_CONTRACTS: List[Container] = [
Container(
name="retf_top_frame",
sections=[
Section.Code(
code=(Op.RETF),
code_inputs=0,
code_outputs=0,
max_stack_height=0,
),
],
),
Container(
name="function_finishes_contract_execution",
sections=[
Section.Code(
code=(Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=0,
),
Section.Code(
code=(Op.STOP),
code=(Op.RETF),
code_inputs=0,
code_outputs=0,
max_stack_height=0,
Expand All @@ -132,13 +134,13 @@
Section.Code(
code=(Op.PUSH1(1) + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=1,
),
Section.Code(
code=(
Op.DUP1
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT)
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT - 1)
+ Op.SUB
+ Op.RJUMPI[len(Op.POP) + len(Op.RETF)]
+ Op.POP
Expand All @@ -157,21 +159,27 @@
Container(
name="max_recursive_callf_sstore",
sections=[
Section.Code(
code=(Op.PUSH1(1) + Op.PUSH0 + Op.SSTORE + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
),
Section.Code(
code=(
Op.PUSH0
+ Op.SLOAD
+ Op.DUP1
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT)
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT - 1)
+ Op.SUB
+ Op.RJUMPI[len(Op.POP) + len(Op.RETF)]
+ Op.RJUMPI[len(Op.POP) + len(Op.STOP)]
+ Op.POP
+ Op.RETF
+ Op.PUSH1(1)
+ Op.ADD
+ Op.PUSH0
+ Op.SSTORE
+ Op.CALLF[0]
+ Op.CALLF[1]
+ Op.RETF
),
code_inputs=0,
Expand All @@ -183,12 +191,18 @@
Container(
name="max_recursive_callf_memory",
sections=[
Section.Code(
code=(Op.PUSH1(1) + Op.PUSH0 + Op.MSTORE + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
),
Section.Code(
code=(
Op.PUSH0
+ Op.MLOAD
+ Op.DUP1
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT)
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT - 1)
+ Op.SUB
+ Op.RJUMPI[len(Op.POP) + len(Op.RETF)]
+ Op.POP
Expand All @@ -197,7 +211,7 @@
+ Op.ADD
+ Op.PUSH0
+ Op.MSTORE
+ Op.CALLF[0]
+ Op.CALLF[1]
+ Op.RETF
),
code_inputs=0,
Expand All @@ -218,7 +232,7 @@
Section.Code(
code=(Op.INVALID),
code_inputs=0,
code_outputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=0,
),
],
Expand All @@ -229,7 +243,7 @@
Section.Code(
code=(Op.PUSH1(1) + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=1,
),
Section.Code(
Expand All @@ -254,12 +268,18 @@
Container(
name="overflow_recursive_callf_sstore",
sections=[
Section.Code(
code=(Op.PUSH1(1) + Op.PUSH0 + Op.SSTORE + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
),
Section.Code(
code=(
Op.PUSH0
+ Op.SLOAD
+ Op.DUP1
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT + 1)
+ Op.PUSH2(MAX_RETURN_STACK_HEIGHT)
+ Op.SUB
+ Op.RJUMPI[len(Op.POP) + len(Op.RETF)]
+ Op.POP
Expand All @@ -268,7 +288,7 @@
+ Op.ADD
+ Op.PUSH0
+ Op.SSTORE
+ Op.CALLF[0]
+ Op.CALLF[1]
+ Op.RETF
),
code_inputs=0,
Expand All @@ -280,6 +300,12 @@
Container(
name="overflow_recursive_callf_memory",
sections=[
Section.Code(
code=(Op.PUSH1(1) + Op.PUSH0 + Op.MSTORE + Op.CALLF[1] + Op.STOP),
code_inputs=0,
code_outputs=NON_RETURNING_SECTION,
max_stack_height=2,
),
Section.Code(
code=(
Op.PUSH0
Expand All @@ -294,7 +320,7 @@
+ Op.ADD
+ Op.PUSH0
+ Op.MSTORE
+ Op.CALLF[0]
+ Op.CALLF[1]
+ Op.RETF
),
code_inputs=0,
Expand Down
Loading

0 comments on commit a0b9a5c

Please sign in to comment.