Skip to content

Commit 3e9d75c

Browse files
feat: add invalud boundary test cases
1 parent 197625e commit 3e9d75c

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

tests/osaka/eip7883_modexp_gas_increase/conftest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,21 @@ def tx_gas_limit(
178178
memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator()
179179
sstore_gas = fork.gas_costs().G_STORAGE_SET * (len(modexp_expected) // 32)
180180
extra_gas = 100_000
181-
return (
181+
182+
total_gas = (
182183
extra_gas
183184
+ intrinsic_gas_cost_calculator(calldata=bytes(modexp_input))
184185
+ memory_expansion_gas_calculator(new_bytes=len(bytes(modexp_input)))
185186
+ precompile_gas
186187
+ sstore_gas
187188
)
188189

190+
tx_gas_limit_cap = fork.transaction_gas_limit_cap()
191+
192+
if tx_gas_limit_cap is not None:
193+
return min(tx_gas_limit_cap, total_gas)
194+
return total_gas
195+
189196

190197
@pytest.fixture
191198
def post(

tests/osaka/eip7883_modexp_gas_increase/spec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Spec:
3434
LARGE_BASE_MODULUS_MULTIPLIER = 1
3535
MAX_LENGTH_THRESHOLD = 32
3636
EXPONENT_BYTE_MULTIPLIER = 8
37+
MAX_LENGTH_BYTES = 1024
3738

3839
WORD_SIZE = 8
3940
EXPONENT_THRESHOLD = 32

tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds.py

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
)
1616
from ethereum_test_tools.vm.opcode import Opcodes as Op
1717

18+
from ...byzantium.eip198_modexp_precompile.helpers import ModExpInput
1819
from .helpers import vectors_from_file
1920
from .spec import Spec, ref_spec_7883
2021

@@ -75,9 +76,9 @@ def create_modexp_input(
7576
return bytes.fromhex(input_hex)
7677

7778

78-
def generate_invalid_inputs_cases():
79-
"""Generate test cases for invalid ModExp inputs."""
80-
return [
79+
@pytest.mark.parametrize(
80+
"modexp_input,modexp_expected,call_succeeds",
81+
[
8182
pytest.param(bytes(), bytes(), False, id="zero-length-calldata"),
8283
pytest.param(
8384
create_modexp_input(10, 11, 12, b_data="FF" * 9),
@@ -103,21 +104,92 @@ def generate_invalid_inputs_cases():
103104
False,
104105
id="all-zeros",
105106
),
106-
]
107+
],
108+
)
109+
@EIPChecklist.Precompile.Test.Inputs.AllZeros
110+
def test_modexp_invalid_inputs(
111+
state_test: StateTestFiller,
112+
pre: Alloc,
113+
tx: Transaction,
114+
post: Dict,
115+
):
116+
"""Test ModExp gas cost with invalid inputs."""
117+
state_test(
118+
pre=pre,
119+
tx=tx,
120+
post=post,
121+
)
122+
123+
124+
def create_boundary_modexp_case(
125+
base: str = "FF", exponent: str = "FF", modulus: str = "FF", case_id: str = ""
126+
):
127+
"""
128+
Create a single boundary ModExp test case.
129+
130+
Args:
131+
base: Base data (hex string)
132+
exponent: Exponent data (hex string)
133+
modulus: Modulus data (hex string)
134+
case_id: Test case identifier
135+
136+
Returns:
137+
pytest.param for the test case
138+
139+
"""
140+
modexp_input = ModExpInput(
141+
base=base,
142+
exponent=exponent,
143+
modulus=modulus,
144+
)
145+
return pytest.param(modexp_input, Spec.modexp_error, False, id=case_id)
107146

108147

109148
@pytest.mark.parametrize(
110149
"modexp_input,modexp_expected,call_succeeds",
111-
generate_invalid_inputs_cases(),
150+
[
151+
create_boundary_modexp_case(
152+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="base-too-long"
153+
),
154+
create_boundary_modexp_case(
155+
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="exponent-too-long"
156+
),
157+
create_boundary_modexp_case(
158+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="modulus-too-long"
159+
),
160+
create_boundary_modexp_case(
161+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
162+
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1),
163+
modulus="FF",
164+
case_id="base-exponent-too-long",
165+
),
166+
create_boundary_modexp_case(
167+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
168+
exponent="FF",
169+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
170+
case_id="base-modulus-too-long",
171+
),
172+
create_boundary_modexp_case(
173+
base="FF",
174+
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1),
175+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
176+
case_id="exponent-modulus-too-long",
177+
),
178+
create_boundary_modexp_case(
179+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
180+
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1),
181+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
182+
case_id="all-too-long",
183+
),
184+
],
112185
)
113-
@EIPChecklist.Precompile.Test.Inputs.AllZeros
114-
def test_modexp_invalid_inputs(
186+
def test_modexp_boundary_inputs(
115187
state_test: StateTestFiller,
116188
pre: Alloc,
117189
tx: Transaction,
118190
post: Dict,
119191
):
120-
"""Test ModExp gas cost with invalid inputs."""
192+
"""Test ModExp boundary inputs."""
121193
state_test(
122194
pre=pre,
123195
tx=tx,

0 commit comments

Comments
 (0)