Skip to content

Commit 59c0cb4

Browse files
authored
Merge pull request #301 from spencer-tb/hive-fixture-refactor
improvement: Fixture generation split based on hive specificity
2 parents eab85da + 70dc4ed commit 59c0cb4

20 files changed

+1759
-334
lines changed

docs/getting_started/executing_tests_command_line.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Output:
113113
```console
114114
usage: fill [-h] [--evm-bin EVM_BIN] [--traces] [--solc-bin SOLC_BIN]
115115
[--filler-path FILLER_PATH] [--output OUTPUT] [--flat-output]
116-
[--disable-hive] [--forks] [--fork FORK] [--from FROM]
116+
[--enable-hive] [--forks] [--fork FORK] [--from FROM]
117117
[--until UNTIL] [--test-help]
118118

119119
options:
@@ -136,7 +136,7 @@ Arguments defining filler location and output:
136136
deleted.
137137
--flat-output Output each test case in the directory without the
138138
folder structure.
139-
--disable-hive Output tests skipping hive-related properties.
139+
--enable-hive Output test fixtures with the hive-specific properties.
140140

141141
Arguments defining debug behavior:
142142
--t8n-dump-dir T8N_DUMP_DIR

src/ethereum_test_tools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
FixtureEngineNewPayload,
2626
Header,
2727
HistoryStorageAddress,
28+
HiveFixture,
2829
JSONEncoder,
2930
Removable,
3031
Storage,
@@ -77,6 +78,7 @@
7778
"FixtureEngineNewPayload",
7879
"Header",
7980
"HistoryStorageAddress",
81+
"HiveFixture",
8082
"Initcode",
8183
"JSONEncoder",
8284
"Opcode",

src/ethereum_test_tools/common/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
Hash,
4242
Header,
4343
HeaderNonce,
44+
HiveFixture,
4445
JSONEncoder,
4546
Number,
4647
Removable,
@@ -77,6 +78,7 @@
7778
"Header",
7879
"HeaderNonce",
7980
"HistoryStorageAddress",
81+
"HiveFixture",
8082
"JSONEncoder",
8183
"Number",
8284
"Removable",

src/ethereum_test_tools/common/types.py

Lines changed: 101 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,16 +2569,21 @@ class FixtureEngineNewPayload:
25692569
to_json=True,
25702570
),
25712571
)
2572-
version: int = field(
2573-
json_encoder=JSONEncoder.Field(),
2574-
)
25752572
beacon_root: Optional[FixedSizeBytesConvertible] = field(
25762573
default=None,
25772574
json_encoder=JSONEncoder.Field(
25782575
name="parentBeaconBlockRoot",
25792576
cast_type=Hash,
25802577
),
25812578
)
2579+
version: int = field(
2580+
json_encoder=JSONEncoder.Field(),
2581+
)
2582+
valid: bool = field(
2583+
json_encoder=JSONEncoder.Field(
2584+
skip_string_convert=True,
2585+
),
2586+
)
25822587
error_code: Optional[EngineAPIError] = field(
25832588
default=None,
25842589
json_encoder=JSONEncoder.Field(
@@ -2594,6 +2599,7 @@ def from_fixture_header(
25942599
header: FixtureHeader,
25952600
transactions: List[Transaction],
25962601
withdrawals: Optional[List[Withdrawal]],
2602+
valid: bool,
25972603
error_code: Optional[EngineAPIError],
25982604
) -> Optional["FixtureEngineNewPayload"]:
25992605
"""
@@ -2611,6 +2617,7 @@ def from_fixture_header(
26112617
withdrawals=withdrawals,
26122618
),
26132619
version=new_payload_version,
2620+
valid=valid,
26142621
error_code=error_code,
26152622
)
26162623

@@ -2641,13 +2648,6 @@ class FixtureBlock:
26412648
to_json=True,
26422649
),
26432650
)
2644-
new_payload: Optional[FixtureEngineNewPayload] = field(
2645-
default=None,
2646-
json_encoder=JSONEncoder.Field(
2647-
name="engineNewPayload",
2648-
to_json=True,
2649-
),
2650-
)
26512651
expected_exception: Optional[str] = field(
26522652
default=None,
26532653
json_encoder=JSONEncoder.Field(
@@ -2689,9 +2689,9 @@ class FixtureBlock:
26892689

26902690

26912691
@dataclass(kw_only=True)
2692-
class Fixture:
2692+
class BaseFixture:
26932693
"""
2694-
Cross-client compatible Ethereum test fixture.
2694+
Base Ethereum test fixture class.
26952695
"""
26962696

26972697
info: Dict[str, str] = field(
@@ -2701,36 +2701,78 @@ class Fixture:
27012701
to_json=True,
27022702
),
27032703
)
2704-
blocks: List[FixtureBlock] = field(
2704+
fork: str = field(
27052705
json_encoder=JSONEncoder.Field(
2706-
name="blocks",
2707-
to_json=True,
2706+
name="network",
27082707
),
27092708
)
2710-
fcu_version: Optional[int] = field(
2709+
name: str = field(
2710+
default="",
27112711
json_encoder=JSONEncoder.Field(
2712-
name="engineFcuVersion",
2712+
skip=True,
27132713
),
27142714
)
2715-
genesis: FixtureHeader = field(
2715+
_json: Dict[str, Any] | None = field(
2716+
default=None,
27162717
json_encoder=JSONEncoder.Field(
2717-
name="genesisBlockHeader",
2718-
to_json=True,
2718+
skip=True,
27192719
),
27202720
)
2721+
2722+
def __post_init__(self):
2723+
"""
2724+
Post init hook to convert to JSON after instantiation.
2725+
"""
2726+
self._json = to_json(self)
2727+
2728+
def to_json(self) -> Dict[str, Any]:
2729+
"""
2730+
Convert to JSON.
2731+
"""
2732+
assert self._json is not None, "Fixture not initialized"
2733+
self._json["_info"] = self.info
2734+
return self._json
2735+
2736+
def fill_info(
2737+
self,
2738+
t8n: TransitionTool,
2739+
ref_spec: ReferenceSpec | None,
2740+
):
2741+
"""
2742+
Fill the info field for this fixture
2743+
"""
2744+
self.info["filling-transition-tool"] = t8n.version()
2745+
if ref_spec is not None:
2746+
ref_spec.write_info(self.info)
2747+
2748+
2749+
@dataclass(kw_only=True)
2750+
class Fixture(BaseFixture):
2751+
"""
2752+
Cross-client specific test fixture information.
2753+
"""
2754+
27212755
genesis_rlp: Bytes = field(
27222756
json_encoder=JSONEncoder.Field(
27232757
name="genesisRLP",
27242758
),
27252759
)
2726-
head: Hash = field(
2760+
genesis: FixtureHeader = field(
27272761
json_encoder=JSONEncoder.Field(
2728-
name="lastblockhash",
2762+
name="genesisBlockHeader",
2763+
to_json=True,
27292764
),
27302765
)
2731-
fork: str = field(
2766+
blocks: Optional[List[FixtureBlock]] = field(
2767+
default=None,
27322768
json_encoder=JSONEncoder.Field(
2733-
name="network",
2769+
name="blocks",
2770+
to_json=True,
2771+
),
2772+
)
2773+
head: Hash = field(
2774+
json_encoder=JSONEncoder.Field(
2775+
name="lastblockhash",
27342776
),
27352777
)
27362778
pre_state: Mapping[str, Account] = field(
@@ -2753,42 +2795,45 @@ class Fixture:
27532795
name="sealEngine",
27542796
),
27552797
)
2756-
name: str = field(
2757-
default="",
2798+
2799+
2800+
@dataclass(kw_only=True)
2801+
class HiveFixture(BaseFixture):
2802+
"""
2803+
Hive specific test fixture information.
2804+
"""
2805+
2806+
genesis: FixtureHeader = field(
27582807
json_encoder=JSONEncoder.Field(
2759-
skip=True,
2808+
name="genesisBlockHeader",
2809+
to_json=True,
27602810
),
27612811
)
2762-
2763-
_json: Dict[str, Any] | None = field(
2812+
payloads: Optional[List[Optional[FixtureEngineNewPayload]]] = field(
27642813
default=None,
27652814
json_encoder=JSONEncoder.Field(
2766-
skip=True,
2815+
name="engineNewPayloads",
2816+
to_json=True,
2817+
),
2818+
)
2819+
fcu_version: Optional[int] = field(
2820+
default=None,
2821+
json_encoder=JSONEncoder.Field(
2822+
name="engineFcuVersion",
2823+
),
2824+
)
2825+
pre_state: Mapping[str, Account] = field(
2826+
json_encoder=JSONEncoder.Field(
2827+
name="pre",
2828+
cast_type=Alloc,
2829+
to_json=True,
2830+
),
2831+
)
2832+
post_state: Optional[Mapping[str, Account]] = field(
2833+
default=None,
2834+
json_encoder=JSONEncoder.Field(
2835+
name="postState",
2836+
cast_type=Alloc,
2837+
to_json=True,
27672838
),
27682839
)
2769-
2770-
def __post_init__(self):
2771-
"""
2772-
Post init hook to convert to JSON after instantiation.
2773-
"""
2774-
self._json = to_json(self)
2775-
2776-
def to_json(self) -> Dict[str, Any]:
2777-
"""
2778-
Convert to JSON.
2779-
"""
2780-
assert self._json is not None, "Fixture not initialized"
2781-
self._json["_info"] = self.info
2782-
return self._json
2783-
2784-
def fill_info(
2785-
self,
2786-
t8n: TransitionTool,
2787-
ref_spec: ReferenceSpec | None,
2788-
):
2789-
"""
2790-
Fill the info field for this fixture
2791-
"""
2792-
self.info["filling-transition-tool"] = t8n.version()
2793-
if ref_spec is not None:
2794-
ref_spec.write_info(self.info)
Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
"""
22
Filler object definitions.
33
"""
4-
from typing import List, Optional
4+
from typing import List, Optional, Union
55

66
from ethereum_test_forks import Fork
77
from evm_transition_tool import TransitionTool
88

9-
from ..common import Fixture, alloc_to_accounts
9+
from ..common import Fixture, HiveFixture, alloc_to_accounts
1010
from ..reference_spec.reference_spec import ReferenceSpec
1111
from ..spec import BaseTest
1212

@@ -18,35 +18,53 @@ def fill_test(
1818
engine: str,
1919
spec: ReferenceSpec | None,
2020
eips: Optional[List[int]] = None,
21-
) -> Fixture:
21+
) -> Optional[Union[Fixture, HiveFixture]]:
2222
"""
2323
Fills fixtures for the specified fork.
2424
"""
2525
t8n.reset_traces()
2626

2727
pre, genesis_rlp, genesis = test_spec.make_genesis(t8n, fork)
2828

29-
(blocks, head, alloc, fcu_version) = test_spec.make_blocks(
29+
(blocks, payloads, head, alloc, fcu_version) = test_spec.make_blocks(
3030
t8n,
3131
genesis,
3232
pre,
3333
fork,
3434
eips=eips,
3535
)
3636

37-
fork_name = fork.name()
38-
fixture = Fixture(
39-
blocks=blocks,
40-
genesis=genesis,
41-
genesis_rlp=genesis_rlp,
42-
head=head,
43-
fork="+".join([fork_name] + [str(eip) for eip in eips]) if eips is not None else fork_name,
44-
pre_state=pre,
45-
post_state=alloc_to_accounts(alloc),
46-
seal_engine=engine,
47-
name=test_spec.tag,
48-
fcu_version=fcu_version,
37+
network_info = (
38+
"+".join([fork.name()] + [str(eip) for eip in eips]) if eips is not None else fork.name()
4939
)
40+
41+
fixture: Union[Fixture, HiveFixture]
42+
if test_spec.base_test_config.enable_hive:
43+
if fork.engine_new_payload_version() is not None:
44+
fixture = HiveFixture(
45+
payloads=payloads,
46+
fcu_version=fcu_version,
47+
genesis=genesis,
48+
fork=network_info,
49+
pre_state=pre,
50+
post_state=alloc_to_accounts(alloc),
51+
name=test_spec.tag,
52+
)
53+
else: # pre Merge tests are not supported in Hive
54+
# TODO: remove this logic. if hive enabled set --from to Merge
55+
return None
56+
else:
57+
fixture = Fixture(
58+
blocks=blocks,
59+
genesis=genesis,
60+
genesis_rlp=genesis_rlp,
61+
head=head,
62+
fork=network_info,
63+
pre_state=pre,
64+
post_state=alloc_to_accounts(alloc),
65+
seal_engine=engine,
66+
name=test_spec.tag,
67+
)
5068
fixture.fill_info(t8n, spec)
5169

5270
return fixture

0 commit comments

Comments
 (0)