Skip to content

Commit 7ea7b98

Browse files
feat: add eoa delegation target
1 parent 128a008 commit 7ea7b98

3 files changed

Lines changed: 146 additions & 66 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""Deterministic benchmark sender and receiver accounts."""
2+
3+
import itertools
4+
from typing import Generator
5+
6+
from execution_testing import (
7+
DETERMINISTIC_FACTORY_ADDRESS,
8+
EOA,
9+
Address,
10+
compute_create2_address,
11+
compute_create_address,
12+
keccak256,
13+
)
14+
15+
# Deterministic sender pool, pre-funded via system-contract withdrawals
16+
# (funding.txt) during payload generation. Kept out of the pre-allocation so
17+
# the accounts stay uncached.
18+
SENDER_BASE_KEY = int.from_bytes(
19+
keccak256(b"gas-repricings-private-key"), "big"
20+
)
21+
22+
# Deterministic EIP-7702 delegate authorities:
23+
# Authority i delegates to EXISTING_CONTRACT_DIFF receiver i.
24+
DELEGATE_BASE_KEY = int.from_bytes(
25+
keccak256(b"gas-repricings-7702-delegate"), "big"
26+
)
27+
28+
# Bittrex controller mainnet address: it created 1.5M contracts via CREATE with
29+
# deterministic addresses, none self-destructed. Used as existing-contract
30+
# receivers.
31+
BITTREX_CONTROLLER_ADDRESS = Address(
32+
0xA3C1E324CA1CE40DB73ED6026C4A177F099B5770
33+
)
34+
35+
36+
def yield_distinct_sender() -> Generator[EOA, None, None]:
37+
"""Yield deterministic sender EOAs pre-funded on-chain."""
38+
for i in itertools.count(0):
39+
yield EOA(key=SENDER_BASE_KEY + i)
40+
41+
42+
def yield_distinct_create2_receiver(
43+
initcode: bytes,
44+
) -> Generator[Address, None, None]:
45+
"""Yield addresses deployed by the deterministic CREATE2 factory."""
46+
for salt in itertools.count(0):
47+
yield compute_create2_address(
48+
address=DETERMINISTIC_FACTORY_ADDRESS,
49+
salt=salt,
50+
initcode=initcode,
51+
)
52+
53+
54+
def yield_distinct_contract_receiver() -> Generator[Address, None, None]:
55+
"""Yield contracts created by the Bittrex controller via CREATE."""
56+
for nonce in itertools.count(2):
57+
yield compute_create_address(
58+
address=BITTREX_CONTROLLER_ADDRESS, nonce=nonce
59+
)
60+
61+
62+
def yield_distinct_existent_receiver() -> Generator[Address, None, None]:
63+
"""
64+
Yield existing balance-only EOAs on bloatnet, pre-funded by Spamoor
65+
(https://github.com/CPerezz/spamoor/pull/12).
66+
"""
67+
for address in itertools.count(0x1000):
68+
yield Address(address)
69+
70+
71+
def yield_distinct_nonexistent_receiver() -> Generator[Address, None, None]:
72+
"""Yield non-existent accounts starting from keccak256('random')."""
73+
for address in itertools.count(0xF3CF193BB4AF1022AF7D2089F37D8BAE7157B85F):
74+
yield Address(address)
75+
76+
77+
def yield_distinct_delegate_receiver() -> Generator[Address, None, None]:
78+
"""Yield EOA that delegates to distinct EXISTING_CONTRACT_DIFF receiver."""
79+
for i in itertools.count(0):
80+
yield EOA(key=DELEGATE_BASE_KEY + i)

tests/benchmark/stateful/bloatnet/test_setup_contracts.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,29 @@
22

33
from execution_testing import (
44
DETERMINISTIC_FACTORY_ADDRESS,
5+
EOA,
6+
Account,
57
Alloc,
8+
AuthorizationTuple,
69
BenchmarkTestFiller,
710
Fork,
811
Hash,
912
Op,
1013
Transaction,
14+
compute_create2_address,
1115
)
1216

1317
from tests.benchmark.helper.account_creator import (
1418
AccountCreator,
1519
AccountMode,
1620
)
21+
from tests.benchmark.helper.account_sender_receiver import (
22+
DELEGATE_BASE_KEY,
23+
)
1724
from tests.benchmark.stateful.helpers import (
1825
pack_transactions_into_blocks,
1926
)
27+
from tests.prague.eip7702_set_code_tx.spec import Spec as Spec7702
2028

2129
RECEIVER_CONTRACT_COUNT = 120_000
2230

@@ -58,12 +66,16 @@ def test_deploy_existing_contracts(
5866
pre: Alloc,
5967
fork: Fork,
6068
gas_benchmark_value: int,
69+
tx_gas_limit: int,
6170
) -> None:
6271
"""
6372
Deploy the contracts behind the `AccountMode.EXISTING_CONTRACT_*`
6473
receivers via the deterministic CREATE2 factory.
74+
75+
Delegate deterministic EOAs to EXISTING_CONTRACT_DIFF receivers.
6576
"""
6677
txs = []
78+
post: dict = {}
6779
for account_mode in CONTRACT_MODES:
6880
creator = AccountCreator(account_mode)
6981
initcode = creator.initcode
@@ -79,10 +91,52 @@ def test_deploy_existing_contracts(
7991
)
8092
)
8193

82-
blocks = pack_transactions_into_blocks(txs, gas_benchmark_value)
94+
# Delegate authority i to the i-th DIFF receiver (EIP-7702).
95+
delegation_sender = pre.fund_eoa()
96+
intrinsic = fork.transaction_intrinsic_cost_calculator()
97+
# DIFF receivers share one initcode; build it once for CREATE2 derivation.
98+
diff_initcode = AccountCreator(AccountMode.EXISTING_CONTRACT_DIFF).initcode
99+
100+
base_gas = intrinsic(authorization_list_or_count=0)
101+
per_auth_gas = intrinsic(authorization_list_or_count=1) - base_gas
102+
gas_buffer = 100_000
103+
auths_per_tx = max(
104+
1, (tx_gas_limit - gas_buffer - base_gas) // per_auth_gas
105+
)
106+
107+
for start in range(0, RECEIVER_CONTRACT_COUNT, auths_per_tx):
108+
count = min(auths_per_tx, RECEIVER_CONTRACT_COUNT - start)
109+
authorization_list = []
110+
for i in range(start, start + count):
111+
authority = EOA(key=DELEGATE_BASE_KEY + i)
112+
target = compute_create2_address(
113+
address=DETERMINISTIC_FACTORY_ADDRESS,
114+
salt=i,
115+
initcode=diff_initcode,
116+
)
117+
authorization_list.append(
118+
AuthorizationTuple(address=target, nonce=0, signer=authority)
119+
)
120+
if i == 0 or i == RECEIVER_CONTRACT_COUNT - 1:
121+
post[authority] = Account(
122+
nonce=1,
123+
code=Spec7702.delegation_designation(target),
124+
)
125+
126+
txs.append(
127+
Transaction(
128+
to=delegation_sender,
129+
gas_limit=(
130+
intrinsic(authorization_list_or_count=count) + gas_buffer
131+
),
132+
sender=delegation_sender,
133+
authorization_list=authorization_list,
134+
)
135+
)
83136

84137
benchmark_test(
85-
blocks=blocks,
138+
post=post,
139+
blocks=pack_transactions_into_blocks(txs, gas_benchmark_value),
86140
skip_gas_used_validation=True,
87141
expected_receipt_status=1,
88142
)

tests/benchmark/stateful/bloatnet/test_transaction_types.py

Lines changed: 10 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,32 @@
11
"""Benchmark ether transfers to receivers that exist on-chain."""
22

3-
import itertools
43
from typing import Generator
54

65
import pytest
76
from execution_testing import (
8-
DETERMINISTIC_FACTORY_ADDRESS,
9-
EOA,
107
Address,
118
Alloc,
129
BenchmarkTestFiller,
1310
Block,
1411
Fork,
1512
Op,
1613
Transaction,
17-
compute_create2_address,
18-
compute_create_address,
19-
keccak256,
2014
)
2115

2216
from tests.benchmark.helper.account_creator import (
2317
AccountCreator,
2418
AccountMode,
2519
)
26-
27-
# Deterministic sender pool of 15K accounts.
28-
# Funded via system contract withdrawals (funding.txt) in payload generation.
29-
# Placed outside pre-allocation to ensure accounts remain uncached.
30-
SENDER_BASE_KEY = int.from_bytes(
31-
keccak256(b"gas-repricings-private-key"), "big"
32-
)
33-
34-
35-
def yield_distinct_sender() -> Generator[EOA, None, None]:
36-
"""Yield deterministic sender EOAs pre-funded on-chain."""
37-
for i in itertools.count(0):
38-
yield EOA(key=SENDER_BASE_KEY + i)
39-
40-
41-
def yield_distinct_create2_receiver(
42-
initcode: bytes,
43-
) -> Generator[Address, None, None]:
44-
"""
45-
Yield contract addresses deployed by the deterministic CREATE2 factory.
46-
"""
47-
for salt in itertools.count(0):
48-
yield compute_create2_address(
49-
address=DETERMINISTIC_FACTORY_ADDRESS,
50-
salt=salt,
51-
initcode=initcode,
52-
)
53-
54-
55-
# Bittrex controller mainnet address
56-
# Creates 1.5M contracts with deterministic address via CREATE
57-
# It is guaranteed no contract is destructed
58-
# Used for existing contract targets in benchmark
59-
BITTREX_CONTROLLER_ADDRESS = Address(
60-
0xA3C1E324CA1CE40DB73ED6026C4A177F099B5770
20+
from tests.benchmark.helper.account_sender_receiver import (
21+
yield_distinct_contract_receiver,
22+
yield_distinct_create2_receiver,
23+
yield_distinct_delegate_receiver,
24+
yield_distinct_existent_receiver,
25+
yield_distinct_nonexistent_receiver,
26+
yield_distinct_sender,
6127
)
6228

6329

64-
def yield_distinct_contract_receiver() -> Generator[Address, None, None]:
65-
"""Yield contract account created by Bittrex controller via CREATE."""
66-
for nonce in itertools.count(2):
67-
yield compute_create_address(
68-
address=BITTREX_CONTROLLER_ADDRESS, nonce=nonce
69-
)
70-
71-
72-
def yield_distinct_existent_receiver() -> Generator[Address, None, None]:
73-
"""
74-
Yield existing balance-only EOA on bloatnet. pre-funded by Spamoor
75-
(https://github.com/CPerezz/spamoor/pull/12).
76-
"""
77-
for address in itertools.count(0x1000):
78-
yield Address(address)
79-
80-
81-
def yield_distinct_nonexistent_receiver() -> Generator[Address, None, None]:
82-
"""Yield non-existent accounts starting from keccak256('random')."""
83-
for address in itertools.count(0xF3CF193BB4AF1022AF7D2089F37D8BAE7157B85F):
84-
yield Address(address)
85-
86-
8730
@pytest.mark.repricing
8831
@pytest.mark.parametrize(
8932
"case_id",
@@ -96,6 +39,7 @@ def yield_distinct_nonexistent_receiver() -> Generator[Address, None, None]:
9639
"diff_to_contract_minimal",
9740
"diff_to_contract_same",
9841
"diff_to_contract_diff",
42+
"diff_to_delegated_contract_diff",
9943
],
10044
)
10145
@pytest.mark.parametrize("transfer_amount", [0, 1])
@@ -146,6 +90,8 @@ def test_ether_transfers_onchain_receivers(
14690
receivers = yield_distinct_create2_receiver(
14791
AccountCreator(AccountMode.EXISTING_CONTRACT_DIFF).initcode
14892
)
93+
case "diff_to_delegated_contract_diff":
94+
receivers = yield_distinct_delegate_receiver()
14995
case _:
15096
raise ValueError(f"Unknown case: {case_id}")
15197

0 commit comments

Comments
 (0)