Skip to content

test_bal_many_storage_writes_single_account()

Documentation for tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py::test_bal_many_storage_writes_single_account@87aba1a3.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py::test_bal_many_storage_writes_single_account --fork Amsterdam

Verify the BAL records many distinct storage changes for a single account written by a single transaction.

One transaction calls a contract that writes num_slots distinct, previously-zero slots (slot[i] = i + 1 for i in 0..num_slots). The account's storage_changes in the BAL must list every slot, in ascending slot order, each at block_access_index=1.

Existing BAL storage tests touch at most a handful of slots per account (e.g. test_bal_cross_tx_storage_chain writes 8 slots, one per transaction). This exercises a much higher per-account, per-transaction storage-change cardinality, which stresses any client that records or preloads an account's BAL storage keys into a fixed-size buffer.

Source code in tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
@pytest.mark.parametrize(
    "num_slots",
    [
        pytest.param(17, id="17_slots"),
        pytest.param(32, id="32_slots"),
        pytest.param(128, id="128_slots"),
    ],
)
def test_bal_many_storage_writes_single_account(
    pre: Alloc,
    blockchain_test: BlockchainTestFiller,
    fork: Fork,
    num_slots: int,
) -> None:
    """
    Verify the BAL records many distinct storage changes for a single
    account written by a single transaction.

    One transaction calls a contract that writes `num_slots` distinct,
    previously-zero slots (`slot[i] = i + 1` for `i` in `0..num_slots`).
    The account's `storage_changes` in the BAL must list every slot, in
    ascending slot order, each at `block_access_index=1`.

    Existing BAL storage tests touch at most a handful of slots per
    account (e.g. `test_bal_cross_tx_storage_chain` writes 8 slots, one
    per transaction). This exercises a much higher per-account,
    per-transaction storage-change cardinality, which stresses any client
    that records or preloads an account's BAL storage keys into a
    fixed-size buffer.
    """
    contract_code = Op.SSTORE(0, 1)
    for i in range(1, num_slots):
        contract_code += Op.SSTORE(i, i + 1)
    contract_code += Op.STOP
    contract = pre.deploy_contract(code=contract_code)

    alice = pre.fund_eoa()
    tx = Transaction(
        sender=alice,
        to=contract,
        gas_limit=fork.transaction_gas_limit_cap(),
    )

    account_expectations = {
        alice: BalAccountExpectation(
            nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)],
        ),
        contract: BalAccountExpectation(
            storage_changes=[
                BalStorageSlot(
                    slot=i,
                    slot_changes=[
                        BalStorageChange(
                            block_access_index=1, post_value=i + 1
                        )
                    ],
                )
                for i in range(num_slots)
            ],
            storage_reads=[],
        ),
    }

    blockchain_test(
        pre=pre,
        blocks=[
            Block(
                txs=[tx],
                expected_block_access_list=BlockAccessListExpectation(
                    account_expectations=account_expectations
                ),
            )
        ],
        post={
            contract: Account(storage={i: i + 1 for i in range(num_slots)}),
        },
    )

Parametrized Test Cases

This test generates 3 parametrized test cases across 1 fork.