@pytest.mark.parametrize(
"precompile_address,calldata,target",
[
pytest.param(
bls12381_spec.Spec.G1ADD,
bls12381_spec.Spec.G1 + bls12381_spec.Spec.P1,
Precompile.BLS12_G1ADD,
id="bls12_g1add",
marks=pytest.mark.repricing,
),
pytest.param(
bls12381_spec.Spec.G1MSM,
(
bls12381_spec.Spec.P1
+ bls12381_spec.Scalar(bls12381_spec.Spec.Q)
)
* (len(bls12381_spec.Spec.G1MSM_DISCOUNT_TABLE) - 1),
Precompile.BLS12_G1MSM,
id="bls12_g1msm",
),
pytest.param(
bls12381_spec.Spec.G2ADD,
bls12381_spec.Spec.G2 + bls12381_spec.Spec.P2,
Precompile.BLS12_G2ADD,
id="bls12_g2add",
marks=pytest.mark.repricing,
),
pytest.param(
bls12381_spec.Spec.G2MSM,
# TODO: the //2 is required due to a limitation of the max
# contract size limit. In a further iteration we can insert
# inputs as calldata or storage and avoid doing PUSHes which
# has this limitation. This also applies to G1MSM.
(
bls12381_spec.Spec.P2
+ bls12381_spec.Scalar(bls12381_spec.Spec.Q)
)
* (len(bls12381_spec.Spec.G2MSM_DISCOUNT_TABLE) // 2),
Precompile.BLS12_G2MSM,
id="bls12_g2msm",
),
pytest.param(
bls12381_spec.Spec.PAIRING,
bls12381_spec.Spec.G1 + bls12381_spec.Spec.G2,
Precompile.BLS12_PAIRING,
id="bls12_pairing_check",
),
pytest.param(
bls12381_spec.Spec.MAP_FP_TO_G1,
bls12381_spec.FP(bls12381_spec.Spec.P - 1),
Precompile.BLS12_MAP_FP_TO_G1,
id="bls12_fp_to_g1",
marks=pytest.mark.repricing,
),
pytest.param(
bls12381_spec.Spec.MAP_FP2_TO_G2,
bls12381_spec.FP2(
(bls12381_spec.Spec.P - 1, bls12381_spec.Spec.P - 1)
),
Precompile.BLS12_MAP_FP2_TO_G2,
id="bls12_fp_to_g2",
marks=pytest.mark.repricing,
),
],
)
def test_bls12_381(
benchmark_test: BenchmarkTestFiller,
fork: Fork,
precompile_address: Address,
calldata: bytes,
target: OpcodeTarget,
) -> None:
"""Benchmark BLS12_381 precompile."""
if precompile_address not in fork.precompiles():
pytest.skip("Precompile not enabled")
attack_block = Op.POP(
Op.STATICCALL(
gas=Op.GAS, address=precompile_address, args_size=Op.CALLDATASIZE
),
)
benchmark_test(
target_opcode=target,
code_generator=JumpLoopGenerator(
setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE),
attack_block=attack_block,
tx_kwargs={"data": calldata},
),
)