Skip to content

test_delete_around_inline_leaves()

Documentation for tests/mpt/test_storage_trie_structure.py::test_delete_around_inline_leaves@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/mpt/test_storage_trie_structure.py::test_delete_around_inline_leaves --fork Bogota

Delete next to inline leaves; re-insert in the next block.

ext(4) -> branch@4 -> {c, ext(3) -> branch@8 -> {a, b}}

a, b = leaf(55), 31 B with a 1-byte value, 33 B with 2 bytes

post: block 1: deleting a or b collapses branch@8 and the survivor becomes leaf(59), 2 B larger; deleting c leaves ext(8) -> branch@8 -> {a, b}; block 2: the pre shape Two more bytes move a 31 B leaf past the hash threshold.

Source code in tests/mpt/test_storage_trie_structure.py
@pytest.mark.parametrize(
    "values,doomed,survivor_sizes",
    [
        pytest.param(
            {0: 1, 1: 1, 2: 1}, 1, (31, 33), id="deleted_inline_survivor_flips"
        ),
        pytest.param(
            {0: 1, 1: 128, 2: 1},
            0,
            (33, 35),
            id="deleted_inline_survivor_hashed",
        ),
        pytest.param(
            {0: 128, 1: 1, 2: 1},
            0,
            (31, 33),
            id="deleted_hashed_survivor_flips",
        ),
        pytest.param(
            {0: 1, 1: 1, 2: 1},
            2,
            (31, 31),
            id="deleted_hashed_siblings_inline",
        ),
    ],
)
def test_delete_around_inline_leaves(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    values: Dict[int, int],
    doomed: int,
    survivor_sizes: Tuple[int, int],
) -> None:
    """
    Delete next to inline leaves; re-insert in the next block.

    pre:  ext(4) -> branch@4 -> {c, ext(3) -> branch@8 -> {a, b}}
          a, b = leaf(55), 31 B with a 1-byte value, 33 B with 2 bytes
    post: block 1: deleting a or b collapses branch@8 and the survivor
          becomes leaf(59), 2 B larger; deleting c leaves
          ext(8) -> branch@8 -> {a, b}; block 2: the pre shape
    Two more bytes move a 31 B leaf past the hash threshold.
    """
    trio = (*EMBEDDED_LEAF_PAIR, EMBEDDED_LEAF_PAIR_SIBLING_DEPTH4)
    storage: StorageRootType = {trio[i]: v for i, v in values.items()}
    doomed_slot = trio[doomed]
    survivor = trio[0] if doomed else trio[1]
    before, after = survivor_sizes
    assert storage_shape(trio, survivor)[-1] == (9, "leaf", 55)
    assert storage_leaf_size(55, values[trio.index(survivor)]) == before
    remaining = [s for s in trio if s != doomed_slot]
    depth, kind, rest = storage_shape(remaining, survivor)[-1]
    assert storage_leaf_size(rest, values[trio.index(survivor)]) == after
    if doomed == 2:
        assert storage_shape(remaining, survivor)[0] == (0, "ext", 8)
    else:
        assert storage_shape(remaining, survivor)[-1] == (5, "leaf", 59)
    contract = pre.deploy_contract(code=SLOT_WRITER, storage=storage)
    sender = pre.fund_eoa()
    without = {s: v for s, v in storage.items() if s != doomed_slot}

    blockchain_test(
        pre=pre,
        post={contract: Account(storage=storage)},
        blocks=[
            Block(
                txs=[_write(sender, contract, doomed_slot, 0)],
                expected_post_state={contract: Account(storage=without)},
            ),
            Block(txs=[_write(sender, contract, doomed_slot, values[doomed])]),
        ],
    )

Parametrized Test Cases

This test generates 4 parametrized test cases across 3 forks.