|
5 | 5 |
|
6 | 6 | import pytest
|
7 | 7 |
|
8 |
| -from ethereum_test_tools import Alloc, Environment, StateTestFiller, Transaction |
| 8 | +from ethereum_test_forks import Fork |
| 9 | +from ethereum_test_tools import ( |
| 10 | + EOA, |
| 11 | + Address, |
| 12 | + Alloc, |
| 13 | + Environment, |
| 14 | + StateTestFiller, |
| 15 | + Transaction, |
| 16 | +) |
9 | 17 | from ethereum_test_tools import Opcodes as Op
|
10 | 18 |
|
11 | 19 | from .conftest import (
|
|
15 | 23 | G2_POINTS_NOT_ON_CURVE,
|
16 | 24 | )
|
17 | 25 | from .helpers import vectors_from_file
|
18 |
| -from .spec import PointG1, PointG2, Spec, ref_spec_2537 |
| 26 | +from .spec import PointG1, PointG2, Spec, pairing_gas, ref_spec_2537 |
19 | 27 |
|
20 | 28 | REFERENCE_SPEC_GIT_PATH = ref_spec_2537.git_path
|
21 | 29 | REFERENCE_SPEC_VERSION = ref_spec_2537.version
|
|
49 | 57 | None,
|
50 | 58 | id="inf_pair",
|
51 | 59 | ),
|
52 |
| - pytest.param( # 1000 copies of e(inf, inf) == 1 |
53 |
| - (Spec.INF_G1 + Spec.INF_G2) * 1000, |
54 |
| - Spec.PAIRING_TRUE, |
55 |
| - None, |
56 |
| - id="multi_inf_pair", |
57 |
| - ), |
58 | 60 | pytest.param( # e(P, Q) . e(P, −Q) == 1 (inverse pair, factors cancel)
|
59 | 61 | Spec.G1 + Spec.G2 + Spec.G1 + (-Spec.G2),
|
60 | 62 | Spec.PAIRING_TRUE,
|
@@ -133,6 +135,57 @@ def test_valid(
|
133 | 135 | )
|
134 | 136 |
|
135 | 137 |
|
| 138 | +@pytest.mark.slow |
| 139 | +@pytest.mark.parametrize("precompile_gas", [None], ids=[""]) |
| 140 | +@pytest.mark.parametrize("expected_output", [Spec.PAIRING_TRUE], ids=[""]) |
| 141 | +def test_valid_multi_inf( |
| 142 | + state_test: StateTestFiller, |
| 143 | + pre: Alloc, |
| 144 | + call_contract_address: Address, |
| 145 | + sender: EOA, |
| 146 | + fork: Fork, |
| 147 | + post: dict, |
| 148 | +): |
| 149 | + """ |
| 150 | + Test maximum input given the current environment gas limit for the BLS12_PAIRING |
| 151 | + precompile. |
| 152 | + """ |
| 153 | + intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator() |
| 154 | + memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator() |
| 155 | + extra_gas = 100_000 |
| 156 | + |
| 157 | + environment_gas_limit = Environment().gas_limit |
| 158 | + |
| 159 | + inf_data = Spec.INF_G1 + Spec.INF_G2 |
| 160 | + input_data = inf_data |
| 161 | + |
| 162 | + while True: |
| 163 | + precompile_gas = pairing_gas(len(input_data + inf_data)) |
| 164 | + new_tx_gas_limit = ( |
| 165 | + extra_gas |
| 166 | + + intrinsic_gas_cost_calculator(calldata=input_data + inf_data) |
| 167 | + + memory_expansion_gas_calculator(new_bytes=len(input_data + inf_data)) |
| 168 | + + precompile_gas |
| 169 | + ) |
| 170 | + if new_tx_gas_limit > environment_gas_limit: |
| 171 | + break |
| 172 | + tx_gas_limit = new_tx_gas_limit |
| 173 | + input_data += inf_data |
| 174 | + |
| 175 | + tx = Transaction( |
| 176 | + gas_limit=tx_gas_limit, |
| 177 | + data=input_data, |
| 178 | + to=call_contract_address, |
| 179 | + sender=sender, |
| 180 | + ) |
| 181 | + state_test( |
| 182 | + env=Environment(), |
| 183 | + pre=pre, |
| 184 | + tx=tx, |
| 185 | + post=post, |
| 186 | + ) |
| 187 | + |
| 188 | + |
136 | 189 | @pytest.mark.parametrize(
|
137 | 190 | "input_data",
|
138 | 191 | # Test vectors from the reference spec (from the cryptography team)
|
@@ -180,10 +233,6 @@ def test_valid(
|
180 | 233 | Spec.INF_G1 + Spec.P2_NOT_IN_SUBGROUP,
|
181 | 234 | id="p2_not_in_subgroup",
|
182 | 235 | ),
|
183 |
| - pytest.param( |
184 |
| - (Spec.INF_G1 + Spec.INF_G2) * 1000 + PointG1(Spec.P, 0) + Spec.INF_G2, |
185 |
| - id="long_input_with_invalid_tail", |
186 |
| - ), |
187 | 236 | # Points not in the subgroup or not on the curve randomly generated.
|
188 | 237 | pytest.param(
|
189 | 238 | G1_POINTS_NOT_ON_CURVE[0] + Spec.INF_G2,
|
@@ -235,6 +284,57 @@ def test_invalid(
|
235 | 284 | )
|
236 | 285 |
|
237 | 286 |
|
| 287 | +@pytest.mark.slow |
| 288 | +@pytest.mark.parametrize("precompile_gas", [None], ids=[""]) |
| 289 | +@pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""]) |
| 290 | +def test_invalid_multi_inf( |
| 291 | + state_test: StateTestFiller, |
| 292 | + pre: Alloc, |
| 293 | + call_contract_address: Address, |
| 294 | + sender: EOA, |
| 295 | + fork: Fork, |
| 296 | + post: dict, |
| 297 | +): |
| 298 | + """ |
| 299 | + Test maximum input given the current environment gas limit for the BLS12_PAIRING |
| 300 | + precompile and an invalid tail. |
| 301 | + """ |
| 302 | + intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator() |
| 303 | + memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator() |
| 304 | + extra_gas = 100_000 |
| 305 | + |
| 306 | + environment_gas_limit = Environment().gas_limit |
| 307 | + |
| 308 | + inf_data = Spec.INF_G1 + Spec.INF_G2 |
| 309 | + input_data = PointG1(Spec.P, 0) + Spec.INF_G2 |
| 310 | + |
| 311 | + while True: |
| 312 | + precompile_gas = pairing_gas(len(input_data + inf_data)) |
| 313 | + new_tx_gas_limit = ( |
| 314 | + extra_gas |
| 315 | + + intrinsic_gas_cost_calculator(calldata=input_data + inf_data) |
| 316 | + + memory_expansion_gas_calculator(new_bytes=len(input_data + inf_data)) |
| 317 | + + precompile_gas |
| 318 | + ) |
| 319 | + if new_tx_gas_limit > environment_gas_limit: |
| 320 | + break |
| 321 | + tx_gas_limit = new_tx_gas_limit |
| 322 | + input_data = inf_data + input_data |
| 323 | + |
| 324 | + tx = Transaction( |
| 325 | + gas_limit=tx_gas_limit, |
| 326 | + data=input_data, |
| 327 | + to=call_contract_address, |
| 328 | + sender=sender, |
| 329 | + ) |
| 330 | + state_test( |
| 331 | + env=Environment(), |
| 332 | + pre=pre, |
| 333 | + tx=tx, |
| 334 | + post=post, |
| 335 | + ) |
| 336 | + |
| 337 | + |
238 | 338 | @pytest.mark.parametrize(
|
239 | 339 | "input_data,expected_output,precompile_gas_modifier",
|
240 | 340 | [
|
|
0 commit comments