Skip to content

test_tstore_key_distribution()

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

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
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
@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.