Skip to content

test_ecrecover()

Documentation for tests/benchmark/compute/precompile/test_ecrecover.py::test_ecrecover@tests-snobal-devnet-6@v1.1.0.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/benchmark/compute/precompile/test_ecrecover.py::test_ecrecover --gas-benchmark-values 1

Benchmark ECRECOVER precompile with unique input per call.

Each loop iteration increments the hash at memory[0] by the STATICCALL success flag (1) so every call receives a distinct input, avoiding precompile result caching in clients.

Source code in tests/benchmark/compute/precompile/test_ecrecover.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@pytest.mark.repricing
@pytest.mark.parametrize(
    "precompile_address,calldata",
    [
        pytest.param(
            0x01,
            concatenate_parameters(
                [
                    # Inputs below are a valid signature, thus ECRECOVER call
                    # will perform full computation, not blocked by validation.
                    "38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E",
                    "000000000000000000000000000000000000000000000000000000000000001B",
                    "38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E",
                    "789D1DD423D25F0772D2748D60F7E4B81BB14D086EBA8E8E8EFB6DCFF8A4AE02",
                ]
            ),
            id="ecrecover",
        )
    ],
)
def test_ecrecover(
    benchmark_test: BenchmarkTestFiller,
    fork: Fork,
    precompile_address: Address,
    calldata: bytes,
) -> None:
    """
    Benchmark ECRECOVER precompile with unique input per call.

    Each loop iteration increments the hash at memory[0] by
    the STATICCALL success flag (1) so every call receives a
    distinct input, avoiding precompile result caching in
    clients.
    """
    if precompile_address not in fork.precompiles():
        pytest.skip("Precompile not enabled")

    attack_block = Op.MSTORE(
        0,
        Op.ADD(
            Op.MLOAD(0),
            Op.STATICCALL(
                gas=Op.GAS,
                address=precompile_address,
                args_size=Op.CALLDATASIZE,
                ret_offset=0x80,
                ret_size=0x20,
            ),
        ),
    )

    benchmark_test(
        target_opcode=Precompile.ECRECOVER,
        code_generator=JumpLoopGenerator(
            setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE),
            attack_block=attack_block,
            tx_kwargs={"data": calldata},
        ),
    )

Parametrized Test Cases

This test generates 1 parametrized test case across 3 forks.