Benchmark TSTORE against a growing transient store.
GAS gives a unique key per write with no memory counter, and COINBASE a
nonzero value, so every write inserts an entry instead of being elided.
Source code in tests/benchmark/compute/instruction/test_storage.py
| @pytest.mark.repricing(fixed_key=False, tload="none")
@pytest.mark.parametrize("fixed_key", [True, False])
@pytest.mark.parametrize("tload", ["none", "hit", "miss"])
def test_tstore(
benchmark_test: BenchmarkTestFiller,
fixed_key: bool,
tload: str,
) -> None:
"""
Benchmark TSTORE against a growing transient store.
GAS gives a unique key per write with no memory counter, and COINBASE a
nonzero value, so every write inserts an entry instead of being elided.
"""
assert Environment().fee_recipient != Address(0), (
"coinbase must be nonzero so the TSTORE value is nonzero"
)
key = Op.PUSH0 if fixed_key else Op.GAS
setup = Bytecode()
value = Op.COINBASE
match tload:
case "hit":
# Seed the value and feed each read into the next TSTORE so
# the TLOAD is not discarded. Stack carries [value].
setup = Op.COINBASE
attack_block = key + Op.SWAP1 + Op.DUP2 + Op.TSTORE + Op.TLOAD
case "miss":
# Read a fresh, never-written key: a miss on a growing store.
attack_block = Op.TSTORE(key, value) + Op.POP(Op.TLOAD(Op.GAS))
case "none":
attack_block = Op.TSTORE(key, value)
case _:
raise ValueError(f"Unknown tload mode: {tload}")
benchmark_test(
target_opcode=Op.TSTORE,
code_generator=JumpLoopGenerator(
setup=setup,
attack_block=attack_block,
),
)
|