Skip to content

Commit 7bd5794

Browse files
refactor: update naming and new cases
1 parent df29c1d commit 7bd5794

File tree

1 file changed

+107
-59
lines changed

1 file changed

+107
-59
lines changed

tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds.py

Lines changed: 107 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
vectors_from_file("vectors.json"),
2727
ids=lambda v: v.name,
2828
)
29-
def test_vectors_from_file(
29+
def test_vectors_from_eip(
3030
state_test: StateTestFiller,
3131
pre: Alloc,
3232
tx: Transaction,
@@ -99,47 +99,48 @@ def test_modexp_invalid_inputs(
9999
)
100100

101101

102-
def create_boundary_modexp_case(
103-
base: str = "FF", exponent: str = "FF", modulus: str = "FF", case_id: str = ""
104-
):
105-
"""
106-
Create a single boundary ModExp test case.
107-
108-
Args:
109-
base: Base data (hex string)
110-
exponent: Exponent data (hex string)
111-
modulus: Modulus data (hex string)
112-
case_id: Test case identifier
113-
114-
Returns:
115-
pytest.param for the test case
116-
117-
"""
118-
modexp_input = ModExpInput(
119-
base=base,
120-
exponent=exponent,
121-
modulus=modulus,
122-
)
123-
return pytest.param(modexp_input, Spec.modexp_error, False, id=case_id)
124-
125-
126102
@pytest.mark.parametrize(
127103
"modexp_input,modexp_expected,call_succeeds",
128104
[
129-
create_boundary_modexp_case(
130-
base="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="base-too-long"
105+
pytest.param(
106+
ModExpInput(
107+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
108+
exponent="FF",
109+
modulus="FF",
110+
),
111+
Spec.modexp_error,
112+
False,
113+
id="base-too-long",
131114
),
132-
create_boundary_modexp_case(
133-
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="exponent-too-long"
115+
pytest.param(
116+
ModExpInput(
117+
base="FF",
118+
exponent="FF" * (Spec.MAX_LENGTH_BYTES + 1),
119+
modulus="FF",
120+
),
121+
Spec.modexp_error,
122+
False,
123+
id="exponent-too-long",
134124
),
135-
create_boundary_modexp_case(
136-
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1), case_id="modulus-too-long"
125+
pytest.param(
126+
ModExpInput(
127+
base="FF",
128+
exponent="FF",
129+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
130+
),
131+
Spec.modexp_error,
132+
False,
133+
id="modulus-too-long",
137134
),
138-
create_boundary_modexp_case(
139-
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
140-
exponent="FF",
141-
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
142-
case_id="base-modulus-too-long",
135+
pytest.param(
136+
ModExpInput(
137+
base="FF" * (Spec.MAX_LENGTH_BYTES + 1),
138+
exponent="FF",
139+
modulus="FF" * (Spec.MAX_LENGTH_BYTES + 1),
140+
),
141+
Spec.modexp_error,
142+
False,
143+
id="base-modulus-too-long",
143144
),
144145
],
145146
)
@@ -219,13 +220,13 @@ def test_modexp_call_operations(
219220
@EIPChecklist.Precompile.Test.ValueTransfer.Fee.Over
220221
@EIPChecklist.Precompile.Test.ValueTransfer.Fee.Exact
221222
@EIPChecklist.Precompile.Test.ValueTransfer.Fee.Under
222-
def test_modexp_gas_usage(
223+
def test_modexp_gas_usage_contract_wrapper(
223224
state_test: StateTestFiller,
224225
pre: Alloc,
225226
tx: Transaction,
226227
post: Dict,
227228
):
228-
"""Test ModExp gas cost with different precompile gas modifiers."""
229+
"""Test ModExp gas cost with different gas modifiers using contract wrapper calls."""
229230
state_test(pre=pre, tx=tx, post=post)
230231

231232

@@ -255,14 +256,14 @@ def test_modexp_gas_usage(
255256
),
256257
],
257258
)
258-
def test_modexp_entry_points(
259+
def test_modexp_used_in_transaction_entry_points(
259260
state_test: StateTestFiller,
260261
pre: Alloc,
261262
tx: Transaction,
262263
modexp_input: bytes,
263264
tx_gas_limit: int,
264265
):
265-
"""Test ModExp entry points with different precompile gas modifiers."""
266+
"""Test ModExp using in transaction entry points with different precompile gas modifiers."""
266267
tx = Transaction(
267268
to=Spec.MODEXP_ADDRESS,
268269
sender=pre.fund_eoa(),
@@ -296,6 +297,34 @@ def create_modexp_variable_gas_test_cases():
296297
("01" * 40, "00" * 39 + "01", "02" * 40, "01" * 40, "L3"),
297298
("01" * 48, "01", "02" * 16, "01" * 16, "L4"),
298299
("01" * 16, "00" * 40, "02" * 48, "00" * 47 + "01", "L5"),
300+
# Critical 32-byte boundary cases
301+
("01" * 31, "01", "02" * 33, "00" * 2 + "01" * 31, "B1"),
302+
("01" * 33, "01", "02" * 31, "00" * 29 + "01" * 2, "B2"),
303+
("01" * 33, "01", "02" * 33, "01" * 33, "B4"),
304+
# Zero value edge cases
305+
("00" * 32, "00" * 32, "01" * 32, "00" * 31 + "01", "Z1"),
306+
("01" * 32, "00" * 32, "00" * 32, "00" * 32, "Z2"),
307+
("00" * 32, "01" * 32, "02" * 32, "00" * 32, "Z3"),
308+
# Maximum value stress tests
309+
("FF" * 64, "FF" * 64, "FF" * 64, "00" * 64, "M1"),
310+
("FF" * 32, "01", "FF" * 32, "00" * 32, "M2"),
311+
("01", "FF" * 64, "FF" * 64, "00" * 63 + "01", "M3"),
312+
# Tiny maximum values
313+
("FF", "FE", "FD", "47", "T2"),
314+
# Bit pattern cases
315+
("01" * 32, "80" * 32, "02" * 32, "01" * 32, "P2"),
316+
("01" * 33, "00" * 31 + "80" + "00", "02" * 33, "01" * 33, "P3"),
317+
# Asymmetric length cases
318+
("01", "00" * 64, "02" * 64, "00" * 63 + "01", "A1"),
319+
("01" * 64, "01", "02", "01", "A2"),
320+
("01" * 64, "00" * 64, "02", "01", "A3"),
321+
# Word boundary case
322+
("01" * 8, "01", "02" * 8, "0101010101010101", "W2"),
323+
# Exponent edge cases
324+
("01" * 16, "00" * 32 + "01", "02" * 16, "01" * 16, "E1"),
325+
("01" * 16, "80" + "00" * 31, "02" * 16, "01" * 16, "E2"),
326+
("01" * 16, "00" * 31 + "80", "02" * 16, "01" * 16, "E3"),
327+
("01" * 16, "7F" + "FF" * 31, "02" * 16, "01" * 16, "E4"),
299328
]
300329

301330
# Gas calculation parameters:
@@ -318,25 +347,44 @@ def create_modexp_variable_gas_test_cases():
318347
# - Clamp: True if raw gas < 500 (clamped to 500), False if raw gas ≥ 500 (no clamping)
319348

320349
# Test case coverage table:
321-
# ┌─────┬──────┬─────┬──────┬───────┬─────────┬─────────────────────────────────────────────┐
322-
# │ ID │ Comp │ Rel │ Iter │ Clamp │ Gas │ Description │
323-
# ├─────┼──────┼─────┼──────┼───────┼─────────┼─────────────────────────────────────────────┤
324-
# │ Z0 │ - │ - │ - │ - │ 500 │ Zero case - empty inputs │
325-
# │ S0 │ S │ = │ A │ True │ 500 │ Small, equal, zero exponent, clamped │
326-
# │ S1 │ S │ = │ B │ True │ 500 │ Small, equal, small exp, clamped │
327-
# │ S2 │ S │ = │ B │ False │ 4080 │ Small, equal, large exp, unclamped │
328-
# │ S3 │ S │ = │ C │ False │ 2032 │ Small, equal, large exp+zero low256 │
329-
# │ S4 │ S │ = │ D │ False │ 2048 │ Small, equal, large exp+non-zero low256 │
330-
# │ S5 │ S │ > │ A │ True │ 500 │ Small, base>mod, zero exp, clamped │
331-
# │ S6 │ S │ < │ B │ True │ 500 │ Small, base<mod, small exp, clamped │
332-
# │ L0 │ L │ = │ A │ True │ 500 │ Large, equal, zero exp, clamped │
333-
# │ L1 │ L │ = │ B │ False │ 12750 │ Large, equal, large exp, unclamped │
334-
# │ L2 │ L │ = │ C │ False │ 6350 │ Large, equal, large exp+zero low256 │
335-
# │ L3 │ L │ = │ D │ False │ 6400 │ Large, equal, large exp+non-zero low256 │
336-
# │ L4 │ L │ > │ B │ True │ 500 │ Large, base>mod, small exp, clamped │
337-
# │ L5 │ L │ < │ C │ False │ 9144 │ Large, base<mod, large exp+zero low256 │
338-
# └─────┴──────┴─────┴──────┴───────┴─────────┴─────────────────────────────────────────────┘
339-
350+
# ┌─────┬──────┬─────┬──────┬───────┬─────────┬───────────────────────────────────────────────┐
351+
# │ ID │ Comp │ Rel │ Iter │ Clamp │ Gas │ Description │
352+
# ├─────┼──────┼─────┼──────┼───────┼─────────┼───────────────────────────────────────────────┤
353+
# │ Z0 │ - │ - │ - │ - │ 500 │ Zero case – empty inputs │
354+
# │ S0 │ S │ = │ A │ True │ 500 │ Small, equal, zero exp, clamped │
355+
# │ S1 │ S │ = │ B │ True │ 500 │ Small, equal, small exp, clamped │
356+
# │ S2 │ S │ = │ B │ False │ 4080 │ Small, equal, large exp, unclamped │
357+
# │ S3 │ S │ = │ C │ False │ 2032 │ Small, equal, large exp + zero low256 │
358+
# │ S4 │ S │ = │ D │ False │ 2048 │ Small, equal, large exp + non-zero low256 │
359+
# │ S5 │ S │ > │ A │ True │ 500 │ Small, base > mod, zero exp, clamped │
360+
# │ S6 │ S │ < │ B │ True │ 500 │ Small, base < mod, small exp, clamped │
361+
# │ L0 │ L │ = │ A │ True │ 500 │ Large, equal, zero exp, clamped │
362+
# │ L1 │ L │ = │ B │ False │ 12750 │ Large, equal, large exp, unclamped │
363+
# │ L2 │ L │ = │ C │ False │ 6350 │ Large, equal, large exp + zero low256 │
364+
# │ L3 │ L │ = │ D │ False │ 6400 │ Large, equal, large exp + non-zero low256 │
365+
# │ L4 │ L │ > │ B │ True │ 500 │ Large, base > mod, small exp, clamped │
366+
# │ L5 │ L │ < │ C │ False │ 9144 │ Large, base < mod, large exp + zero low256 │
367+
# │ B1 │ L │ < │ B │ True │ 500 │ Cross 32-byte boundary (31/33) │
368+
# │ B2 │ L │ > │ B │ True │ 500 │ Cross 32-byte boundary (33/31) │
369+
# │ B4 │ L │ = │ B │ True │ 500 │ Just over 32-byte boundary │
370+
# │ Z1 │ S │ = │ A │ True │ 500 │ All zeros except modulus │
371+
# │ Z2 │ S │ = │ A │ True │ 500 │ Zero modulus special case │
372+
# │ Z3 │ S │ = │ B │ False │ 3968 │ Zero base, large exponent │
373+
# │ M1 │ L │ = │ D │ False │ 98176 │ Maximum values stress test │
374+
# │ M2 │ S │ = │ B │ True │ 500 │ Max base/mod, small exponent │
375+
# │ M3 │ L │ < │ D │ False │ 98176 │ Small base, max exponent/mod │
376+
# │ T2 │ S │ = │ B │ True │ 500 │ Tiny maximum values │
377+
# │ P2 │ S │ = │ B │ False │ 4080 │ High bit in exponent │
378+
# │ P3 │ L │ = │ D │ False │ 1550 │ Specific bit pattern in large exponent │
379+
# │ A1 │ L │ < │ C │ False │ 65408 │ Asymmetric: tiny base, large exp/mod │
380+
# │ A2 │ L │ > │ B │ True │ 500 │ Asymmetric: large base, tiny exp/mod │
381+
# │ A3 │ L │ > │ C │ False │ 65408 │ Asymmetric: large base/exp, tiny modulus │
382+
# │ W2 │ S │ = │ B │ True │ 500 │ Exactly 8-byte words │
383+
# │ E1 │ S │ = │ D │ True │ 500 │ Exponent exactly 33 bytes │
384+
# │ E2 │ S │ = │ B │ False │ 4080 │ High bit in exponent first byte │
385+
# │ E3 │ S │ = │ B │ True │ 500 │ High bit in exponent last byte │
386+
# │ E4 │ S │ = │ B │ False │ 4064 │ Maximum 32-byte exponent │
387+
# └─────┴──────┴─────┴──────┴───────┴─────────┴───────────────────────────────────────────────┘
340388
for base, exponent, modulus, expected_result, test_id in test_cases:
341389
yield pytest.param(
342390
ModExpInput(base=base, exponent=exponent, modulus=modulus),

0 commit comments

Comments
 (0)