Skip to content

Commit 6084805

Browse files
refactor compute precompile folder
1 parent f360809 commit 6084805

File tree

10 files changed

+1404
-0
lines changed

10 files changed

+1404
-0
lines changed

tests/benchmark/compute/precompile/alt_bn128.py

Lines changed: 488 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Benchmark BLAKE2F precompile."""
2+
3+
import pytest
4+
from ethereum_test_benchmark import JumpLoopGenerator
5+
from ethereum_test_forks import Fork
6+
from ethereum_test_tools import (
7+
Address,
8+
BenchmarkTestFiller,
9+
)
10+
from ethereum_test_vm import Opcodes as Op
11+
12+
from tests.benchmark.compute.helpers import concatenate_parameters
13+
from tests.istanbul.eip152_blake2.common import Blake2bInput
14+
from tests.istanbul.eip152_blake2.spec import Spec as Blake2bSpec
15+
16+
17+
@pytest.mark.parametrize(
18+
"precompile_address,calldata",
19+
[
20+
pytest.param(
21+
Blake2bSpec.BLAKE2_PRECOMPILE_ADDRESS,
22+
concatenate_parameters(
23+
[
24+
Blake2bInput(
25+
rounds=0xFFFF, f=True
26+
).create_blake2b_tx_data(),
27+
]
28+
),
29+
id="blake2f",
30+
),
31+
],
32+
)
33+
def test_blake2f(
34+
benchmark_test: BenchmarkTestFiller,
35+
fork: Fork,
36+
precompile_address: Address,
37+
calldata: bytes,
38+
) -> None:
39+
"""Benchmark BLAKE2F precompile."""
40+
if precompile_address not in fork.precompiles():
41+
pytest.skip("Precompile not enabled")
42+
43+
attack_block = Op.POP(
44+
Op.STATICCALL(
45+
gas=Op.GAS, address=precompile_address, args_size=Op.CALLDATASIZE
46+
),
47+
)
48+
49+
benchmark_test(
50+
code_generator=JumpLoopGenerator(
51+
setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE),
52+
attack_block=attack_block,
53+
tx_kwargs={"data": calldata},
54+
),
55+
)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""Benchmark BLS12_381 precompile."""
2+
3+
import pytest
4+
from ethereum_test_benchmark import JumpLoopGenerator
5+
from ethereum_test_forks import Fork
6+
from ethereum_test_tools import (
7+
Address,
8+
BenchmarkTestFiller,
9+
)
10+
from ethereum_test_vm import Opcodes as Op
11+
12+
from tests.benchmark.compute.helpers import concatenate_parameters
13+
from tests.prague.eip2537_bls_12_381_precompiles import spec as bls12381_spec
14+
15+
16+
@pytest.mark.parametrize(
17+
"precompile_address,calldata",
18+
[
19+
pytest.param(
20+
bls12381_spec.Spec.G1ADD,
21+
concatenate_parameters(
22+
[
23+
bls12381_spec.Spec.G1,
24+
bls12381_spec.Spec.P1,
25+
]
26+
),
27+
id="bls12_g1add",
28+
),
29+
pytest.param(
30+
bls12381_spec.Spec.G1MSM,
31+
concatenate_parameters(
32+
[
33+
(
34+
bls12381_spec.Spec.P1
35+
+ bls12381_spec.Scalar(bls12381_spec.Spec.Q)
36+
)
37+
* (len(bls12381_spec.Spec.G1MSM_DISCOUNT_TABLE) - 1),
38+
]
39+
),
40+
id="bls12_g1msm",
41+
),
42+
pytest.param(
43+
bls12381_spec.Spec.G2ADD,
44+
concatenate_parameters(
45+
[
46+
bls12381_spec.Spec.G2,
47+
bls12381_spec.Spec.P2,
48+
]
49+
),
50+
id="bls12_g2add",
51+
),
52+
pytest.param(
53+
bls12381_spec.Spec.G2MSM,
54+
concatenate_parameters(
55+
[
56+
# TODO: the //2 is required due to a limitation of the max
57+
# contract size limit. In a further iteration we can insert
58+
# inputs as calldata or storage and avoid doing PUSHes
59+
# which has this limitation. This also applies to G1MSM.
60+
(
61+
bls12381_spec.Spec.P2
62+
+ bls12381_spec.Scalar(bls12381_spec.Spec.Q)
63+
)
64+
* (len(bls12381_spec.Spec.G2MSM_DISCOUNT_TABLE) // 2),
65+
]
66+
),
67+
id="bls12_g2msm",
68+
),
69+
pytest.param(
70+
bls12381_spec.Spec.PAIRING,
71+
concatenate_parameters(
72+
[
73+
bls12381_spec.Spec.G1,
74+
bls12381_spec.Spec.G2,
75+
]
76+
),
77+
id="bls12_pairing_check",
78+
),
79+
pytest.param(
80+
bls12381_spec.Spec.MAP_FP_TO_G1,
81+
concatenate_parameters(
82+
[
83+
bls12381_spec.FP(bls12381_spec.Spec.P - 1),
84+
]
85+
),
86+
id="bls12_fp_to_g1",
87+
),
88+
pytest.param(
89+
bls12381_spec.Spec.MAP_FP2_TO_G2,
90+
concatenate_parameters(
91+
[
92+
bls12381_spec.FP2(
93+
(bls12381_spec.Spec.P - 1, bls12381_spec.Spec.P - 1)
94+
),
95+
]
96+
),
97+
id="bls12_fp_to_g2",
98+
),
99+
],
100+
)
101+
def test_bls12_381(
102+
benchmark_test: BenchmarkTestFiller,
103+
fork: Fork,
104+
precompile_address: Address,
105+
calldata: bytes,
106+
) -> None:
107+
"""Benchmark BLS12_381 precompile."""
108+
if precompile_address not in fork.precompiles():
109+
pytest.skip("Precompile not enabled")
110+
111+
attack_block = Op.POP(
112+
Op.STATICCALL(
113+
gas=Op.GAS, address=precompile_address, args_size=Op.CALLDATASIZE
114+
),
115+
)
116+
117+
benchmark_test(
118+
code_generator=JumpLoopGenerator(
119+
setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE),
120+
attack_block=attack_block,
121+
tx_kwargs={"data": calldata},
122+
),
123+
)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Benchmark ECRECOVER precompile."""
2+
3+
import pytest
4+
from ethereum_test_benchmark import JumpLoopGenerator
5+
from ethereum_test_forks import Fork
6+
from ethereum_test_tools import (
7+
Address,
8+
BenchmarkTestFiller,
9+
)
10+
from ethereum_test_vm import Opcodes as Op
11+
12+
from tests.benchmark.compute.helpers import concatenate_parameters
13+
14+
15+
@pytest.mark.parametrize(
16+
"precompile_address,calldata",
17+
[
18+
pytest.param(
19+
0x01,
20+
concatenate_parameters(
21+
[
22+
# Inputs below are a valid signature, thus ECRECOVER call
23+
# will perform full computation, not blocked by validation.
24+
"38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E",
25+
"000000000000000000000000000000000000000000000000000000000000001B",
26+
"38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E",
27+
"789D1DD423D25F0772D2748D60F7E4B81BB14D086EBA8E8E8EFB6DCFF8A4AE02",
28+
]
29+
),
30+
id="ecrecover",
31+
)
32+
],
33+
)
34+
def test_ecrecover(
35+
benchmark_test: BenchmarkTestFiller,
36+
fork: Fork,
37+
precompile_address: Address,
38+
calldata: bytes,
39+
) -> None:
40+
"""Benchmark ECRECOVER precompile."""
41+
if precompile_address not in fork.precompiles():
42+
pytest.skip("Precompile not enabled")
43+
44+
attack_block = Op.POP(
45+
Op.STATICCALL(
46+
gas=Op.GAS, address=precompile_address, args_size=Op.CALLDATASIZE
47+
),
48+
)
49+
50+
benchmark_test(
51+
code_generator=JumpLoopGenerator(
52+
setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE),
53+
attack_block=attack_block,
54+
tx_kwargs={"data": calldata},
55+
),
56+
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Benchmark IDENTITY precompile."""
2+
3+
from ethereum_test_benchmark import JumpLoopGenerator
4+
from ethereum_test_forks import Fork
5+
from ethereum_test_tools import (
6+
BenchmarkTestFiller,
7+
)
8+
from ethereum_test_vm import Opcodes as Op
9+
10+
from tests.benchmark.compute.helpers import calculate_optimal_input_length
11+
12+
13+
def test_identity(
14+
benchmark_test: BenchmarkTestFiller,
15+
fork: Fork,
16+
gas_benchmark_value: int,
17+
) -> None:
18+
"""Benchmark IDENTITY precompile."""
19+
intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator()
20+
gas_available = gas_benchmark_value - intrinsic_gas_calculator()
21+
22+
optimal_input_length = calculate_optimal_input_length(
23+
available_gas=gas_available,
24+
fork=fork,
25+
static_cost=15,
26+
per_word_dynamic_cost=3,
27+
bytes_per_unit_of_work=1,
28+
)
29+
30+
attack_block = Op.POP(
31+
Op.STATICCALL(
32+
Op.GAS, 0x04, Op.PUSH0, optimal_input_length, Op.PUSH0, Op.PUSH0
33+
)
34+
)
35+
36+
benchmark_test(
37+
code_generator=JumpLoopGenerator(
38+
setup=Op.CODECOPY(0, 0, optimal_input_length),
39+
attack_block=attack_block,
40+
),
41+
)

0 commit comments

Comments
 (0)