diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index fe01f1fdbca..04b9d0dfc86 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -38,6 +38,7 @@ This release additionally includes fixes for tests in hive, as well as new test - ✨ Added `--watch` flag that monitors test files for changes and automatically re-runs the fill command when developing tests ([#2173](https://github.com/ethereum/execution-spec-tests/pull/2173)). - 🔀 Upgraded ckzg version to 2.1.3 or newer for correct handling of points at infinity ([#2171](https://github.com/ethereum/execution-spec-tests/pull/2171)). - 🔀 Move pytest marker registration for `fill` and `execute-*` from their respective ini files to the shared `pytest_plugins.shared.execute_fill` pytest plugin ([#2110](https://github.com/ethereum/execution-spec-tests/pull/2110)). +- ✨ Added an `--input.config` CLI argument to the transition tool (`t8n`) invocation ([#2264](https://github.com/ethereum/execution-spec-tests/pull/2264)). #### `consume` diff --git a/src/ethereum_clis/cli_types.py b/src/ethereum_clis/cli_types.py index c1b1ba8385b..f5292311d0c 100644 --- a/src/ethereum_clis/cli_types.py +++ b/src/ethereum_clis/cli_types.py @@ -15,6 +15,7 @@ Hash, HexNumber, ) +from ethereum_test_base_types.composite_types import ForkBlobSchedule from ethereum_test_exceptions import ( BlockException, ExceptionMapperValidator, @@ -261,6 +262,15 @@ class TransitionToolInput(CamelModel): env: Environment +class TransitionToolCLIInput(CamelModel): + """Transition tool CLI input.""" + + alloc: Alloc + txs: List[Transaction] + env: Environment + blob_params: ForkBlobSchedule | None = None + + class TransitionToolOutput(CamelModel): """Transition tool output.""" diff --git a/src/ethereum_clis/clis/evmone.py b/src/ethereum_clis/clis/evmone.py index 18baecaa176..b2cc47402a1 100644 --- a/src/ethereum_clis/clis/evmone.py +++ b/src/ethereum_clis/clis/evmone.py @@ -40,6 +40,7 @@ class EvmOneTransitionTool(TransitionTool): cached_version: Optional[str] = None trace: bool supports_opcode_count: ClassVar[bool] = True + supports_blob_params: ClassVar[bool] = True def __init__( self, diff --git a/src/ethereum_clis/transition_tool.py b/src/ethereum_clis/transition_tool.py index 4137c4c8afc..273739396a9 100644 --- a/src/ethereum_clis/transition_tool.py +++ b/src/ethereum_clis/transition_tool.py @@ -19,6 +19,7 @@ from requests_unixsocket import Session from ethereum_test_base_types import BlobSchedule +from ethereum_test_base_types.composite_types import ForkBlobSchedule from ethereum_test_exceptions import ExceptionMapper from ethereum_test_forks import Fork from ethereum_test_forks.helpers import get_development_forks, get_forks @@ -29,6 +30,7 @@ Traces, TransactionReceipt, TransactionTraces, + TransitionToolCLIInput, TransitionToolContext, TransitionToolInput, TransitionToolOutput, @@ -75,6 +77,7 @@ class TransitionTool(EthereumCLI): supports_opcode_count: ClassVar[bool] = False supports_xdist: ClassVar[bool] = True + supports_blob_params: ClassVar[bool] = False @abstractmethod def __init__( @@ -175,6 +178,16 @@ def fork_name(self) -> str: timestamp=self.env.timestamp, ) + @property + def blob_params(self) -> ForkBlobSchedule | None: + """Return the blob parameters for the current fork.""" + if self.blob_schedule: + fork_name = self.fork.fork_at( + block_number=self.env.number, timestamp=self.env.timestamp + ).name() + return self.blob_schedule[fork_name] + return None + def __post_init__(self) -> None: """Modify the reward if the environment number is 0.""" if self.env.number == 0: @@ -188,6 +201,15 @@ def to_input(self) -> TransitionToolInput: env=self.env, ) + def to_cli_input(self) -> TransitionToolCLIInput: + """Convert the data to a TransitionToolCLIInput object.""" + return TransitionToolCLIInput( + alloc=self.alloc, + txs=self.txs, + env=self.env, + blob_params=self.blob_params, + ) + def get_request_data(self) -> TransitionToolRequest: """Convert the data to a TransitionToolRequest object.""" return TransitionToolRequest( @@ -214,7 +236,7 @@ def _evaluate_filesystem( os.mkdir(os.path.join(temp_dir.name, "input")) os.mkdir(os.path.join(temp_dir.name, "output")) - input_contents = t8n_data.to_input().model_dump(mode="json", **model_dump_config) + input_contents = t8n_data.to_cli_input().model_dump(mode="json", **model_dump_config) input_paths = { k: os.path.join(temp_dir.name, "input", f"{k}.json") for k in input_contents.keys() @@ -258,6 +280,13 @@ def _evaluate_filesystem( "opcodes.json", ] ) + if self.supports_blob_params and input_paths.get("blobParams"): + args.extend( + [ + "--input.blobParams", + input_paths["blobParams"], + ] + ) if self.trace: args.append("--trace") diff --git a/src/ethereum_test_forks/base_fork.py b/src/ethereum_test_forks/base_fork.py index a08fc617cd8..ece6b3350f1 100644 --- a/src/ethereum_test_forks/base_fork.py +++ b/src/ethereum_test_forks/base_fork.py @@ -827,6 +827,17 @@ def parent(cls) -> Type["BaseFork"] | None: return None return base_class + @classmethod + def non_bpo_ancestor(cls) -> Type["BaseFork"]: + """Return the nearest non-BPO ancestor fork.""" + ancestor = cls + while ancestor.bpo_fork(): + parent = ancestor.parent() + if parent is None: + break + ancestor = parent + return ancestor + @classmethod def children(cls) -> Set[Type["BaseFork"]]: """Return the children forks.""" diff --git a/src/ethereum_test_forks/forks/forks.py b/src/ethereum_test_forks/forks/forks.py index 8831d4ea03e..8ac257555d2 100644 --- a/src/ethereum_test_forks/forks/forks.py +++ b/src/ethereum_test_forks/forks/forks.py @@ -1870,6 +1870,18 @@ def blob_base_cost(cls, *, block_number: int = 0, timestamp: int = 0) -> int: class BPO1(Osaka, bpo_fork=True): """Mainnet BPO1 fork - Blob Parameter Only fork 1.""" + @classmethod + def transition_tool_name(cls, *, block_number: int = 0, timestamp: int = 0) -> str: + """ + Return fork name as it's meant to be passed to the transition tool for + execution. + """ + return ( + cls.fork_at(block_number=block_number, timestamp=timestamp) + .non_bpo_ancestor() + .transition_tool_name() + ) + @classmethod def blob_base_fee_update_fraction(cls, *, block_number: int = 0, timestamp: int = 0) -> int: """Return the blob base fee update fraction for BPO1."""