From f67704d280b0749ca65407c0c45016e1b11b21d5 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:22:21 +0200 Subject: [PATCH 01/14] feat(fixtures): add `executionWitness` to `FixtureBlockBase` --- src/ethereum_test_fixtures/blockchain.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/ethereum_test_fixtures/blockchain.py b/src/ethereum_test_fixtures/blockchain.py index 3cd0b848d17..7ea7c5c9982 100644 --- a/src/ethereum_test_fixtures/blockchain.py +++ b/src/ethereum_test_fixtures/blockchain.py @@ -1,5 +1,7 @@ """BlockchainTest types.""" +import json +from dataclasses import dataclass from functools import cached_property from typing import ( Annotated, @@ -401,6 +403,21 @@ def from_withdrawal(cls, w: WithdrawalGeneric) -> "FixtureWithdrawal": return cls(**w.model_dump()) +@dataclass(slots=True) +class WitnessChunk: + """Represents execution witness data for a block.""" + + state: List[str] + codes: List[str] + keys: List[str] + headers: List[str] + + @classmethod + def from_json(cls, s: str) -> List["WitnessChunk"]: + """Parse witness chunks from JSON string.""" + return [cls(**obj) for obj in json.loads(s)] + + class FixtureBlockBase(CamelModel): """Representation of an Ethereum block within a test Fixture without RLP bytes.""" @@ -408,6 +425,7 @@ class FixtureBlockBase(CamelModel): txs: List[FixtureTransaction] = Field(default_factory=list, alias="transactions") ommers: List[FixtureHeader] = Field(default_factory=list, alias="uncleHeaders") withdrawals: List[FixtureWithdrawal] | None = None + execution_witness: WitnessChunk | None = Field(None, alias="executionWitness") @computed_field(alias="blocknumber") # type: ignore[misc] @cached_property From 3f5be35863fb442e8caf996625e02ac2f0a51f26 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:31:23 +0200 Subject: [PATCH 02/14] feat(fill): add a plugin for execution witness generation --- src/pytest_plugins/filler/witness.py | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/pytest_plugins/filler/witness.py diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py new file mode 100644 index 00000000000..eb3a4abd494 --- /dev/null +++ b/src/pytest_plugins/filler/witness.py @@ -0,0 +1,107 @@ +""" +Pytest plugin for witness functionality. + +Provides --witness command-line option that installs the witness-filler tool +and generates execution witness data for blockchain test fixtures when enabled. +""" + +import subprocess +from typing import Any, Callable + +import pytest + +from ethereum_test_fixtures.blockchain import FixtureBlock, WitnessChunk + + +def pytest_addoption(parser: pytest.Parser): + """Add witness command-line options to pytest.""" + witness_group = parser.getgroup("witness", "Arguments for witness functionality") + witness_group.addoption( + "--witness", + action="store_true", + dest="witness", + default=False, + help=( + "Install the witness-filler tool and generate execution witness data for blockchain " + "test fixtures" + ), + ) + + +def pytest_configure(config): + """ + Pytest hook called after command line options have been parsed. + + If --witness is enabled, installs the witness-filler tool from the specified + git repository. + """ + if config.getoption("witness"): + print("🔧 Installing witness-filler tool from kevaundray/reth...") + print(" This may take several minutes for first-time compilation...") + + result = subprocess.run( + [ + "cargo", + "install", + "--git", + "https://github.com/kevaundray/reth.git", + "--rev", + "8016a8a5736e4427b3d285c82cd39c4ece70f8c4", + "witness-filler", + ], + ) + + if result.returncode != 0: + pytest.exit( + f"Failed to install witness-filler tool (exit code: {result.returncode}). " + "Please ensure you have a compatible Rust toolchain installed. " + "You may need to update your Rust version to 1.86+ or run without --witness.", + 1, + ) + else: + print("✅ witness-filler tool installed successfully!") + + +@pytest.fixture +def witness_generator(request: pytest.FixtureRequest) -> Callable[[Any], None] | None: + """ + Provide a witness generator function if --witness is enabled. + + Returns: + None if witness functionality is disabled. + Callable that generates witness data for a fixture if enabled. + + """ + if not request.config.getoption("witness"): + return None + + def generate_witness(fixture: Any) -> None: + """Generate witness data for a fixture using the witness-filler tool.""" + if not hasattr(fixture, "blocks") or not fixture.blocks: + return + + result = subprocess.run( + ["witness-filler"], + input=fixture.model_dump_json(by_alias=True), + text=True, + capture_output=True, + ) + + if result.returncode != 0: + raise RuntimeError( + f"witness-filler tool failed with exit code {result.returncode}. " + f"stderr: {result.stderr}" + ) + + try: + witnesses = WitnessChunk.from_json(result.stdout) + for i, witness in enumerate(witnesses): + if i < len(fixture.blocks) and isinstance(fixture.blocks[i], FixtureBlock): + fixture.blocks[i].execution_witness = witness + except (ValueError, IndexError, AttributeError) as e: + raise RuntimeError( + f"Failed to parse witness data from witness-filler tool. " + f"Output was: {result.stdout[:500]}{'...' if len(result.stdout) > 500 else ''}" + ) from e + + return generate_witness From 6e4d8ee8cf482ce2b11d89798489360f0780d4ce Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:33:08 +0200 Subject: [PATCH 03/14] feat(fill): use the `generate_witness` fixture in the `filler` plugin --- src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini | 1 + src/pytest_plugins/filler/filler.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini b/src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini index dcdab775d66..84915897eb4 100644 --- a/src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini +++ b/src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini @@ -12,6 +12,7 @@ addopts = -p pytest_plugins.concurrency -p pytest_plugins.filler.pre_alloc -p pytest_plugins.filler.filler + -p pytest_plugins.filler.witness -p pytest_plugins.shared.execute_fill -p pytest_plugins.filler.ported_tests -p pytest_plugins.filler.static_filler diff --git a/src/pytest_plugins/filler/filler.py b/src/pytest_plugins/filler/filler.py index b96ec252a34..83d8e94812e 100644 --- a/src/pytest_plugins/filler/filler.py +++ b/src/pytest_plugins/filler/filler.py @@ -1140,6 +1140,7 @@ def base_test_parametrizer_func( test_case_description: str, fixture_source_url: str, gas_benchmark_value: int, + witness_generator, ): """ Fixture used to instantiate an auto-fillable BaseTest object from within @@ -1223,6 +1224,10 @@ def __init__(self, *args, **kwargs): _info_metadata=t8n._info_metadata, ) + # Generate witness data if witness functionality is enabled via the witness plugin + if witness_generator is not None: + witness_generator(fixture) + fixture_path = fixture_collector.add_fixture( node_to_test_info(request.node), fixture, From c43c1ba94728036ca2df5f6f0119d344eb5c722b Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:40:00 +0200 Subject: [PATCH 04/14] feat(fill,help): enable witness plugin help output to `fill --help`. --- src/pytest_plugins/help/help.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pytest_plugins/help/help.py b/src/pytest_plugins/help/help.py index aaa55960bd4..b70c0357a55 100644 --- a/src/pytest_plugins/help/help.py +++ b/src/pytest_plugins/help/help.py @@ -87,6 +87,7 @@ def pytest_configure(config): "defining debug", "pre-allocation behavior during test filling", "ported", + "witness", ], ) elif config.getoption("show_consume_help"): From d2eddbfa417e2203547bf5a341a7e765ebf88d87 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:41:47 +0200 Subject: [PATCH 05/14] chore(fill): fix punctuation in witness plugin help string --- src/pytest_plugins/filler/witness.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index eb3a4abd494..1ed0178a53f 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -18,12 +18,13 @@ def pytest_addoption(parser: pytest.Parser): witness_group = parser.getgroup("witness", "Arguments for witness functionality") witness_group.addoption( "--witness", + "--witness-the-fitness", action="store_true", dest="witness", default=False, help=( "Install the witness-filler tool and generate execution witness data for blockchain " - "test fixtures" + "test fixtures." ), ) From a2bb2b1c9cc0a9cde0eab5724e99914a956f6dbf Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:48:04 +0200 Subject: [PATCH 06/14] chore(fill): add hotfix to generate_witness for Paris The `witness-filler` tool doesn't recognise Paris: Re-write `fixture.fork` to Merge if its value is Paris and then write it back to Paris afterwards. --- src/pytest_plugins/filler/witness.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index 1ed0178a53f..29f9166c677 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -81,12 +81,23 @@ def generate_witness(fixture: Any) -> None: if not hasattr(fixture, "blocks") or not fixture.blocks: return - result = subprocess.run( - ["witness-filler"], - input=fixture.model_dump_json(by_alias=True), - text=True, - capture_output=True, - ) + # Hotfix: witness-filler expects "Merge" but execution-spec-tests uses "Paris" + original_fork = None + if hasattr(fixture, "fork") and str(fixture.fork) == "Paris": + original_fork = fixture.fork + fixture.fork = "Merge" + + try: + result = subprocess.run( + ["witness-filler"], + input=fixture.model_dump_json(by_alias=True), + text=True, + capture_output=True, + ) + finally: + # Restore original fork value + if original_fork is not None: + fixture.fork = original_fork if result.returncode != 0: raise RuntimeError( From 9be75e81ae54dd5890774a6218afcc1092a6fd20 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 21 Aug 2025 19:59:04 +0200 Subject: [PATCH 07/14] docs: update changelog --- docs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a6d9e2f2df2..ff099700426 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -87,6 +87,7 @@ Users can select any of the artifacts depending on their testing needs for their - 💥 Flag `--flat-output` has been removed due to having been unneeded for an extended period of time ([#2018](https://github.com/ethereum/execution-spec-tests/pull/2018)). - ✨ Add support for `BlockchainEngineSyncFixture` format for tests marked with `pytest.mark.verify_sync` to enable client synchronization testing via `consume sync` command ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)). - ✨ Framework is updated to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) fork markers to enable the filling of BPO tests ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)). +- ✨ Generate and include execution witness data in blockchain fixtures if `--witness` is specified ([#2066](https://github.com/ethereum/execution-spec-tests/pull/2066)). #### `consume` From 4bb601933abe64c8b2b89e1996ab4b743ab58f1f Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 25 Aug 2025 13:39:22 +0200 Subject: [PATCH 08/14] fill: update witness-filler ref as requested by jsign --- src/pytest_plugins/filler/witness.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index 29f9166c677..370f3dc5542 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -47,7 +47,7 @@ def pytest_configure(config): "--git", "https://github.com/kevaundray/reth.git", "--rev", - "8016a8a5736e4427b3d285c82cd39c4ece70f8c4", + "e7efffd314a003018883caf2489c39733fc59388", "witness-filler", ], ) From 9de840191abc387b1221cabc8f5ddf43d59c8189 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 25 Aug 2025 13:48:12 +0200 Subject: [PATCH 09/14] fixtures: change WitnessChunk from dataclass to CamelModel --- src/ethereum_test_fixtures/blockchain.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ethereum_test_fixtures/blockchain.py b/src/ethereum_test_fixtures/blockchain.py index 7ea7c5c9982..ddc82d14c68 100644 --- a/src/ethereum_test_fixtures/blockchain.py +++ b/src/ethereum_test_fixtures/blockchain.py @@ -1,7 +1,6 @@ """BlockchainTest types.""" import json -from dataclasses import dataclass from functools import cached_property from typing import ( Annotated, @@ -403,8 +402,7 @@ def from_withdrawal(cls, w: WithdrawalGeneric) -> "FixtureWithdrawal": return cls(**w.model_dump()) -@dataclass(slots=True) -class WitnessChunk: +class WitnessChunk(CamelModel): """Represents execution witness data for a block.""" state: List[str] From c8d28dae1779bbaa21b8032da8b6d797bb7d11fb Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 25 Aug 2025 13:53:13 +0200 Subject: [PATCH 10/14] fixtures: rename WitnessChunk json parser helper method --- src/ethereum_test_fixtures/blockchain.py | 8 ++++++-- src/pytest_plugins/filler/witness.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ethereum_test_fixtures/blockchain.py b/src/ethereum_test_fixtures/blockchain.py index ddc82d14c68..545dec6b74d 100644 --- a/src/ethereum_test_fixtures/blockchain.py +++ b/src/ethereum_test_fixtures/blockchain.py @@ -411,8 +411,12 @@ class WitnessChunk(CamelModel): headers: List[str] @classmethod - def from_json(cls, s: str) -> List["WitnessChunk"]: - """Parse witness chunks from JSON string.""" + def parse_witness_chunks(cls, s: str) -> List["WitnessChunk"]: + """ + Parse multiple witness chunks from JSON string. + + Returns a list of WitnessChunk instances parsed from the JSON array. + """ return [cls(**obj) for obj in json.loads(s)] diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index 370f3dc5542..453afb2fa48 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -106,7 +106,7 @@ def generate_witness(fixture: Any) -> None: ) try: - witnesses = WitnessChunk.from_json(result.stdout) + witnesses = WitnessChunk.parse_witness_chunks(result.stdout) for i, witness in enumerate(witnesses): if i < len(fixture.blocks) and isinstance(fixture.blocks[i], FixtureBlock): fixture.blocks[i].execution_witness = witness From 14494fdb15591d5fad85e4f6f4e713db702abfd8 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 25 Aug 2025 17:13:14 +0200 Subject: [PATCH 11/14] fill: add a WitnessFillerResult to validate witness-filler output --- src/pytest_plugins/filler/witness.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index 453afb2fa48..f839666742b 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -6,13 +6,20 @@ """ import subprocess -from typing import Any, Callable +from typing import Any, Callable, List import pytest +from ethereum_test_base_types import EthereumTestRootModel from ethereum_test_fixtures.blockchain import FixtureBlock, WitnessChunk +class WitnessFillerResult(EthereumTestRootModel[List[WitnessChunk]]): + """Model that defines the expected result from the `witness-filler` command.""" + + root: List[WitnessChunk] + + def pytest_addoption(parser: pytest.Parser): """Add witness command-line options to pytest.""" witness_group = parser.getgroup("witness", "Arguments for witness functionality") @@ -106,11 +113,13 @@ def generate_witness(fixture: Any) -> None: ) try: - witnesses = WitnessChunk.parse_witness_chunks(result.stdout) + result_model = WitnessFillerResult.model_validate_json(result.stdout) + witnesses = result_model.root + for i, witness in enumerate(witnesses): if i < len(fixture.blocks) and isinstance(fixture.blocks[i], FixtureBlock): fixture.blocks[i].execution_witness = witness - except (ValueError, IndexError, AttributeError) as e: + except Exception as e: raise RuntimeError( f"Failed to parse witness data from witness-filler tool. " f"Output was: {result.stdout[:500]}{'...' if len(result.stdout) > 500 else ''}" From 7ead93ce8a52db60ead8fc9d59ec866bef1e8237 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 28 Aug 2025 16:55:08 +0200 Subject: [PATCH 12/14] refactor(fill): improve `generate_witness` fixture & fork checks 1. Avoid `hasattr` by checking that the provided fixture is of the required pydantic model type (`BlockchainFixture`). 2. Add a clean solution for the `witness-filler` fork naming incompatibility by subclassing `Paris` as `Merge`. --- src/pytest_plugins/filler/witness.py | 42 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index f839666742b..86ab7a1b474 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -6,12 +6,13 @@ """ import subprocess -from typing import Any, Callable, List +from typing import Callable, List import pytest from ethereum_test_base_types import EthereumTestRootModel -from ethereum_test_fixtures.blockchain import FixtureBlock, WitnessChunk +from ethereum_test_fixtures.blockchain import BlockchainFixture, FixtureBlock, WitnessChunk +from ethereum_test_forks import Paris class WitnessFillerResult(EthereumTestRootModel[List[WitnessChunk]]): @@ -20,6 +21,18 @@ class WitnessFillerResult(EthereumTestRootModel[List[WitnessChunk]]): root: List[WitnessChunk] +class Merge(Paris): + """ + Paris fork that serializes as 'Merge' for witness-filler compatibility. + + IMPORTANT: This class MUST be named 'Merge' (not 'MergeForWitness' or similar) + because the class name is used directly in Pydantic serialization, and + witness-filler expects exactly 'Merge' for this fork. + """ + + pass + + def pytest_addoption(parser: pytest.Parser): """Add witness command-line options to pytest.""" witness_group = parser.getgroup("witness", "Arguments for witness functionality") @@ -71,28 +84,30 @@ def pytest_configure(config): @pytest.fixture -def witness_generator(request: pytest.FixtureRequest) -> Callable[[Any], None] | None: +def witness_generator( + request: pytest.FixtureRequest, +) -> Callable[[BlockchainFixture], None] | None: """ Provide a witness generator function if --witness is enabled. Returns: None if witness functionality is disabled. - Callable that generates witness data for a fixture if enabled. + Callable that generates witness data for a BlockchainFixture if enabled. """ if not request.config.getoption("witness"): return None - def generate_witness(fixture: Any) -> None: - """Generate witness data for a fixture using the witness-filler tool.""" - if not hasattr(fixture, "blocks") or not fixture.blocks: - return + def generate_witness(fixture: BlockchainFixture) -> None: + """Generate witness data for a blockchain fixture using the witness-filler tool.""" + if not isinstance(fixture, BlockchainFixture): + return None # Hotfix: witness-filler expects "Merge" but execution-spec-tests uses "Paris" original_fork = None - if hasattr(fixture, "fork") and str(fixture.fork) == "Paris": + if fixture.fork is Paris: original_fork = fixture.fork - fixture.fork = "Merge" + fixture.fork = Merge try: result = subprocess.run( @@ -102,7 +117,6 @@ def generate_witness(fixture: Any) -> None: capture_output=True, ) finally: - # Restore original fork value if original_fork is not None: fixture.fork = original_fork @@ -117,8 +131,10 @@ def generate_witness(fixture: Any) -> None: witnesses = result_model.root for i, witness in enumerate(witnesses): - if i < len(fixture.blocks) and isinstance(fixture.blocks[i], FixtureBlock): - fixture.blocks[i].execution_witness = witness + if i < len(fixture.blocks): + block = fixture.blocks[i] + if isinstance(block, FixtureBlock): + block.execution_witness = witness except Exception as e: raise RuntimeError( f"Failed to parse witness data from witness-filler tool. " From bd5c72a5cf7c435f126acfe21329894d1e426673 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 28 Aug 2025 17:05:45 +0200 Subject: [PATCH 13/14] chore(fixtures): remove unncessary pydantic field alias --- src/ethereum_test_fixtures/blockchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ethereum_test_fixtures/blockchain.py b/src/ethereum_test_fixtures/blockchain.py index 545dec6b74d..61688a4c3dc 100644 --- a/src/ethereum_test_fixtures/blockchain.py +++ b/src/ethereum_test_fixtures/blockchain.py @@ -427,7 +427,7 @@ class FixtureBlockBase(CamelModel): txs: List[FixtureTransaction] = Field(default_factory=list, alias="transactions") ommers: List[FixtureHeader] = Field(default_factory=list, alias="uncleHeaders") withdrawals: List[FixtureWithdrawal] | None = None - execution_witness: WitnessChunk | None = Field(None, alias="executionWitness") + execution_witness: WitnessChunk | None = None @computed_field(alias="blocknumber") # type: ignore[misc] @cached_property From 6c4551a9d6adc59e41ab160385d6bd50e0bac56e Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 28 Aug 2025 21:02:16 +0200 Subject: [PATCH 14/14] chore(fill): exit on error if witness-filler is unavailable Don't build it using cargo install; this must be done by the user. --- src/pytest_plugins/filler/witness.py | 37 +++++++++------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/pytest_plugins/filler/witness.py b/src/pytest_plugins/filler/witness.py index 86ab7a1b474..fc21e3dceeb 100644 --- a/src/pytest_plugins/filler/witness.py +++ b/src/pytest_plugins/filler/witness.py @@ -1,10 +1,11 @@ """ Pytest plugin for witness functionality. -Provides --witness command-line option that installs the witness-filler tool +Provides --witness command-line option that checks for the witness-filler tool in PATH and generates execution witness data for blockchain test fixtures when enabled. """ +import shutil import subprocess from typing import Callable, List @@ -43,8 +44,8 @@ def pytest_addoption(parser: pytest.Parser): dest="witness", default=False, help=( - "Install the witness-filler tool and generate execution witness data for blockchain " - "test fixtures." + "Generate execution witness data for blockchain test fixtures using the " + "witness-filler tool (must be installed separately)." ), ) @@ -53,34 +54,18 @@ def pytest_configure(config): """ Pytest hook called after command line options have been parsed. - If --witness is enabled, installs the witness-filler tool from the specified - git repository. + If --witness is enabled, checks that the witness-filler tool is available in PATH. """ if config.getoption("witness"): - print("🔧 Installing witness-filler tool from kevaundray/reth...") - print(" This may take several minutes for first-time compilation...") - - result = subprocess.run( - [ - "cargo", - "install", - "--git", - "https://github.com/kevaundray/reth.git", - "--rev", - "e7efffd314a003018883caf2489c39733fc59388", - "witness-filler", - ], - ) - - if result.returncode != 0: + # Check if witness-filler binary is available in PATH + if not shutil.which("witness-filler"): pytest.exit( - f"Failed to install witness-filler tool (exit code: {result.returncode}). " - "Please ensure you have a compatible Rust toolchain installed. " - "You may need to update your Rust version to 1.86+ or run without --witness.", + "witness-filler tool not found in PATH. Please build and install witness-filler " + "from https://github.com/kevaundray/reth.git before using --witness flag.\n" + "Example: cargo install --git https://github.com/kevaundray/reth.git " + "witness-filler", 1, ) - else: - print("✅ witness-filler tool installed successfully!") @pytest.fixture