Skip to content

test_bal_invalid_noop_storage_change()

Documentation for tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py::test_bal_invalid_noop_storage_change@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py::test_bal_invalid_noop_storage_change --fork Amsterdam

Test that clients reject a BAL storage change whose post-value equals the value already present at the start of the transaction.

Oracle performs a round-trip write: SSTORE(0, 0x42) with slot 0 already at 0x42. The canonical BAL demotes such a no-op write to a storage_reads entry. The BAL is corrupted into exactly the shape a builder without no-op demotion would emit: the raw write recorded as a storage_changes entry (post_value == pre-tx value) and the read dropped.

Source code in tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
@pytest.mark.valid_from("Amsterdam")
@pytest.mark.exception_test
def test_bal_invalid_noop_storage_change(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
) -> None:
    """
    Test that clients reject a BAL storage change whose post-value equals
    the value already present at the start of the transaction.

    Oracle performs a round-trip write: SSTORE(0, 0x42) with slot 0
    already at 0x42. The canonical BAL demotes such a no-op write to a
    storage_reads entry. The BAL is corrupted into exactly the shape a
    builder without no-op demotion would emit: the raw write recorded as
    a storage_changes entry (post_value == pre-tx value) and the read
    dropped.
    """
    alice = pre.fund_eoa()
    oracle = pre.deploy_contract(code=Op.SSTORE(0, 0x42), storage={0: 0x42})

    tx = Transaction(sender=alice, to=oracle, gas_limit=1_000_000)

    blockchain_test(
        pre=pre,
        # The block reverts and the post state remains unchanged.
        post=pre,
        blocks=[
            Block(
                txs=[tx],
                exception=BlockException.INVALID_BLOCK_ACCESS_LIST,
                expected_block_access_list=BlockAccessListExpectation(
                    account_expectations={
                        alice: BalAccountExpectation(
                            nonce_changes=[
                                BalNonceChange(
                                    block_access_index=1, post_nonce=1
                                )
                            ],
                        ),
                        oracle: BalAccountExpectation(
                            storage_reads=[0],
                        ),
                    }
                ).modify(
                    remove_storage_reads(oracle),
                    append_storage(
                        address=oracle,
                        slot=0,
                        change=BalStorageChange(
                            block_access_index=1, post_value=0x42
                        ),
                    ),
                ),
            )
        ],
    )

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.