Skip to content

test_worst_calldatacopy()

Documentation for tests/benchmark/test_worst_memory.py::test_worst_calldatacopy@e9958ed2.

Generate fixtures for these test cases for Osaka with:

fill -v tests/benchmark/test_worst_memory.py::test_worst_calldatacopy -m benchmark

Test running a block filled with CALLDATACOPY executions.

Source code in tests/benchmark/test_worst_memory.py
 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
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@pytest.mark.parametrize(
    "origin",
    [
        pytest.param(CallDataOrigin.TRANSACTION, id="transaction"),
        pytest.param(CallDataOrigin.CALL, id="call"),
    ],
)
@pytest.mark.parametrize(
    "size",
    [
        pytest.param(0, id="0 bytes"),
        pytest.param(100, id="100 bytes"),
        pytest.param(10 * 1024, id="10KiB"),
        pytest.param(1024 * 1024, id="1MiB"),
    ],
)
@pytest.mark.parametrize(
    "fixed_src_dst",
    [
        True,
        False,
    ],
)
@pytest.mark.parametrize(
    "non_zero_data",
    [
        True,
        False,
    ],
)
def test_worst_calldatacopy(
    benchmark_test: BenchmarkTestFiller,
    pre: Alloc,
    fork: Fork,
    origin: CallDataOrigin,
    size: int,
    fixed_src_dst: bool,
    non_zero_data: bool,
    gas_benchmark_value: int,
) -> None:
    """Test running a block filled with CALLDATACOPY executions."""
    if size == 0 and non_zero_data:
        pytest.skip("Non-zero data with size 0 is not applicable.")

    # If `non_zero_data` is True, we fill the calldata with deterministic
    # random data. Note that if `size == 0` and `non_zero_data` is a skipped
    # case.
    data = Bytes([i % 256 for i in range(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 > gas_benchmark_value:
        pytest.skip("Minimum gas required for calldata ({min_gas}) is greater than the 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 size == 0 else Op.PUSH3(size)
    src_dst = 0 if fixed_src_dst else Op.MOD(Op.GAS, 7)
    attack_block = Op.CALLDATACOPY(
        src_dst, src_dst, Op.CALLDATASIZE if non_zero_data or size == 0 else Op.DUP1
    )

    code_address = JumpLoopGenerator(setup=setup, attack_block=attack_block).deploy_contracts(
        pre=pre, fork=fork
    )

    tx_target = code_address

    # If the origin is CALL, we need to create a contract that will call the
    # target contract with the calldata.
    if origin == CallDataOrigin.CALL:
        # If `non_zero_data` is False we leverage just using zeroed memory.
        # Otherwise, we copy the calldata received from the transaction.
        setup = (
            Op.CALLDATACOPY(Op.PUSH0, Op.PUSH0, Op.CALLDATASIZE) if non_zero_data else Bytecode()
        ) + Op.JUMPDEST
        arg_size = Op.CALLDATASIZE if non_zero_data else size
        attack_block = Op.STATICCALL(
            address=code_address, args_offset=Op.PUSH0, args_size=arg_size
        )

        tx_target = JumpLoopGenerator(setup=setup, attack_block=attack_block).deploy_contracts(
            pre=pre, fork=fork
        )

    tx = Transaction(
        to=tx_target,
        gas_limit=gas_benchmark_value,
        data=data,
        sender=pre.fund_eoa(),
    )

    benchmark_test(tx=tx)

Parametrized Test Cases

This test case is only parametrized by fork.

Test ID (Abbreviated) non_zero_data fixed_src_dst size origin
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-0 bytes-transaction True True 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-0 bytes-call True True 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-100 bytes-transaction True True 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-100 bytes-call True True 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-10KiB-transaction True True 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-10KiB-call True True 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-1MiB-transaction True True 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_True-1MiB-call True True 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-0 bytes-transaction True False 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-0 bytes-call True False 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-100 bytes-transaction True False 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-100 bytes-call True False 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-10KiB-transaction True False 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-10KiB-call True False 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-1MiB-transaction True False 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_True-fixed_src_dst_False-1MiB-call True False 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-0 bytes-transaction False True 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-0 bytes-call False True 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-100 bytes-transaction False True 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-100 bytes-call False True 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-10KiB-transaction False True 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-10KiB-call False True 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-1MiB-transaction False True 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_True-1MiB-call False True 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-0 bytes-transaction False False 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-0 bytes-call False False 0 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-100 bytes-transaction False False 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-100 bytes-call False False 100 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-10KiB-transaction False False 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-10KiB-call False False 10240 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-1MiB-transaction False False 1048576 auto(_auto_null)
...fork_Prague-blockchain_test-non_zero_data_False-fixed_src_dst_False-1MiB-call False False 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-0 bytes-transaction True True 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-0 bytes-call True True 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-100 bytes-transaction True True 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-100 bytes-call True True 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-10KiB-transaction True True 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-10KiB-call True True 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-1MiB-transaction True True 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_True-1MiB-call True True 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-0 bytes-transaction True False 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-0 bytes-call True False 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-100 bytes-transaction True False 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-100 bytes-call True False 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-10KiB-transaction True False 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-10KiB-call True False 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-1MiB-transaction True False 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_True-fixed_src_dst_False-1MiB-call True False 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-0 bytes-transaction False True 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-0 bytes-call False True 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-100 bytes-transaction False True 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-100 bytes-call False True 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-10KiB-transaction False True 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-10KiB-call False True 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-1MiB-transaction False True 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_True-1MiB-call False True 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-0 bytes-transaction False False 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-0 bytes-call False False 0 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-100 bytes-transaction False False 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-100 bytes-call False False 100 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-10KiB-transaction False False 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-10KiB-call False False 10240 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-1MiB-transaction False False 1048576 auto(_auto_null)
...fork_Osaka-blockchain_test-non_zero_data_False-fixed_src_dst_False-1MiB-call False False 1048576 auto(_auto_null)