Skip to content

Commit 19d709c

Browse files
committed
more unit tests for post state verification
expect section wip
1 parent 398003d commit 19d709c

File tree

2 files changed

+386
-11
lines changed

2 files changed

+386
-11
lines changed
Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
"""
2+
Tests for the fixture `post` (expect) section.
3+
"""
4+
5+
from collections import namedtuple
6+
from typing import Any, Mapping, Optional
7+
8+
import pytest
9+
10+
from ethereum_test_forks import Fork, Shanghai
11+
from evm_transition_tool import GethTransitionTool
12+
13+
from ..common import Account, Environment, Transaction
14+
from ..common.types import Storage
15+
from ..filling import fill_test
16+
from ..spec import BaseTestConfig, StateTest
17+
from ..vm.opcode import Opcodes as Op
18+
19+
ExpectSectionIndex = namedtuple("ExpectSectionIndex", ["d", "g", "v", "fork"])
20+
21+
22+
class ExpectSection:
23+
"""Manage expected post states for state tests transactions"""
24+
25+
def __init__(self):
26+
self.sections: list[tuple[ExpectSectionIndex, dict[str, Account]]] = []
27+
28+
def add_expect(self, ind: ExpectSectionIndex, expect: dict[str, Account]) -> None:
29+
"""Adds a section with a given indexes and expect dictionary."""
30+
self.sections.append((ind, expect))
31+
32+
def get_expect(self, tx_ind: ExpectSectionIndex) -> Optional[dict[str, Account]]:
33+
"""Returns the element associated with the given id, if it exists."""
34+
for section_ind, section in self.sections:
35+
if (
36+
(tx_ind.d in section_ind.d or section_ind.d == -1)
37+
and (tx_ind.g in section_ind.g or section_ind.g == -1)
38+
and (tx_ind.v in section_ind.v or section_ind.v == -1)
39+
):
40+
return section
41+
return None
42+
43+
44+
test_fork = Shanghai
45+
sender_address = "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"
46+
test_address = "0x1000000000000000000000000000000000000000"
47+
test_transaction = Transaction(
48+
ty=0x0,
49+
chain_id=0x0,
50+
nonce=0,
51+
to=test_address,
52+
gas_limit=100000000,
53+
gas_price=10,
54+
protected=False,
55+
)
56+
57+
58+
def run_test(
59+
pre: Mapping[Any, Any], post: Mapping[Any, Any], tx: Transaction, fork: Fork, exception: Any
60+
) -> Optional[pytest.ExceptionInfo]:
61+
"""
62+
Perform the test execution and post state verification given pre and post
63+
"""
64+
state_test = StateTest(
65+
env=Environment(),
66+
pre=pre,
67+
post=post,
68+
txs=[tx],
69+
tag="post_storage_value_mismatch",
70+
base_test_config=BaseTestConfig(enable_hive=False),
71+
)
72+
73+
t8n = GethTransitionTool()
74+
75+
e_info: pytest.ExceptionInfo
76+
if exception is not None:
77+
with pytest.raises(exception) as e_info:
78+
fixture = {
79+
f"000/my_chain_id_test/{fork}": fill_test(
80+
t8n=t8n,
81+
test_spec=state_test,
82+
fork=fork,
83+
spec=None,
84+
),
85+
}
86+
return e_info
87+
else:
88+
fixture = {
89+
f"000/my_chain_id_test/{fork}": fill_test(
90+
t8n=t8n,
91+
test_spec=state_test,
92+
fork=fork,
93+
spec=None,
94+
),
95+
}
96+
return None
97+
98+
99+
def test_expect_section_example():
100+
"""
101+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
102+
"""
103+
pre = {
104+
sender_address: Account(balance=1000000000000000000000),
105+
test_address: Account(nonce=1, code=Op.SSTORE(0, Op.CALLVALUE)),
106+
}
107+
108+
post_1 = {
109+
test_address: Account(storage={"0x00": "0x09"}),
110+
}
111+
post_2 = {
112+
test_address: Account(storage={"0x00": "0x03"}),
113+
}
114+
115+
expect_section = ExpectSection()
116+
expect_section.add_expect(ExpectSectionIndex(d=[0], g=[0], v=[0, 1], fork=Shanghai), post_1)
117+
# expect_section.add_expect(ExpectSectionIndex(d=0, g=0, v=1, fork=Shanghai), post_2)
118+
119+
transaction = test_transaction
120+
transaction.value = 1
121+
tx_index = ExpectSectionIndex(d=0, g=0, v=0, fork=Shanghai)
122+
e_info = run_test(
123+
pre, expect_section.get_expect(tx_index), transaction, test_fork, Storage.KeyValueMismatch
124+
)
125+
assert e_info.value.want == 9
126+
assert e_info.value.got == 1
127+
assert e_info.value.key == 0
128+
assert e_info.value.address == test_address
129+
assert "incorrect value in address" in str(e_info.value)
130+
131+
transaction = test_transaction
132+
transaction.value = 2
133+
tx_index = ExpectSectionIndex(d=0, g=0, v=1, fork=Shanghai)
134+
e_info = run_test(
135+
pre, expect_section.get_expect(tx_index), transaction, test_fork, Storage.KeyValueMismatch
136+
)
137+
assert e_info.value.want == 9
138+
assert e_info.value.got == 2
139+
assert e_info.value.key == 0
140+
assert e_info.value.address == test_address
141+
assert "incorrect value in address" in str(e_info.value)
142+
143+
144+
def test_post_account_mismatch_nonce():
145+
"""
146+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
147+
"""
148+
pre = {
149+
sender_address: Account(balance=1000000000000000000000),
150+
test_address: Account(nonce=1),
151+
}
152+
153+
post = {
154+
test_address: Account(nonce=2),
155+
}
156+
157+
e_info = run_test(pre, post, test_transaction, test_fork, Account.NonceMismatch)
158+
assert e_info.value.want == 2
159+
assert e_info.value.got == 1
160+
assert e_info.value.address == test_address
161+
assert "unexpected nonce for account" in str(e_info.value)
162+
163+
164+
def test_post_account_mismatch_nonce_a():
165+
"""
166+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
167+
"""
168+
pre = {
169+
sender_address: Account(balance=1000000000000000000000),
170+
test_address: Account(nonce=1),
171+
}
172+
173+
post = {
174+
test_address: Account(),
175+
}
176+
177+
run_test(pre, post, test_transaction, test_fork, None)
178+
179+
180+
def test_post_account_mismatch_nonce_b():
181+
"""
182+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
183+
"""
184+
pre = {
185+
sender_address: Account(balance=1000000000000000000000),
186+
test_address: Account(nonce=1),
187+
}
188+
189+
post = {
190+
test_address: Account(nonce=0),
191+
}
192+
193+
e_info = run_test(pre, post, test_transaction, test_fork, Account.NonceMismatch)
194+
assert e_info.value.want == 0
195+
assert e_info.value.got == 1
196+
assert e_info.value.address == test_address
197+
assert "unexpected nonce for account" in str(e_info.value)
198+
199+
200+
def test_post_account_mismatch_code():
201+
"""
202+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
203+
"""
204+
pre = {
205+
sender_address: Account(balance=1000000000000000000000),
206+
test_address: Account(code="0x02"),
207+
}
208+
209+
post = {
210+
test_address: Account(code="0x01"),
211+
}
212+
213+
e_info = run_test(pre, post, test_transaction, test_fork, Account.CodeMismatch)
214+
assert e_info.value.want == "0x01"
215+
assert e_info.value.got == "0x02"
216+
assert e_info.value.address == test_address
217+
assert "unexpected code for account" in str(e_info.value)
218+
219+
220+
def test_post_account_mismatch_code_a():
221+
"""
222+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
223+
"""
224+
pre = {
225+
sender_address: Account(balance=1000000000000000000000),
226+
test_address: Account(code="0x02"),
227+
}
228+
229+
post = {
230+
test_address: Account(),
231+
}
232+
233+
run_test(pre, post, test_transaction, test_fork, None)
234+
235+
236+
def test_post_account_mismatch_code_b():
237+
"""
238+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
239+
"""
240+
pre = {
241+
sender_address: Account(balance=1000000000000000000000),
242+
test_address: Account(code="0x02"),
243+
}
244+
245+
post = {
246+
test_address: Account(code=""),
247+
}
248+
249+
e_info = run_test(pre, post, test_transaction, test_fork, Account.CodeMismatch)
250+
assert e_info.value.want == "0x"
251+
assert e_info.value.got == "0x02"
252+
assert e_info.value.address == test_address
253+
assert "unexpected code for account" in str(e_info.value)
254+
255+
256+
def test_post_account_mismatch_balance():
257+
"""
258+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
259+
"""
260+
pre = {
261+
sender_address: Account(balance=1000000000000000000000),
262+
test_address: Account(balance=1),
263+
}
264+
265+
post = {
266+
test_address: Account(balance=2),
267+
}
268+
269+
test_transaction.value = 0
270+
e_info = run_test(pre, post, test_transaction, test_fork, Account.BalanceMismatch)
271+
assert e_info.value.want == 2
272+
assert e_info.value.got == 1
273+
assert e_info.value.address == test_address
274+
assert "unexpected balance for account" in str(e_info.value)
275+
276+
277+
def test_post_account_mismatch_balance_a():
278+
"""
279+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
280+
"""
281+
pre = {
282+
sender_address: Account(balance=1000000000000000000000),
283+
test_address: Account(balance=1),
284+
}
285+
286+
post = {
287+
test_address: Account(),
288+
}
289+
290+
test_transaction.value = 0
291+
run_test(pre, post, test_transaction, test_fork, None)
292+
293+
294+
def test_post_account_mismatch_balance_b():
295+
"""
296+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
297+
"""
298+
pre = {
299+
sender_address: Account(balance=1000000000000000000000),
300+
test_address: Account(balance=1),
301+
}
302+
303+
post = {
304+
test_address: Account(balance=0),
305+
}
306+
307+
e_info = run_test(pre, post, test_transaction, test_fork, Account.BalanceMismatch)
308+
assert e_info.value.want == 0
309+
assert e_info.value.got == 1
310+
assert e_info.value.address == test_address
311+
assert "unexpected balance for account" in str(e_info.value)
312+
313+
314+
def test_post_account_mismatch_account():
315+
"""
316+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
317+
"""
318+
pre = {
319+
sender_address: Account(balance=1000000000000000000000),
320+
test_address: Account(balance=1),
321+
}
322+
323+
post = {
324+
test_address: Account(),
325+
}
326+
327+
run_test(pre, post, test_transaction, test_fork, None)
328+
329+
330+
def test_post_account_mismatch_account_a():
331+
"""
332+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
333+
"""
334+
pre = {
335+
sender_address: Account(balance=1000000000000000000000),
336+
test_address: Account(balance=1),
337+
}
338+
339+
post = {
340+
0x1000000000000000000000000000000000000001: Account(),
341+
}
342+
343+
e_info = run_test(pre, post, test_transaction, test_fork, Exception)
344+
assert "expected account not found" in str(e_info.value)
345+
346+
347+
def test_post_account_mismatch_account_b():
348+
"""
349+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
350+
"""
351+
pre = {
352+
sender_address: Account(balance=1000000000000000000000),
353+
test_address: Account(balance=1),
354+
}
355+
356+
post = {}
357+
358+
run_test(pre, post, test_transaction, test_fork, None)
359+
360+
361+
def test_post_account_mismatch_account_c():
362+
"""
363+
Test `ethereum_test.filler.fill_fixtures` with `StateTest` and post state verification.
364+
"""
365+
pre = {
366+
sender_address: Account(balance=1000000000000000000000),
367+
test_address: Account(balance=1),
368+
}
369+
370+
post = {test_address: Account.NONEXISTENT}
371+
372+
e_info = run_test(pre, post, test_transaction, test_fork, Exception)
373+
assert "found unexpected account" in str(e_info.value)

0 commit comments

Comments
 (0)