Skip to content

test_block_full_access_list_and_data()

Documentation for tests/benchmark/test_worst_blocks.py::test_block_full_access_list_and_data@88e9fb8f.

Generate fixtures for these test cases for Osaka with:

fill -v tests/benchmark/test_worst_blocks.py::test_block_full_access_list_and_data -m benchmark

Test a block with access lists (60% gas) and calldata (40% gas) using random mixed bytes.

Source code in tests/benchmark/test_worst_blocks.py
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
def test_block_full_access_list_and_data(
    benchmark_test: BenchmarkTestFiller,
    pre: Alloc,
    intrinsic_cost: int,
    total_cost_standard_per_token: int,
    fork: Fork,
    gas_benchmark_value: int,
    tx_gas_limit_cap: int,
) -> None:
    """
    Test a block with access lists (60% gas) and calldata (40% gas) using
    random mixed bytes.
    """
    iteration_count = math.ceil(gas_benchmark_value / tx_gas_limit_cap)

    gas_remaining = gas_benchmark_value
    total_gas_used = 0

    txs = []
    for _ in range(iteration_count):
        gas_available = min(tx_gas_limit_cap, gas_remaining) - intrinsic_cost

        # Split available gas: 60% for access lists, 40% for calldata
        gas_for_access_list = int(gas_available * 0.6)
        gas_for_calldata = int(gas_available * 0.4)

        # Access list gas costs from fork's gas_costs
        gas_costs = fork.gas_costs()
        gas_per_address = gas_costs.G_ACCESS_LIST_ADDRESS
        gas_per_storage_key = gas_costs.G_ACCESS_LIST_STORAGE

        # Calculate number of storage keys we can fit
        gas_after_address = gas_for_access_list - gas_per_address
        num_storage_keys = gas_after_address // gas_per_storage_key

        # Create access list with 1 address and many storage keys
        access_address = Address("0x1234567890123456789012345678901234567890")
        storage_keys = []
        for i in range(num_storage_keys):
            # Generate random-looking storage keys
            storage_keys.append(Hash(i))

        access_list = [
            AccessList(
                address=access_address,
                storage_keys=storage_keys,
            )
        ]

        # Calculate calldata with 29% of gas for zero bytes and 71% for
        # non-zero bytes
        # Token accounting: tokens_in_calldata = zero_bytes + 4 *
        # non_zero_bytes
        # We want to split the gas budget:
        # - 29% of gas_for_calldata for zero bytes
        # - 71% of gas_for_calldata for non-zero bytes

        max_tokens_in_calldata = gas_for_calldata // total_cost_standard_per_token

        # Calculate how many tokens to allocate to each type
        tokens_for_zero_bytes = int(max_tokens_in_calldata * 0.29)
        tokens_for_non_zero_bytes = max_tokens_in_calldata - tokens_for_zero_bytes

        # Convert tokens to actual byte counts
        # Zero bytes: 1 token per byte
        # Non-zero bytes: 4 tokens per byte
        num_zero_bytes = tokens_for_zero_bytes  # 1 token = 1 zero byte
        num_non_zero_bytes = tokens_for_non_zero_bytes // 4  # 4 tokens = 1 non-zero byte

        # Create calldata with mixed bytes
        calldata = bytearray()

        # Add zero bytes
        calldata.extend(b"\x00" * num_zero_bytes)

        # Add non-zero bytes (random values from 0x01 to 0xff)
        rng = random.Random(42)  # For reproducibility
        for _ in range(num_non_zero_bytes):
            calldata.append(rng.randint(1, 255))

        # Shuffle the bytes to mix zero and non-zero bytes
        calldata_list = list(calldata)
        rng.shuffle(calldata_list)
        shuffled_calldata = bytes(calldata_list)

        txs.append(
            Transaction(
                to=pre.fund_eoa(amount=0),
                data=shuffled_calldata,
                gas_limit=gas_available + intrinsic_cost,
                sender=pre.fund_eoa(),
                access_list=access_list,
            )
        )

        gas_remaining -= gas_for_access_list + intrinsic_cost
        total_gas_used += fork.transaction_intrinsic_cost_calculator()(
            calldata=shuffled_calldata,
            access_list=access_list,
        )

    benchmark_test(
        blocks=[Block(txs=txs)],
        expected_benchmark_gas_used=total_gas_used,
    )

Parametrized Test Cases

This test case is only parametrized by fork.

Test ID (Abbreviated)
...fork_Prague-blockchain_test
...fork_Osaka-blockchain_test