Skip to content

test_calldatacopy_from_call()

Documentation for tests/benchmark/compute/instruction/test_call_context.py::test_calldatacopy_from_call@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/benchmark/compute/instruction/test_call_context.py::test_calldatacopy_from_call --gas-benchmark-values 1

Benchmark CALLDATACOPY instruction.

Source code in tests/benchmark/compute/instruction/test_call_context.py
@pytest.mark.parametrize(
    "fixed_src_dst",
    [
        True,
        False,
    ],
)
@pytest.mark.parametrize(
    "calldata_size,non_zero_data",
    [
        (size, nzd)
        for size in [0, 32, 256, 1024]
        for nzd in [True, False]
        if not (size == 0 and nzd)
    ],
)
def test_calldatacopy_from_call(
    benchmark_test: BenchmarkTestFiller,
    fork: Fork,
    calldata_size: int,
    fixed_src_dst: bool,
    non_zero_data: bool,
    tx_gas_limit: int,
) -> None:
    """Benchmark CALLDATACOPY instruction."""
    # If `non_zero_data` is True, we fill the calldata with deterministic
    # random data.
    data = (
        Bytes([i % 256 for i in range(calldata_size)])
        if non_zero_data
        else Bytes()
    )

    intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator()
    min_gas = intrinsic_gas_calculator(calldata=data)
    if min_gas > tx_gas_limit:
        pytest.skip(
            f"Intrinsic gas for calldata ({min_gas}) exceeds "
            f"tx gas limit ({tx_gas_limit})"
        )

    # We create the contract that will be doing the CALLDATACOPY multiple
    # times.
    #
    # If `non_zero_data` is True, we leverage CALLDATASIZE for the copy
    # length. Otherwise, since we
    # don't send zero data explicitly via calldata, PUSH the target size and
    # use DUP1 to copy it.
    setup = (
        Bytecode()
        if non_zero_data or calldata_size == 0
        else Op.PUSH3(calldata_size)
    )
    src_dst = 0 if fixed_src_dst else Op.AND(Op.GAS, 7)
    attack_block = Op.CALLDATACOPY(
        src_dst,
        src_dst,
        Op.CALLDATASIZE if non_zero_data or calldata_size == 0 else Op.DUP1,
    )

    benchmark_test(
        target_opcode=Op.CALLDATACOPY,
        code_generator=ExtCallGenerator(
            setup=setup,
            attack_block=attack_block,
            tx_kwargs={"data": data},
        ),
    )

Parametrized Test Cases

This test generates 14 parametrized test cases across 4 forks.