Skip to content
182 changes: 182 additions & 0 deletions tests/benchmark/stateful/bloatnet/test_transaction_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
"""Benchmark ether transfers to receivers that exist on-chain."""

import itertools
from typing import Generator

import pytest
from execution_testing import (
EOA,
Address,
Alloc,
BenchmarkTestFiller,
Block,
Fork,
Transaction,
compute_create2_address,
compute_create_address,
)

# Deterministic sender pool: keys start at 0x111...111 (32 bytes) and
# increment by 1. Accounts are assumed to be pre-funded on bloatnet
# (e.g. by Spamoor), so they are intentionally NOT added to the pre-alloc.
SENDER_BASE_KEY = (
0x1111111111111111111111111111111111111111111111111111111111111111
)


def yield_distinct_sender() -> Generator[EOA, None, None]:
"""Yield deterministic sender EOAs pre-funded on-chain."""
for i in itertools.count(0):
yield EOA(key=SENDER_BASE_KEY + i)


# Bittrex controller mainnet address
# Creates 1.5M contracts with deterministic address via CREATE
# It is guaranteed no contract is destructed
# Used for existing contract targets in benchmark
BITTREX_CONTROLLER_ADDRESS = Address(
0xA3C1E324CA1CE40DB73ED6026C4A177F099B5770
)


# Ether reception cost for Bittrex-created contracts
RECEIVER_CONTRACT_EXECUTION_GAS = 51


# Arachnid's deterministic deployment proxy. Assumed to have already
# deployed the unique-code contracts via CREATE2 with salts 0, 1, 2, ...
DETERMINISTIC_FACTORY_ADDRESS = Address(
0x4E59B44847B379578588920CA78FBF26C0B4956C
)


# Initcode deployed by DETERMINISTIC_FACTORY_ADDRESS for each
# diff_to_unique_code_jumpdest_contract receiver. Returns a 24,576-byte
# runtime whose entry is PUSH2 0x5fff; JUMP, landing on a JUMPDEST near
# the end of code (then implicit STOP). Each contract embeds its own
# address in code, so the deployed code is unique per address while
# initcode (and therefore the CREATE2 hash input) is shared.
UNIQUE_CODE_JUMPDEST_INITCODE = bytes.fromhex(
"7f5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b6000"
"526020600060205e6040600060405e6080600060805e61010060006101005e61020060"
"006102005e61040060006104005e61080060006108005e61100060006110005e612000"
"60006120005e61400060006140005e7f615fff565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b"
"5b5b5b5b5b5b5b5b5b5b5b5b5b6000527f5b5b5b5b5b5b5b5b5b5b5b5b000000000000"
"000000000000000000000000000030176020526160006000f3"
)


# Runtime gas cost: PUSH2 (3) + JUMP (8) + JUMPDEST (1) = 12.
RECEIVER_JUMPDEST_EXECUTION_GAS = 3 + 8 + 1


def yield_distinct_contract_receiver() -> Generator[Address, None, None]:
"""Yield contract account created by Bittrex controller via CREATE."""
for nonce in itertools.count(2):
yield compute_create_address(
address=BITTREX_CONTROLLER_ADDRESS, nonce=nonce
)


def yield_distinct_unique_code_jumpdest_receiver() -> (
Generator[Address, None, None]
):
"""
Yield contract addresses deployed by the deterministic CREATE2 factory.

Each address corresponds to a contract with unique deployed code whose
runtime executes PUSH2 + JUMP + JUMPDEST (12 gas).
"""
for salt in itertools.count(0):
yield compute_create2_address(
address=DETERMINISTIC_FACTORY_ADDRESS,
salt=salt,
initcode=UNIQUE_CODE_JUMPDEST_INITCODE,
)


def yield_distinct_existent_receiver() -> Generator[Address, None, None]:
"""
Yield existing balance-only EOA on bloatnet. pre-funded by Spamoor
(https://github.com/CPerezz/spamoor/pull/12).
"""
for address in itertools.count(0x1000):
yield Address(address)


def yield_distinct_nonexistent_receiver() -> Generator[Address, None, None]:
"""Yield non-existent accounts starting from keccak256('random')."""
for address in itertools.count(0xF3CF193BB4AF1022AF7D2089F37D8BAE7157B85F):
yield Address(address)


@pytest.mark.repricing
@pytest.mark.parametrize(
"case_id",
[
"diff_to_nonexistent",
"diff_to_existent",
"diff_to_contract",
"diff_to_unique_code_jumpdest_contract",
],
)
@pytest.mark.parametrize("transfer_amount", [0, 1])
Comment thread
LouisTsai-Csie marked this conversation as resolved.
def test_ether_transfers_onchain_receivers(
benchmark_test: BenchmarkTestFiller,
pre: Alloc,
case_id: str,
transfer_amount: int,
fork: Fork,
gas_benchmark_value: int,
) -> None:
"""
Ether transfers to receivers that exist on-chain at run time.

Scenarios:
- diff_to_nonexistent: distinct nonexistent receivers
(matches AccountMode.NON_EXISTING_ACCOUNT)
- diff_to_existent: distinct existent EOA receivers
(matches AccountMode.EXISTING_EOA)
- diff_to_contract: distinct contract receivers
(matches AccountMode.EXISTING_CONTRACT)
- diff_to_unique_code_jumpdest_contract: distinct CREATE2 contract
receivers each holding unique deployed code; runtime executes
PUSH2 + JUMP + JUMPDEST.
"""
senders = yield_distinct_sender()
receiver_execution_gas = 0
if case_id == "diff_to_nonexistent":
receivers = yield_distinct_nonexistent_receiver()
elif case_id == "diff_to_existent":
receivers = yield_distinct_existent_receiver()
elif case_id == "diff_to_contract":
receivers = yield_distinct_contract_receiver()
receiver_execution_gas = RECEIVER_CONTRACT_EXECUTION_GAS
elif case_id == "diff_to_unique_code_jumpdest_contract":
receivers = yield_distinct_unique_code_jumpdest_receiver()
receiver_execution_gas = RECEIVER_JUMPDEST_EXECUTION_GAS
else:
raise ValueError(f"Unknown case: {case_id}")

iteration_cost = (
fork.transaction_intrinsic_cost_calculator()() + receiver_execution_gas
)
iteration_count = gas_benchmark_value // iteration_cost

txs = [
Transaction(
to=next(receivers),
value=transfer_amount,
gas_limit=iteration_cost,
sender=next(senders),
)
for _ in range(iteration_count)
]

benchmark_test(
pre=pre,
post={},
blocks=[Block(txs=txs)],
expected_benchmark_gas_used=iteration_count * iteration_cost,
expected_receipt_status=1,
)
Loading