test_block_full_access_list_and_data()
Documentation for tests/benchmark/compute/scenario/test_transaction_types.py::test_block_full_access_list_and_data@892e6d1e.
Generate fixtures for these test cases for Amsterdam with:
fill -v tests/benchmark/compute/scenario/test_transaction_types.py::test_block_full_access_list_and_data --gas-benchmark-values 1
Test a block with access lists (60% gas) and calldata (40% gas) using
random mixed bytes.
Source code in tests/benchmark/compute/scenario/test_transaction_types.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 | 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: int,
) -> None:
"""
Test a block with access lists (60% gas) and calldata (40% gas) using
random mixed bytes.
"""
# Skip if EIP-7934 block RLP size limit would be exceeded
block_rlp_limit = fork.block_rlp_size_limit()
if block_rlp_limit:
pytest.skip(
"Test skipped: EIP-7934 block RLP size limit might be exceeded"
)
iteration_count = math.ceil(gas_benchmark_value / tx_gas_limit)
gas_remaining = gas_benchmark_value
total_gas_used = 0
txs = []
for _ in range(iteration_count):
gas_available = min(tx_gas_limit, 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.TX_ACCESS_LIST_ADDRESS
gas_per_storage_key = gas_costs.TX_ACCESS_LIST_STORAGE_KEY
# 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 generates 1 parametrized test case across 3 forks.