Skip to content

Commit d1cebb8

Browse files
committed
new(tests): EIP-5656/7692 - use new marker to EOF-ize MCOPY test
1 parent a87bb09 commit d1cebb8

File tree

1 file changed

+28
-47
lines changed

1 file changed

+28
-47
lines changed

tests/cancun/eip5656_mcopy/test_mcopy_memory_expansion.py

Lines changed: 28 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
that produce a memory expansion, and potentially an out-of-gas error.
55
66
""" # noqa: E501
7-
from typing import Mapping, Tuple
7+
from typing import Mapping
88

99
import pytest
1010

1111
from ethereum_test_tools import Account, Address, Alloc, Bytecode, Environment
1212
from ethereum_test_tools import Opcodes as Op
13-
from ethereum_test_tools import StateTestFiller, Storage, Transaction, cost_memory_bytes
13+
from ethereum_test_tools import StateTestFiller, Transaction, cost_memory_bytes
1414

1515
from .common import REFERENCE_SPEC_GIT_PATH, REFERENCE_SPEC_VERSION
1616

@@ -31,6 +31,8 @@ def callee_bytecode(dest: int, src: int, length: int) -> Bytecode:
3131
# Pushes for the return operation
3232
bytecode += Op.PUSH1(0x00) + Op.PUSH1(0x00)
3333

34+
bytecode += Op.SSTORE(1, 1)
35+
3436
# Perform the mcopy operation
3537
bytecode += Op.MCOPY(dest, src, length)
3638

@@ -40,14 +42,16 @@ def callee_bytecode(dest: int, src: int, length: int) -> Bytecode:
4042

4143

4244
@pytest.fixture
43-
def subcall_exact_cost(
45+
def call_exact_cost(
4446
initial_memory: bytes,
4547
dest: int,
4648
length: int,
4749
) -> int:
4850
"""
4951
Returns the exact cost of the subcall, based on the initial memory and the length of the copy.
5052
"""
53+
intrinsic_cost = 21000 + len(initial_memory) * 16
54+
5155
mcopy_cost = 3
5256
mcopy_cost += 3 * ((length + 31) // 32)
5357
if length > 0 and dest + length > len(initial_memory):
@@ -57,36 +61,18 @@ def subcall_exact_cost(
5761
calldatacopy_cost += 3 * ((len(initial_memory) + 31) // 32)
5862
calldatacopy_cost += cost_memory_bytes(len(initial_memory), 0)
5963

60-
pushes_cost = 3 * 7
64+
pushes_cost = 3 * 9
6165
calldatasize_cost = 2
62-
return mcopy_cost + calldatacopy_cost + pushes_cost + calldatasize_cost
63-
64-
65-
@pytest.fixture
66-
def bytecode_storage(
67-
subcall_exact_cost: int,
68-
successful: bool,
69-
memory_expansion_address: Address,
70-
) -> Tuple[Bytecode, Storage.StorageDictType]:
71-
"""
72-
Prepares the bytecode and storage for the test, based on the expected result of the subcall
73-
(whether it succeeds or fails depending on the length of the memory expansion).
74-
"""
75-
bytecode = Bytecode()
76-
storage = {}
7766

78-
# Pass on the calldata
79-
bytecode += Op.CALLDATACOPY(0x00, 0x00, Op.CALLDATASIZE())
80-
81-
subcall_gas = subcall_exact_cost if successful else subcall_exact_cost - 1
82-
83-
# Perform the subcall and store a one in the result location
84-
bytecode += Op.SSTORE(
85-
Op.CALL(subcall_gas, memory_expansion_address, 0, 0, Op.CALLDATASIZE(), 0, 0), 1
67+
sstore_cost = 22100
68+
return (
69+
intrinsic_cost
70+
+ mcopy_cost
71+
+ calldatacopy_cost
72+
+ pushes_cost
73+
+ calldatasize_cost
74+
+ sstore_cost
8675
)
87-
storage[int(successful)] = 1
88-
89-
return (bytecode, storage)
9076

9177

9278
@pytest.fixture
@@ -101,10 +87,11 @@ def block_gas_limit() -> int: # noqa: D103
10187

10288
@pytest.fixture
10389
def tx_gas_limit( # noqa: D103
104-
subcall_exact_cost: int,
90+
call_exact_cost: int,
10591
block_gas_limit: int,
92+
successful: bool,
10693
) -> int:
107-
return min(max(500_000, subcall_exact_cost * 2), block_gas_limit)
94+
return min(call_exact_cost - (0 if successful else 1), block_gas_limit)
10895

10996

11097
@pytest.fixture
@@ -115,14 +102,7 @@ def env( # noqa: D103
115102

116103

117104
@pytest.fixture
118-
def caller_address( # noqa: D103
119-
pre: Alloc, bytecode_storage: Tuple[bytes, Storage.StorageDictType]
120-
) -> Address:
121-
return pre.deploy_contract(code=bytecode_storage[0])
122-
123-
124-
@pytest.fixture
125-
def memory_expansion_address(pre: Alloc, callee_bytecode: Bytecode) -> Address: # noqa: D103
105+
def caller_address(pre: Alloc, callee_bytecode: bytes) -> Address: # noqa: D103
126106
return pre.deploy_contract(code=callee_bytecode)
127107

128108

@@ -151,11 +131,10 @@ def tx( # noqa: D103
151131

152132
@pytest.fixture
153133
def post( # noqa: D103
154-
caller_address: Address, bytecode_storage: Tuple[bytes, Storage.StorageDictType]
134+
caller_address: Address,
135+
successful: bool,
155136
) -> Mapping:
156-
return {
157-
caller_address: Account(storage=bytecode_storage[1]),
158-
}
137+
return {caller_address: Account(storage={1: 1} if successful else {})}
159138

160139

161140
@pytest.mark.parametrize(
@@ -189,14 +168,15 @@ def post( # noqa: D103
189168
@pytest.mark.parametrize(
190169
"initial_memory",
191170
[
192-
bytes(range(0x00, 0x100)),
171+
bytes(range(0x01, 0xFF)), # NOTE: must be non-zero bytes
193172
bytes(),
194173
],
195174
ids=[
196175
"from_existent_memory",
197176
"from_empty_memory",
198177
],
199178
)
179+
@pytest.mark.with_all_evm_code_types
200180
@pytest.mark.valid_from("Cancun")
201181
def test_mcopy_memory_expansion(
202182
state_test: StateTestFiller,
@@ -242,22 +222,23 @@ def test_mcopy_memory_expansion(
242222
],
243223
)
244224
@pytest.mark.parametrize(
245-
"subcall_exact_cost",
225+
"call_exact_cost",
246226
[2**128 - 1],
247227
ids=[""],
248228
) # Limit subcall gas, otherwise it would be impossibly large
249229
@pytest.mark.parametrize("successful", [False])
250230
@pytest.mark.parametrize(
251231
"initial_memory",
252232
[
253-
bytes(range(0x00, 0x100)),
233+
bytes(range(0x01, 0xFF)), # NOTE: must be non-zero bytes
254234
bytes(),
255235
],
256236
ids=[
257237
"from_existent_memory",
258238
"from_empty_memory",
259239
],
260240
)
241+
@pytest.mark.with_all_evm_code_types
261242
@pytest.mark.valid_from("Cancun")
262243
def test_mcopy_huge_memory_expansion(
263244
state_test: StateTestFiller,

0 commit comments

Comments
 (0)