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

new(tests): EOF - EIP-7480: Add tests for DATACOPY memory expansion #664

Merged
merged 2 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ Add tests for [EIP-3540: EOF - EVM Object Format v1](https://eips.ethereum.org/EIPS/eip-3540) ([#634](https://github.com/ethereum/execution-spec-tests/pull/634)).
- 🔀 Update EIP-7002 tests to match spec changes in [ethereum/execution-apis#549](https://github.com/ethereum/execution-apis/pull/549) ([#600](https://github.com/ethereum/execution-spec-tests/pull/600))
- ✨ Convert a few eip1153 tests from ethereum/tests repo into .py ([#440](https://github.com/ethereum/execution-spec-tests/pull/440)).
- ✨ Add tests for [EIP-7480: EOF - Data section access instructions](https://eips.ethereum.org/EIPS/eip-7480) ([#518](https://github.com/ethereum/execution-spec-tests/pull/518), [#664](https://github.com/ethereum/execution-spec-tests/pull/664)).

### 🛠️ Framework

Expand Down
52 changes: 25 additions & 27 deletions tests/cancun/eip5656_mcopy/test_mcopy_memory_expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,13 @@

import pytest

from ethereum_test_tools import Account, Bytecode, Environment
from ethereum_test_tools import Account, Alloc, Bytecode, Environment
from ethereum_test_tools import Opcodes as Op
from ethereum_test_tools import (
StateTestFiller,
Storage,
TestAddress,
Transaction,
cost_memory_bytes,
)
from ethereum_test_tools import StateTestFiller, Storage, Transaction, cost_memory_bytes
from ethereum_test_tools.common.base_types import Address

from .common import REFERENCE_SPEC_GIT_PATH, REFERENCE_SPEC_VERSION

# Code address used to call the test bytecode on every test case.
caller_address = 0x100

# Code address used to perform the memory expansion.
memory_expansion_address = 0x200

REFERENCE_SPEC_GIT_PATH = REFERENCE_SPEC_GIT_PATH
REFERENCE_SPEC_VERSION = REFERENCE_SPEC_VERSION

Expand Down Expand Up @@ -78,6 +67,7 @@ def subcall_exact_cost(
def bytecode_storage(
subcall_exact_cost: int,
successful: bool,
memory_expansion_address: Address,
) -> Tuple[Bytecode, Storage.StorageDictType]:
"""
Prepares the bytecode and storage for the test, based on the expected result of the subcall
Expand Down Expand Up @@ -126,26 +116,32 @@ def env( # noqa: D103


@pytest.fixture
def pre( # noqa: D103
tx_max_fee_per_gas: int,
tx_gas_limit: int,
bytecode_storage: Tuple[bytes, Storage.StorageDictType],
callee_bytecode: bytes,
) -> Mapping:
return {
TestAddress: Account(balance=tx_max_fee_per_gas * tx_gas_limit),
caller_address: Account(code=bytecode_storage[0]),
memory_expansion_address: Account(code=callee_bytecode),
}
def caller_address( # noqa: D103
pre: Alloc, bytecode_storage: Tuple[bytes, Storage.StorageDictType]
) -> Address:
return pre.deploy_contract(code=bytecode_storage[0])


@pytest.fixture
def memory_expansion_address(pre: Alloc, callee_bytecode: Bytecode) -> Address: # noqa: D103
return pre.deploy_contract(code=callee_bytecode)


@pytest.fixture
def sender(pre: Alloc, tx_max_fee_per_gas: int, tx_gas_limit: int) -> Address: # noqa: D103
return pre.fund_eoa(tx_max_fee_per_gas * tx_gas_limit)


@pytest.fixture
def tx( # noqa: D103
sender: Address,
caller_address: Address,
initial_memory: bytes,
tx_max_fee_per_gas: int,
tx_gas_limit: int,
) -> Transaction:
return Transaction(
sender=sender,
to=caller_address,
data=initial_memory,
gas_limit=tx_gas_limit,
Expand All @@ -155,7 +151,9 @@ def tx( # noqa: D103


@pytest.fixture
def post(bytecode_storage: Tuple[bytes, Storage.StorageDictType]) -> Mapping: # noqa: D103
def post( # noqa: D103
caller_address: Address, bytecode_storage: Tuple[bytes, Storage.StorageDictType]
) -> Mapping:
return {
caller_address: Account(storage=bytecode_storage[1]),
}
Expand Down Expand Up @@ -204,7 +202,7 @@ def post(bytecode_storage: Tuple[bytes, Storage.StorageDictType]) -> Mapping: #
def test_mcopy_memory_expansion(
state_test: StateTestFiller,
env: Environment,
pre: Mapping[str, Account],
pre: Alloc,
post: Mapping[str, Account],
tx: Transaction,
):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"""
Execution of CALLF, RETF opcodes within EOF V1 containers tests
Execution of DATA* opcodes within EOF V1 containers tests
"""

import pytest

from ethereum_test_tools import Account, Alloc, Environment, StateTestFiller, Transaction
from ethereum_test_tools.eof.v1 import Container, Section
from ethereum_test_tools.eof.v1.constants import MAX_CODE_SECTIONS
from ethereum_test_tools.vm.opcode import Opcodes as Op

from .. import EOF_FORK_NAME
Expand All @@ -16,57 +15,6 @@

pytestmark = pytest.mark.valid_from(EOF_FORK_NAME)

contract_call_within_deep_nested_callf = Container(
name="contract_call_within_deep_nested_callf",
sections=[
Section.Code(
code=(Op.CALLF[1] + Op.SSTORE(0, 1) + Op.STOP),
)
]
+ [
# All sections call next section and on return, store a 1
# to their call stack height key
Section.Code(
code=(Op.CALLF[i] + Op.SSTORE(i - 1, 1) + Op.RETF),
code_inputs=0,
code_outputs=0,
)
for i in range(2, MAX_CODE_SECTIONS)
]
+ [
# Last section makes external contract call
Section.Code(
code=(
Op.EXTCALL(0x200, 0, 0, 0) + Op.SSTORE(MAX_CODE_SECTIONS - 1, Op.ISZERO) + Op.RETF
),
code_inputs=0,
code_outputs=0,
)
],
)

recursive_contract_call_within_deep_nested_callf = Container(
name="recursive_contract_call_within_deep_nested_callf",
sections=[
# 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.STOP),
)
for i in range(MAX_CODE_SECTIONS - 1)
]
+ [
# Last section makes external contract call
Section.Code(
code=(
Op.SSTORE(MAX_CODE_SECTIONS - 1, Op.CALL(Op.GAS, 0x200, 0, 0, 0, 0, 0)) + Op.RETF
),
code_inputs=0,
code_outputs=0,
)
],
)


def create_data_test(offset: int, datasize: int):
"""
Expand Down
Loading