Skip to content

Commit df014bf

Browse files
authored
chore(deps): create eels t8n transition tool (#1807)
1 parent cc5fc26 commit df014bf

File tree

7 files changed

+93
-99
lines changed

7 files changed

+93
-99
lines changed

src/ethereum_clis/clis/besu.py

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@
77
import tempfile
88
import textwrap
99
from pathlib import Path
10-
from typing import ClassVar, Dict, List, Optional
10+
from typing import ClassVar, Dict, Optional
1111

1212
import requests # type: ignore
1313

14-
from ethereum_test_base_types import BlobSchedule
1514
from ethereum_test_exceptions import (
1615
BlockException,
1716
ExceptionBase,
1817
ExceptionMapper,
1918
TransactionException,
2019
)
2120
from ethereum_test_forks import Fork
22-
from ethereum_test_types import Alloc, Environment, Transaction
2321

2422
from ..transition_tool import TransitionTool, dump_files_to_directory, model_dump_config
25-
from ..types import TransitionToolInput, TransitionToolOutput
23+
from ..types import TransitionToolOutput
2624

2725

2826
class BesuTransitionTool(TransitionTool):
@@ -98,36 +96,20 @@ def shutdown(self):
9896
def evaluate(
9997
self,
10098
*,
101-
alloc: Alloc,
102-
txs: List[Transaction],
103-
env: Environment,
104-
fork: Fork,
105-
chain_id: int,
106-
reward: int,
107-
blob_schedule: BlobSchedule | None = None,
99+
transition_tool_data: TransitionTool.TransitionToolData,
108100
debug_output_path: str = "",
109-
state_test: bool = False,
110101
slow_request: bool = False,
111102
) -> TransitionToolOutput:
112103
"""Execute `evm t8n` with the specified arguments."""
113104
if not self.process:
114105
self.start_server()
115106

116-
fork_name = fork.transition_tool_name(
117-
block_number=env.number,
118-
timestamp=env.timestamp,
119-
)
120-
121-
input_json = TransitionToolInput(
122-
alloc=alloc,
123-
txs=txs,
124-
env=env,
125-
).model_dump(mode="json", **model_dump_config)
107+
input_json = transition_tool_data.to_input().model_dump(mode="json", **model_dump_config)
126108

127109
state_json = {
128-
"fork": fork_name,
129-
"chainid": chain_id,
130-
"reward": reward,
110+
"fork": transition_tool_data.fork_name,
111+
"chainid": transition_tool_data.chain_id,
112+
"reward": transition_tool_data.reward,
131113
}
132114

133115
post_data = {"state": state_json, "input": input_json}

src/ethereum_clis/tests/test_execution_specs.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,15 @@ def test_evm_t8n(
164164
expected = json.load(exp)
165165

166166
t8n_output = default_t8n.evaluate(
167-
alloc=alloc,
168-
txs=txs,
169-
env=env,
170-
fork=Berlin,
171-
chain_id=1,
172-
reward=0,
173-
blob_schedule=Berlin.blob_schedule(),
167+
transition_tool_data=TransitionTool.TransitionToolData(
168+
alloc=alloc,
169+
txs=txs,
170+
env=env,
171+
fork=Berlin,
172+
chain_id=1,
173+
reward=0,
174+
blob_schedule=Berlin.blob_schedule(),
175+
),
174176
)
175177
assert to_json(t8n_output.alloc) == expected.get("alloc")
176178
if isinstance(default_t8n, ExecutionSpecsTransitionTool):

src/ethereum_clis/transition_tool.py

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,24 @@ class TransitionToolData:
136136
alloc: Alloc
137137
txs: List[Transaction]
138138
env: Environment
139-
fork_name: str
139+
fork: Fork
140140
chain_id: int
141141
reward: int
142142
blob_schedule: BlobSchedule | None
143-
state_test: bool
143+
state_test: bool = False
144+
145+
@property
146+
def fork_name(self) -> str:
147+
"""Return the fork name."""
148+
return self.fork.transition_tool_name(
149+
block_number=self.env.number,
150+
timestamp=self.env.timestamp,
151+
)
152+
153+
def __post_init__(self):
154+
"""Modify the reward if the environment number is 0."""
155+
if self.env.number == 0:
156+
self.reward = -1
144157

145158
def to_input(self) -> TransitionToolInput:
146159
"""Convert the data to a TransactionToolInput object."""
@@ -493,15 +506,8 @@ def dump_debug_stream(
493506
def evaluate(
494507
self,
495508
*,
496-
alloc: Alloc,
497-
txs: List[Transaction],
498-
env: Environment,
499-
fork: Fork,
500-
chain_id: int,
501-
reward: int,
502-
blob_schedule: BlobSchedule | None,
509+
transition_tool_data: TransitionToolData,
503510
debug_output_path: str = "",
504-
state_test: bool = False,
505511
slow_request: bool = False,
506512
) -> TransitionToolOutput:
507513
"""
@@ -510,36 +516,21 @@ def evaluate(
510516
If a client's `t8n` tool varies from the default behavior, this method
511517
can be overridden.
512518
"""
513-
fork_name = fork.transition_tool_name(
514-
block_number=env.number,
515-
timestamp=env.timestamp,
516-
)
517-
if env.number == 0:
518-
reward = -1
519-
t8n_data = self.TransitionToolData(
520-
alloc=alloc,
521-
txs=txs,
522-
env=env,
523-
fork_name=fork_name,
524-
chain_id=chain_id,
525-
reward=reward,
526-
blob_schedule=blob_schedule,
527-
state_test=state_test,
528-
)
529-
530519
if self.t8n_use_server:
531520
if not self.process:
532521
self.start_server()
533522
return self._evaluate_server(
534-
t8n_data=t8n_data,
523+
t8n_data=transition_tool_data,
535524
debug_output_path=debug_output_path,
536525
timeout=SLOW_REQUEST_TIMEOUT if slow_request else NORMAL_SERVER_TIMEOUT,
537526
)
538527

539528
if self.t8n_use_stream:
540-
return self._evaluate_stream(t8n_data=t8n_data, debug_output_path=debug_output_path)
529+
return self._evaluate_stream(
530+
t8n_data=transition_tool_data, debug_output_path=debug_output_path
531+
)
541532

542533
return self._evaluate_filesystem(
543-
t8n_data=t8n_data,
534+
t8n_data=transition_tool_data,
544535
debug_output_path=debug_output_path,
545536
)

src/ethereum_test_specs/blockchain.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,15 @@ def generate_block_data(
498498
)
499499

500500
transition_tool_output = t8n.evaluate(
501-
alloc=previous_alloc,
502-
txs=txs,
503-
env=env,
504-
fork=fork,
505-
chain_id=self.chain_id,
506-
reward=fork.get_reward(env.number, env.timestamp),
507-
blob_schedule=fork.blob_schedule(),
501+
transition_tool_data=TransitionTool.TransitionToolData(
502+
alloc=previous_alloc,
503+
txs=txs,
504+
env=env,
505+
fork=fork,
506+
chain_id=self.chain_id,
507+
reward=fork.get_reward(env.number, env.timestamp),
508+
blob_schedule=fork.blob_schedule(),
509+
),
508510
debug_output_path=self.get_next_transition_tool_output_path(),
509511
slow_request=self.is_tx_gas_heavy_test(),
510512
)

src/ethereum_test_specs/state.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,17 @@ def make_state_test_fixture(
182182
raise Exception(f"Empty accounts in pre state: {empty_accounts}")
183183

184184
transition_tool_output = t8n.evaluate(
185-
alloc=pre_alloc,
186-
txs=[tx],
187-
env=env,
188-
fork=fork,
189-
chain_id=self.chain_id,
190-
reward=0, # Reward on state tests is always zero
191-
blob_schedule=fork.blob_schedule(),
185+
transition_tool_data=TransitionTool.TransitionToolData(
186+
alloc=pre_alloc,
187+
txs=[tx],
188+
env=env,
189+
fork=fork,
190+
chain_id=self.chain_id,
191+
reward=0, # Reward on state tests is always zero
192+
blob_schedule=fork.blob_schedule(),
193+
state_test=True,
194+
),
192195
debug_output_path=self.get_next_transition_tool_output_path(),
193-
state_test=True,
194196
slow_request=self.is_tx_gas_heavy_test(),
195197
)
196198

src/pytest_plugins/filler/filler.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def pytest_addoption(parser: pytest.Parser):
122122
action="store",
123123
dest="evm_bin",
124124
type=Path,
125-
default="ethereum-spec-evm-resolver",
125+
default=None,
126126
help=(
127127
"Path to an evm executable (or name of an executable in the PATH) that provides `t8n`."
128128
" Default: `ethereum-spec-evm-resolver`."
@@ -345,18 +345,23 @@ def pytest_configure(config):
345345

346346
# Instantiate the transition tool here to check that the binary path/trace option is valid.
347347
# This ensures we only raise an error once, if appropriate, instead of for every test.
348-
t8n = TransitionTool.from_binary_path(
349-
binary_path=config.getoption("evm_bin"), trace=config.getoption("evm_collect_traces")
350-
)
351-
if (
352-
isinstance(config.getoption("numprocesses"), int)
353-
and config.getoption("numprocesses") > 0
354-
and "Besu" in str(t8n.detect_binary_pattern)
355-
):
356-
pytest.exit(
357-
"The Besu t8n tool does not work well with the xdist plugin; use -n=0.",
358-
returncode=pytest.ExitCode.USAGE_ERROR,
348+
evm_bin = config.getoption("evm_bin")
349+
if evm_bin is None:
350+
assert TransitionTool.default_tool is not None, "No default transition tool found"
351+
t8n = TransitionTool.default_tool(trace=config.getoption("evm_collect_traces"))
352+
else:
353+
t8n = TransitionTool.from_binary_path(
354+
binary_path=evm_bin, trace=config.getoption("evm_collect_traces")
359355
)
356+
if (
357+
isinstance(config.getoption("numprocesses"), int)
358+
and config.getoption("numprocesses") > 0
359+
and "Besu" in str(t8n.detect_binary_pattern)
360+
):
361+
pytest.exit(
362+
"The Besu t8n tool does not work well with the xdist plugin; use -n=0.",
363+
returncode=pytest.ExitCode.USAGE_ERROR,
364+
)
360365

361366
if "Tools" not in config.stash[metadata_key]:
362367
config.stash[metadata_key]["Tools"] = {
@@ -538,7 +543,7 @@ def pytest_html_report_title(report):
538543

539544

540545
@pytest.fixture(autouse=True, scope="session")
541-
def evm_bin(request: pytest.FixtureRequest) -> Path:
546+
def evm_bin(request: pytest.FixtureRequest) -> Path | None:
542547
"""Return configured evm tool binary path used to run t8n."""
543548
return request.config.getoption("evm_bin")
544549

@@ -553,11 +558,17 @@ def verify_fixtures_bin(request: pytest.FixtureRequest) -> Path | None:
553558

554559

555560
@pytest.fixture(autouse=True, scope="session")
556-
def t8n(request: pytest.FixtureRequest, evm_bin: Path) -> Generator[TransitionTool, None, None]:
561+
def t8n(
562+
request: pytest.FixtureRequest, evm_bin: Path | None
563+
) -> Generator[TransitionTool, None, None]:
557564
"""Return configured transition tool."""
558-
t8n = TransitionTool.from_binary_path(
559-
binary_path=evm_bin, trace=request.config.getoption("evm_collect_traces")
560-
)
565+
if evm_bin is None:
566+
assert TransitionTool.default_tool is not None, "No default transition tool found"
567+
t8n = TransitionTool.default_tool(trace=request.config.getoption("evm_collect_traces"))
568+
else:
569+
t8n = TransitionTool.from_binary_path(
570+
binary_path=evm_bin, trace=request.config.getoption("evm_collect_traces")
571+
)
561572
if not t8n.exception_mapper.reliable:
562573
warnings.warn(
563574
f"The t8n tool that is currently being used to fill tests ({t8n.__class__.__name__}) "
@@ -590,7 +601,7 @@ def do_fixture_verification(
590601
def evm_fixture_verification(
591602
request: pytest.FixtureRequest,
592603
do_fixture_verification: bool,
593-
evm_bin: Path,
604+
evm_bin: Path | None,
594605
verify_fixtures_bin: Path | None,
595606
) -> Generator[FixtureConsumer | None, None, None]:
596607
"""

src/pytest_plugins/forks/forks.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,15 @@ def get_fork_option(config, option_name: str, parameter_name: str) -> Set[Fork]:
524524
return
525525

526526
evm_bin = config.getoption("evm_bin", None)
527-
if evm_bin is not None:
527+
if evm_bin is None:
528+
assert TransitionTool.default_tool is not None, "No default transition tool found"
529+
t8n = TransitionTool.default_tool()
530+
elif evm_bin is not None:
528531
t8n = TransitionTool.from_binary_path(binary_path=evm_bin)
529-
config.unsupported_forks = frozenset( # type: ignore
530-
fork for fork in selected_fork_set if not t8n.is_fork_supported(fork)
531-
)
532+
533+
config.unsupported_forks = frozenset( # type: ignore
534+
fork for fork in selected_fork_set if not t8n.is_fork_supported(fork)
535+
)
532536

533537

534538
@pytest.hookimpl(trylast=True)

0 commit comments

Comments
 (0)