Skip to content

test_tstore_key_distribution()

Documentation for tests/benchmark/compute/instruction/test_storage.py::test_tstore_key_distribution@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/benchmark/compute/instruction/test_storage.py::test_tstore_key_distribution --gas-benchmark-values 1

Benchmark TSTORE with colliding versus spread transient-storage keys.

The besu_collision arm writes distinct slots that share one Arrays.hashCode, so a client keying transient storage by a plain hash of the slot funnels every write into a single bucket; the spread arm writes sequential slots. The value is a fixed nonzero so the write is not elided. besu keys this way; other clients are unaffected.

Source code in tests/benchmark/compute/instruction/test_storage.py
@pytest.mark.parametrize("distribution", ["spread", "besu_collision"])
def test_tstore_key_distribution(
    benchmark_test: BenchmarkTestFiller,
    fork: Fork,
    distribution: str,
) -> None:
    """
    Benchmark TSTORE with colliding versus spread transient-storage keys.

    The ``besu_collision`` arm writes distinct slots that share one
    ``Arrays.hashCode``, so a client keying transient storage by a plain hash
    of the slot funnels every write into a single bucket; the ``spread`` arm
    writes sequential slots. The value is a fixed nonzero so the write is not
    elided. besu keys this way; other clients are unaffected.
    """
    value = 0x2A
    max_write_bytes = len(Op.TSTORE(Op.PUSH32(0), value))
    loop_overhead = len(Op.JUMPDEST) + len(Op.JUMP(0))
    n = (fork.max_code_size() - loop_overhead) // max_write_bytes

    if distribution == "spread":
        slots = list(range(1, n + 1))
    elif distribution == "besu_collision":
        slots = _besu_colliding_slots(n)
    else:
        raise ValueError(f"unknown distribution: {distribution}")

    attack_block = sum((Op.TSTORE(slot, value) for slot in slots), Bytecode())
    benchmark_test(
        target_opcode=Op.TSTORE,
        code_generator=JumpLoopGenerator(attack_block=attack_block),
    )

Parametrized Test Cases

This test generates 2 parametrized test cases across 4 forks.