Skip to content

Commit 0e4427c

Browse files
committed
filler: allow genesis state root calc to modify pre-alloc
1 parent 4aa816d commit 0e4427c

File tree

8 files changed

+49
-32
lines changed

8 files changed

+49
-32
lines changed

src/ethereum_test_tools/common/types.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,15 @@ def check_alloc(self: "Account", address: str, alloc: dict):
683683
actual_storage = Storage(alloc["storage"]) if "storage" in alloc else Storage({})
684684
expected_storage.must_be_equal(address=address, other=actual_storage)
685685

686+
@classmethod
687+
def from_dict(cls: Type, data: "Dict | Account") -> "Account":
688+
"""
689+
Create account from dictionary.
690+
"""
691+
if isinstance(data, cls):
692+
return data
693+
return cls(**data)
694+
686695
@classmethod
687696
def with_code(cls: Type, code: BytesConvertible) -> "Account":
688697
"""
@@ -691,7 +700,7 @@ def with_code(cls: Type, code: BytesConvertible) -> "Account":
691700
return Account(nonce=1, code=code)
692701

693702

694-
class Alloc(dict, Mapping[FixedSizeBytesConvertible, Account], SupportsJSON):
703+
class Alloc(dict, Mapping[FixedSizeBytesConvertible, Account | Dict], SupportsJSON):
695704
"""
696705
Allocation of accounts in the state, pre and post test execution.
697706
"""
@@ -700,7 +709,9 @@ def __json__(self, encoder: JSONEncoder) -> Mapping[str, Any]:
700709
"""
701710
Returns the JSON representation of the allocation.
702711
"""
703-
return encoder.default({Address(address): account for address, account in self.items()})
712+
return encoder.default(
713+
{Address(address): Account.from_dict(account) for address, account in self.items()}
714+
)
704715

705716

706717
def alloc_to_accounts(got_alloc: Dict[str, Any]) -> Mapping[str, Account]:

src/ethereum_test_tools/filling/fill.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Filler object definitions.
33
"""
4-
from copy import copy
54
from typing import List, Optional
65

76
from ethereum_test_forks import Fork
@@ -25,11 +24,12 @@ def fill_test(
2524
"""
2625
t8n.reset_traces()
2726

28-
genesis_rlp, genesis = test_spec.make_genesis(t8n, fork)
27+
pre, genesis_rlp, genesis = test_spec.make_genesis(t8n, fork)
2928

3029
(blocks, head, alloc) = test_spec.make_blocks(
3130
t8n,
3231
genesis,
32+
pre,
3333
fork,
3434
eips=eips,
3535
)
@@ -41,7 +41,7 @@ def fill_test(
4141
genesis_rlp=genesis_rlp,
4242
head=head,
4343
fork="+".join([fork_name] + [str(eip) for eip in eips]) if eips is not None else fork_name,
44-
pre_state=copy(test_spec.pre),
44+
pre_state=pre,
4545
post_state=alloc_to_accounts(alloc),
4646
seal_engine=engine,
4747
name=test_spec.tag,

src/ethereum_test_tools/spec/base_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ethereum_test_forks import Fork
1111
from evm_transition_tool import TransitionTool
1212

13-
from ..common import Account, Address, Bytes, FixtureBlock, FixtureHeader, Hash, Transaction
13+
from ..common import Account, Address, Alloc, Bytes, FixtureBlock, FixtureHeader, Hash, Transaction
1414

1515

1616
def verify_transactions(txs: List[Transaction] | None, result) -> List[int]:
@@ -91,7 +91,7 @@ def make_genesis(
9191
self,
9292
t8n: TransitionTool,
9393
fork: Fork,
94-
) -> Tuple[Bytes, FixtureHeader]:
94+
) -> Tuple[Alloc, Bytes, FixtureHeader]:
9595
"""
9696
Create a genesis block from the test definition.
9797
"""
@@ -102,6 +102,7 @@ def make_blocks(
102102
self,
103103
t8n: TransitionTool,
104104
genesis: FixtureHeader,
105+
pre: Alloc,
105106
fork: Fork,
106107
chain_id: int = 1,
107108
eips: Optional[List[int]] = None,

src/ethereum_test_tools/spec/blockchain_test.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,22 @@ def make_genesis(
5454
self,
5555
t8n: TransitionTool,
5656
fork: Fork,
57-
) -> Tuple[Bytes, FixtureHeader]:
57+
) -> Tuple[Alloc, Bytes, FixtureHeader]:
5858
"""
5959
Create a genesis block from the state test definition.
6060
"""
6161
env = self.genesis_environment.set_fork_requirements(fork)
6262

63+
new_alloc, state_root = t8n.calc_state_root(
64+
alloc=to_json(Alloc(self.pre)),
65+
fork=fork,
66+
debug_output_path=self.get_next_transition_tool_output_path(),
67+
)
6368
genesis = FixtureHeader(
6469
parent_hash=Hash(0),
6570
ommers_hash=Hash(EmptyOmmersRoot),
6671
coinbase=Address(0),
67-
state_root=Hash(
68-
t8n.calc_state_root(
69-
alloc=to_json(Alloc(self.pre)),
70-
fork=fork,
71-
debug_output_path=self.get_next_transition_tool_output_path(),
72-
)
73-
),
72+
state_root=Hash(state_root),
7473
transactions_root=Hash(EmptyTrieRoot),
7574
receipt_root=Hash(EmptyTrieRoot),
7675
bloom=Bloom(0),
@@ -103,7 +102,7 @@ def make_genesis(
103102
withdrawals=env.withdrawals,
104103
)
105104

106-
return genesis_rlp, genesis
105+
return Alloc(new_alloc), genesis_rlp, genesis
107106

108107
def make_block(
109108
self,
@@ -256,6 +255,7 @@ def make_blocks(
256255
self,
257256
t8n: TransitionTool,
258257
genesis: FixtureHeader,
258+
pre: Alloc,
259259
fork: Fork,
260260
chain_id=1,
261261
eips: Optional[List[int]] = None,
@@ -265,7 +265,7 @@ def make_blocks(
265265
Performs checks against the expected behavior of the test.
266266
Raises exception on invalid test behavior.
267267
"""
268-
alloc = to_json(Alloc(self.pre))
268+
alloc = to_json(pre)
269269
env = Environment.from_parent_header(genesis)
270270
blocks: List[FixtureBlock] = []
271271
head = genesis.hash if genesis.hash is not None else Hash(0)

src/ethereum_test_tools/spec/state_test.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def make_genesis(
5454
self,
5555
t8n: TransitionTool,
5656
fork: Fork,
57-
) -> Tuple[Bytes, FixtureHeader]:
57+
) -> Tuple[Alloc, Bytes, FixtureHeader]:
5858
"""
5959
Create a genesis block from the state test definition.
6060
"""
@@ -66,17 +66,17 @@ def make_genesis(
6666

6767
env = env.set_fork_requirements(fork)
6868

69+
new_alloc, state_root = t8n.calc_state_root(
70+
alloc=to_json(Alloc(self.pre)),
71+
fork=fork,
72+
debug_output_path=self.get_next_transition_tool_output_path(),
73+
)
74+
6975
genesis = FixtureHeader(
7076
parent_hash=Hash(0),
7177
ommers_hash=Hash(EmptyOmmersRoot),
7278
coinbase=Address(0),
73-
state_root=Hash(
74-
t8n.calc_state_root(
75-
alloc=to_json(Alloc(self.pre)),
76-
fork=fork,
77-
debug_output_path=self.get_next_transition_tool_output_path(),
78-
)
79-
),
79+
state_root=Hash(state_root),
8080
transactions_root=Hash(EmptyTrieRoot),
8181
receipt_root=Hash(EmptyTrieRoot),
8282
bloom=Bloom(0),
@@ -109,12 +109,13 @@ def make_genesis(
109109
withdrawals=env.withdrawals,
110110
)
111111

112-
return genesis_rlp, genesis
112+
return Alloc(new_alloc), genesis_rlp, genesis
113113

114114
def make_blocks(
115115
self,
116116
t8n: TransitionTool,
117117
genesis: FixtureHeader,
118+
pre: Alloc,
118119
fork: Fork,
119120
chain_id=1,
120121
eips: Optional[List[int]] = None,
@@ -130,7 +131,7 @@ def make_blocks(
130131
txs = [tx.with_signature_and_sender() for tx in self.txs] if self.txs is not None else []
131132

132133
alloc, result = t8n.evaluate(
133-
alloc=to_json(Alloc(self.pre)),
134+
alloc=to_json(pre),
134135
txs=to_json(txs),
135136
env=to_json(env),
136137
fork_name=fork.fork(block_number=Number(env.number), timestamp=Number(env.timestamp)),

src/ethereum_test_tools/tests/test_filler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ def test_make_genesis(fork: Fork, hash: bytes):
7676

7777
t8n = GethTransitionTool()
7878

79-
_, genesis = StateTest(env=env, pre=pre, post={}, txs=[], tag="some_state_test").make_genesis(
79+
_, _, genesis = StateTest(
80+
env=env, pre=pre, post={}, txs=[], tag="some_state_test"
81+
).make_genesis(
8082
t8n,
8183
fork,
8284
)

src/evm_transition_tool/tests/test_evaluate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class TestEnv:
7676

7777
env = TestEnv()
7878
env.base_fee = base_fee
79-
assert t8n.calc_state_root(alloc=alloc, fork=fork).startswith(hash)
79+
assert t8n.calc_state_root(alloc=alloc, fork=fork)[1].startswith(hash)
8080

8181

8282
@pytest.mark.parametrize("evm_tool", [GethTransitionTool])

src/evm_transition_tool/transition_tool.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ def get_traces(self) -> List[List[List[Dict]]] | None:
205205
"""
206206
return self.traces
207207

208-
def calc_state_root(self, *, alloc: Any, fork: Fork, debug_output_path: str = "") -> bytes:
208+
def calc_state_root(
209+
self, *, alloc: Any, fork: Fork, debug_output_path: str = ""
210+
) -> Tuple[Dict[str, Any], bytes]:
209211
"""
210212
Calculate the state root for the given `alloc`.
211213
"""
@@ -234,7 +236,7 @@ def calc_state_root(self, *, alloc: Any, fork: Fork, debug_output_path: str = ""
234236
"beaconRoot"
235237
] = "0x0000000000000000000000000000000000000000000000000000000000000000"
236238

237-
_, result = self.evaluate(
239+
new_alloc, result = self.evaluate(
238240
alloc=alloc,
239241
txs=[],
240242
env=env,
@@ -244,7 +246,7 @@ def calc_state_root(self, *, alloc: Any, fork: Fork, debug_output_path: str = ""
244246
state_root = result.get("stateRoot")
245247
if state_root is None or not isinstance(state_root, str):
246248
raise Exception("Unable to calculate state root")
247-
return bytes.fromhex(state_root[2:])
249+
return new_alloc, bytes.fromhex(state_root[2:])
248250

249251
def calc_withdrawals_root(
250252
self, *, withdrawals: Any, fork: Fork, debug_output_path: str = ""

0 commit comments

Comments
 (0)