Skip to content

Commit 0517b99

Browse files
LouisTsai-CsieCarsons-Eels
authored andcommitted
feat(zkevm): create pure ether transfer worst case (ethereum#1742)
* feat(zkevm): create pure ether transfer worst case * fix(tests): update iteration and transfer amount config * refactor: add iterator for the sender and receiver list * doc: update changelog * refactor(tests): simplify sender and receiver list generation * refactor(tests): streamline ether transfer case handling
1 parent 4181649 commit 0517b99

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Users can select any of the artifacts depending on their testing needs for their
7070
- ✨ EIP-7823, EIP-7883: Add test cases for ModExp precompile gas-cost updates and input limits on Osaka ([#1579](https://github.com/ethereum/execution-spec-tests/pull/1579), [#1729](https://github.com/ethereum/execution-spec-tests/pull/1729)).
7171
-[EIP-7825](https://eips.ethereum.org/EIPS/eip-7825): Add test cases for the transaction gas limit of 30M gas ([#1711](https://github.com/ethereum/execution-spec-tests/pull/1711)).
7272
-[EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): add test cases for `P256VERIFY` precompile to support secp256r1 curve [#1670](https://github.com/ethereum/execution-spec-tests/pull/1670).
73+
- ✨ Introduce blockchain tests for ZKEVM to cover the scenario of pure ether transfers [#1742](https://github.com/ethereum/execution-spec-tests/pull/1742).
7374

7475
## [v4.5.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0) - 2025-05-14
7576

tests/zkevm/test_worst_blocks.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
"""
2+
abstract: Tests zkEVMs worst-case block scenarios.
3+
Tests zkEVMs worst-case block scenarios.
4+
5+
Tests running worst-case block scenarios for zkEVMs.
6+
"""
7+
8+
import pytest
9+
10+
from ethereum_test_forks import Fork
11+
from ethereum_test_tools import (
12+
Account,
13+
Address,
14+
Alloc,
15+
Block,
16+
BlockchainTestFiller,
17+
Environment,
18+
Transaction,
19+
)
20+
21+
22+
@pytest.fixture
23+
def iteration_count(eth_transfer_cost: int):
24+
"""Calculate the number of iterations based on the gas limit and intrinsic cost."""
25+
return Environment().gas_limit // eth_transfer_cost
26+
27+
28+
@pytest.fixture
29+
def transfer_amount():
30+
"""Ether to transfer in each transaction."""
31+
return 1
32+
33+
34+
@pytest.fixture
35+
def eth_transfer_cost(fork: Fork):
36+
"""Transaction gas limit."""
37+
intrinsic_cost = fork.transaction_intrinsic_cost_calculator()
38+
return intrinsic_cost()
39+
40+
41+
def get_distinct_sender_list(pre: Alloc):
42+
"""Get a list of distinct sender accounts."""
43+
while True:
44+
yield pre.fund_eoa()
45+
46+
47+
def get_distinct_receiver_list(pre: Alloc):
48+
"""Get a list of distinct receiver accounts."""
49+
while True:
50+
yield pre.fund_eoa(0)
51+
52+
53+
def get_single_sender_list(pre: Alloc):
54+
"""Get a list of single sender accounts."""
55+
sender = pre.fund_eoa()
56+
while True:
57+
yield sender
58+
59+
60+
def get_single_receiver_list(pre: Alloc):
61+
"""Get a list of single receiver accounts."""
62+
receiver = pre.fund_eoa(0)
63+
while True:
64+
yield receiver
65+
66+
67+
@pytest.fixture
68+
def ether_transfer_case(
69+
case_id: str,
70+
pre: Alloc,
71+
):
72+
"""Generate the test parameters based on the case ID."""
73+
if case_id == "a_to_a":
74+
"""Sending to self."""
75+
senders = get_single_sender_list(pre)
76+
receivers = senders
77+
78+
elif case_id == "a_to_b":
79+
"""One sender → one receiver."""
80+
senders = get_single_sender_list(pre)
81+
receivers = get_single_receiver_list(pre)
82+
83+
elif case_id == "diff_acc_to_b":
84+
"""Multiple senders → one receiver."""
85+
senders = get_distinct_sender_list(pre)
86+
receivers = get_single_receiver_list(pre)
87+
88+
elif case_id == "a_to_diff_acc":
89+
"""One sender → multiple receivers."""
90+
senders = get_single_sender_list(pre)
91+
receivers = get_distinct_receiver_list(pre)
92+
93+
elif case_id == "diff_acc_to_diff_acc":
94+
"""Multiple senders → multiple receivers."""
95+
senders = get_distinct_sender_list(pre)
96+
receivers = get_distinct_receiver_list(pre)
97+
98+
else:
99+
raise ValueError(f"Unknown case: {case_id}")
100+
101+
return senders, receivers
102+
103+
104+
@pytest.mark.valid_from("Cancun")
105+
@pytest.mark.parametrize(
106+
"case_id",
107+
["a_to_a", "a_to_b", "diff_acc_to_b", "a_to_diff_acc", "diff_acc_to_diff_acc"],
108+
)
109+
def test_block_full_of_ether_transfers(
110+
blockchain_test: BlockchainTestFiller,
111+
pre: Alloc,
112+
case_id: str,
113+
ether_transfer_case,
114+
iteration_count: int,
115+
transfer_amount: int,
116+
eth_transfer_cost: int,
117+
):
118+
"""
119+
Single test for ether transfer scenarios.
120+
121+
Scenarios:
122+
- a_to_a: one sender → one sender
123+
- a_to_b: one sender → one receiver
124+
- diff_acc_to_b: multiple senders → one receiver
125+
- a_to_diff_acc: one sender → multiple receivers
126+
- diff_acc_to_diff_acc: multiple senders → multiple receivers
127+
"""
128+
senders, receivers = ether_transfer_case
129+
130+
# Create a single block with all transactions
131+
txs = []
132+
balances: dict[Address, int] = {}
133+
for _ in range(iteration_count):
134+
receiver = next(receivers)
135+
balances[receiver] = balances.get(receiver, 0) + transfer_amount
136+
txs.append(
137+
Transaction(
138+
to=receiver,
139+
value=transfer_amount,
140+
gas_limit=eth_transfer_cost,
141+
sender=next(senders),
142+
)
143+
)
144+
145+
# Only include post state for non a_to_a cases
146+
post_state = (
147+
{}
148+
if case_id == "a_to_a"
149+
else {receiver: Account(balance=balance) for receiver, balance in balances.items()}
150+
)
151+
152+
blockchain_test(
153+
genesis_environment=Environment(),
154+
pre=pre,
155+
post=post_state,
156+
blocks=[Block(txs=txs)],
157+
exclude_full_post_state_in_output=True,
158+
)

0 commit comments

Comments
 (0)