Skip to content

Commit 1e90f5e

Browse files
committed
new(tests): Add tests for OOGing in EXP variable gas
1 parent fd2762c commit 1e90f5e

6 files changed

Lines changed: 87 additions & 3 deletions

File tree

src/ethereum_test_forks/forks/forks.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def gas_costs(cls, *, block_number: int = 0, timestamp: int = 0) -> GasCosts:
116116
G_CALL_STIPEND=2_300,
117117
G_NEW_ACCOUNT=25_000,
118118
G_EXP=10,
119-
G_EXP_BYTE=50,
119+
G_EXP_BYTE=10,
120120
G_MEMORY=3,
121121
G_TX_DATA_ZERO=4,
122122
G_TX_DATA_NON_ZERO=68,
@@ -814,12 +814,22 @@ class Tangerine(DAOFork, ignore=True):
814814

815815

816816
class SpuriousDragon(Tangerine, ignore=True):
817-
"""SpuriousDragon fork (EIP-155, EIP-158)."""
817+
"""SpuriousDragon fork (EIP-155, EIP-158, EIP-160)."""
818+
819+
@classmethod
820+
def gas_costs(cls, *, block_number: int = 0, timestamp: int = 0) -> GasCosts:
821+
"""
822+
On SpuriousDragon, EXP byte gas cost is increased to 50.
823+
"""
824+
return replace(
825+
super(SpuriousDragon, cls).gas_costs(block_number=block_number, timestamp=timestamp),
826+
G_EXP_BYTE=50, # https://eips.ethereum.org/EIPS/eip-160
827+
)
818828

819829
pass
820830

821831

822-
class Byzantium(Homestead):
832+
class Byzantium(SpuriousDragon):
823833
"""Byzantium fork."""
824834

825835
@classmethod

tests/frontier/opcodes/test_all_opcodes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ def test_constant_gas(
284284
+ (code_increment_counter if opcode == Op.CREATE2 else Bytecode())
285285
)
286286
gas_test(
287+
fork,
287288
state_test,
288289
env,
289290
pre,

tests/frontier/opcodes/test_exp.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
Test EXP opcode.
3+
"""
4+
5+
import pytest
6+
7+
from ethereum_test_base_types.base_types import ZeroPaddedHexNumber
8+
from ethereum_test_forks import Fork
9+
from ethereum_test_tools import (
10+
Alloc,
11+
Environment,
12+
StateTestFiller,
13+
)
14+
from ethereum_test_vm import Opcodes as Op
15+
from tests.unscheduled.eip7692_eof_v1.gas_test import gas_test
16+
17+
REFERENCE_SPEC_GIT_PATH = "N/A"
18+
REFERENCE_SPEC_VERSION = "N/A"
19+
20+
21+
def exp_gas(fork: Fork, exponent: int) -> int:
22+
"""Calculate gas cost for EXP opcode given the exponent."""
23+
byte_len = (exponent.bit_length() + 7) // 8
24+
return fork.gas_costs().G_EXP + fork.gas_costs().G_EXP_BYTE * byte_len
25+
26+
27+
@pytest.mark.valid_from("Berlin")
28+
@pytest.mark.parametrize("a", [0, 1, pytest.param(2**256 - 1, id="a2to256minus1")])
29+
@pytest.mark.parametrize(
30+
"exponent",
31+
[
32+
0,
33+
1,
34+
2,
35+
1023,
36+
1024,
37+
pytest.param(2**255, id="exponent2to255"),
38+
pytest.param(2**256 - 1, id="exponent2to256minus1"),
39+
],
40+
)
41+
def test_gas(
42+
state_test: StateTestFiller, pre: Alloc, a: int, exponent: int, fork: Fork, env: Environment
43+
) -> None:
44+
"""Test that EXP gas works as expected."""
45+
warm_gas = exp_gas(fork, exponent)
46+
47+
if cap := fork.transaction_gas_limit_cap():
48+
env.gas_limit = ZeroPaddedHexNumber(cap)
49+
50+
gas_test(
51+
fork,
52+
state_test,
53+
env,
54+
pre,
55+
setup_code=Op.PUSH32(exponent) + Op.PUSH32(a),
56+
subject_code=Op.EXP,
57+
tear_down_code=Op.STOP,
58+
cold_gas=warm_gas,
59+
warm_gas=warm_gas,
60+
eof=False,
61+
)

tests/unscheduled/eip7692_eof_v1/eip7069_extcall/test_gas.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def test_ext_calls_gas(
134134
)
135135
cost_memory_bytes = fork.memory_expansion_gas_calculator()
136136
gas_test(
137+
fork,
137138
state_test,
138139
state_env,
139140
pre,
@@ -153,6 +154,7 @@ def test_ext_calls_gas(
153154
def test_transfer_gas_is_cleared(
154155
state_test: StateTestFiller,
155156
pre: Alloc,
157+
fork: Fork,
156158
state_env: Environment,
157159
opcode: Op,
158160
value: int,
@@ -174,6 +176,7 @@ def test_transfer_gas_is_cleared(
174176
push_gas = (4 if opcode == Op.EXTCALL else 3) * 3
175177

176178
gas_test(
179+
fork,
177180
state_test,
178181
state_env,
179182
pre,
@@ -197,6 +200,7 @@ def test_transfer_gas_is_cleared(
197200
def test_late_account_create(
198201
state_test: StateTestFiller,
199202
pre: Alloc,
203+
fork: Fork,
200204
state_env: Environment,
201205
opcode: Op,
202206
) -> None:
@@ -207,6 +211,7 @@ def test_late_account_create(
207211
empty_address = Address(0xDECAFC0DE)
208212

209213
gas_test(
214+
fork,
210215
state_test,
211216
state_env,
212217
pre,

tests/unscheduled/eip7692_eof_v1/eip7620_eof_create/test_gas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def test_eofcreate_gas(
138138
)
139139
cost_memory_bytes = fork.memory_expansion_gas_calculator()
140140
gas_test(
141+
fork,
141142
state_test,
142143
Environment(),
143144
pre,

tests/unscheduled/eip7692_eof_v1/gas_test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import itertools
44

55
from ethereum_test_base_types.base_types import Address
6+
from ethereum_test_forks.forks.forks import Berlin
7+
from ethereum_test_forks.helpers import Fork
68
from ethereum_test_tools import Account, Alloc, Environment, StateTestFiller, Transaction
79
from ethereum_test_types.eof.v1 import Container, Section
810
from ethereum_test_vm import Bytecode, EVMCodeType
@@ -24,6 +26,7 @@
2426

2527

2628
def gas_test(
29+
fork: Fork,
2730
state_test: StateTestFiller,
2831
env: Environment,
2932
pre: Alloc,
@@ -48,6 +51,9 @@ def gas_test(
4851
test, and MUST NOT have any side-effects which persist across message
4952
calls, and in particular, any effects on the gas usage of `subject_code`.
5053
"""
54+
if fork < Berlin:
55+
raise ValueError("Gas tests before Berlin are not supported due to CALL gas changes")
56+
5157
if cold_gas <= 0:
5258
raise ValueError(f"Target gas allocations (cold_gas) must be > 0, got {cold_gas}")
5359
if warm_gas is None:

0 commit comments

Comments
 (0)