From c353bd5eb95aadd1c27f3da3293209a6a6e22098 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Thu, 26 Jun 2025 19:00:27 +0200 Subject: [PATCH 1/7] minor fix --- src/ethereum_spec_tools/evm_tools/t8n/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ethereum_spec_tools/evm_tools/t8n/env.py b/src/ethereum_spec_tools/evm_tools/t8n/env.py index 9a9a0bf7d4..3a324f2e17 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/env.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/env.py @@ -298,7 +298,7 @@ def read_block_hashes(self, data: Any, t8n: "T8N") -> None: clean_block_hashes: Dict[int, Hash32] = {} if "blockHashes" in data: for key, value in data["blockHashes"].items(): - int_key = int(key, 16) + int_key = int(key) clean_block_hashes[int_key] = Hash32(hex_to_bytes(value)) # Store a maximum of 256 block hashes. From 7dcc52d1139af9b4b93fc8583735d879573fc259 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Tue, 17 Jun 2025 16:36:13 +0200 Subject: [PATCH 2/7] update dependencies --- pytest-eest.ini | 23 +++++++++++++++++++++++ setup.cfg | 6 ++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 pytest-eest.ini diff --git a/pytest-eest.ini b/pytest-eest.ini new file mode 100644 index 0000000000..d251b60a2b --- /dev/null +++ b/pytest-eest.ini @@ -0,0 +1,23 @@ +[pytest] +console_output_style = count +minversion = 7.0 +python_files = *.py +testpaths = tests/ +markers = + slow + pre_alloc_modify + ported_from +addopts = + -p pytest_plugins.concurrency + -p pytest_plugins.filler.pre_alloc + -p pytest_plugins.solc.solc + -p pytest_plugins.filler.filler + -p pytest_plugins.filler.static_filler + -p pytest_plugins.shared.execute_fill + -p pytest_plugins.forks.forks + -p pytest_plugins.help.help + --tb short + --ignore tests/cancun/eip4844_blobs/point_evaluation_vectors/ +# these customizations require the pytest-custom-report plugin +report_passed_verbose = FILLED +report_xpassed_verbose = XFILLED diff --git a/setup.cfg b/setup.cfg index ed0a5ed22b..6927557fe3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -136,6 +136,8 @@ install_requires = ethereum-types>=0.2.1,<0.3 ethereum-rlp>=0.1.4,<0.2 cryptography>=45.0.1,<46 + ethereum-execution-spec-tests @ git+https://github.com/ethereum/execution-spec-tests@dd83fba10492e6f63453b1a35608900b3aee1a87 + ethereum-spec-evm-resolver @ git+https://github.com/petertdavies/ethereum-spec-evm-resolver [options.package_data] ethereum = @@ -172,11 +174,11 @@ docc.plugins.html = [options.extras_require] test = - pytest>=7.4.0,<8 + pytest>=8,<9 pytest-cov>=4.1.0,<5 pytest-xdist>=3.3.1,<4 GitPython>=3.1.0,<3.2 - filelock>=3.12.3,<3.13 + filelock>=3.15.1,<4 requests requests-cache>=1.2.1,<2 From b9238c16357d969d7060bd630af942b213c27d97 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Thu, 12 Jun 2025 11:59:56 +0200 Subject: [PATCH 3/7] add fill to the entry points --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 6927557fe3..9b7c3f3b4e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -160,6 +160,7 @@ console_scripts = ethereum-spec-new-fork = ethereum_spec_tools.new_fork:main ethereum-spec-patch = ethereum_spec_tools.patch_tool:main ethereum-spec-evm = ethereum_spec_tools.evm_tools:main + ethereum-spec-fill = cli.pytest_commands.fill:fill docc.plugins = ethereum_spec_tools.docc.discover = ethereum_spec_tools.docc:EthereumDiscover From aae34bbd30d0c829b04dc4a484a4ec5535b9f821 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Wed, 18 Jun 2025 17:10:14 +0200 Subject: [PATCH 4/7] add eest tests --- .gitmodules | 3 +++ eest_tests | 1 + 2 files changed, 4 insertions(+) create mode 160000 eest_tests diff --git a/.gitmodules b/.gitmodules index e69de29bb2..012bfa5074 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "eest_tests"] + path = eest_tests + url = https://github.com/ethereum/execution-spec-tests diff --git a/eest_tests b/eest_tests new file mode 160000 index 0000000000..dd83fba104 --- /dev/null +++ b/eest_tests @@ -0,0 +1 @@ +Subproject commit dd83fba10492e6f63453b1a35608900b3aee1a87 From 386eb17de395d29147d25a45dc41628f99eb2387 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Fri, 27 Jun 2025 10:26:10 +0200 Subject: [PATCH 5/7] run eest tests in py3 --- .github/workflows/test.yaml | 2 +- .gitignore | 2 ++ tox.ini | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 66815e9a01..2faee660aa 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -43,7 +43,7 @@ jobs: - name: Run Tox (CPython) if: "${{ !startsWith(matrix.py, 'pypy') }}" - run: tox -e static,optimized,py3 + run: tox -e static,py3_eest,optimized,py3 - name: Run Tox (PyPy) if: "${{ startsWith(matrix.py, 'pypy') }}" diff --git a/.gitignore b/.gitignore index 144dc04c86..fd08eaf32b 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,5 @@ pip-delete-this-directory.txt tests/execution-spec-generated-tests tests/fixtures tests/t8n_testdata + +fixtures diff --git a/tox.ini b/tox.ini index da16c8a3a6..746c03bf6f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] min_version = 2.0 -envlist = py3,pypy3,static +envlist = py3,pypy3,py3_eest,static [testenv:static] extras = @@ -30,7 +30,23 @@ commands = --no-cov-on-fail \ --cov-branch \ --ignore-glob='tests/fixtures/*' \ - --basetemp="{temp_dir}/pytest" + --basetemp="{temp_dir}/pytest" \ + tests + +[testenv:py3_eest] +extras = + test +setenv = + COVERAGE_FILE = {toxworkdir}/.coverage +commands = + pytest \ + -c pytest-eest.ini \ + -m "not slow and not zkevm" \ + -n auto --maxprocesses 10 \ + --basetemp="{temp_dir}/pytest" \ + --clean \ + eest_tests/tests + [testenv:pypy3] extras = @@ -45,7 +61,9 @@ commands = -m "not slow" \ -n auto --maxprocesses 5 \ --ignore-glob='tests/fixtures/*' \ + --ignore-glob='eest_tests/*' \ --basetemp="{temp_dir}/pytest" + tests [testenv:optimized] extras = @@ -59,8 +77,10 @@ commands = -n auto --maxprocesses 5 \ --ignore-glob='tests/fixtures/*' \ --ignore-glob='tests/test_t8n.py' \ + --ignore-glob='eest_tests/*' \ --basetemp="{temp_dir}/pytest" \ --optimized + tests [testenv:doc] basepython = python3 From ed3dae9226cce858c4495cbbcacef27e4b4fa98a Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Tue, 17 Jun 2025 02:52:08 +0200 Subject: [PATCH 6/7] create EELS TransitionTool subclass --- conftest.py | 8 ++ .../evm_tools/t8n/transition_tool.py | 128 ++++++++++++++++++ whitelist.txt | 5 +- 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 conftest.py create mode 100644 src/ethereum_spec_tools/evm_tools/t8n/transition_tool.py diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000000..190ce053af --- /dev/null +++ b/conftest.py @@ -0,0 +1,8 @@ +import pytest +from ethereum_spec_tools.evm_tools.t8n.transition_tool import EELST8N +from ethereum_clis import TransitionTool + + +@pytest.hookimpl(tryfirst=True) +def pytest_configure(config): + TransitionTool.set_default_tool(EELST8N) diff --git a/src/ethereum_spec_tools/evm_tools/t8n/transition_tool.py b/src/ethereum_spec_tools/evm_tools/t8n/transition_tool.py new file mode 100644 index 0000000000..c84503cfb0 --- /dev/null +++ b/src/ethereum_spec_tools/evm_tools/t8n/transition_tool.py @@ -0,0 +1,128 @@ +""" +Implementation of the EELS T8N for execution-spec-tests. +""" + +import json +import tempfile +from io import StringIO +from typing import Any, Dict, Optional + +from ethereum_clis.clis.execution_specs import ExecutionSpecsExceptionMapper +from ethereum_clis.file_utils import dump_files_to_directory +from ethereum_clis.transition_tool import TransitionTool, model_dump_config +from ethereum_clis.types import TransitionToolOutput +from ethereum_test_forks import Fork + +import ethereum + +from .. import create_parser +from ..utils import get_supported_forks +from . import T8N + + +class EELST8N(TransitionTool): + """Implementation of the EELS T8N for execution-spec-tests.""" + + def __init__( + self, + *, + trace: bool = False, + ): + """Initialize the EELS Transition Tool interface.""" + self.exception_mapper = ExecutionSpecsExceptionMapper() + self.trace = trace + self._info_metadata: Optional[Dict[str, Any]] = {} + + def version(self) -> str: + """Version of the t8n tool.""" + return ethereum.__version__ + + def is_fork_supported(self, fork: Fork) -> bool: + """Return True if the fork is supported by the tool.""" + return fork.transition_tool_name() in get_supported_forks() + + def evaluate( + self, + *, + transition_tool_data: TransitionTool.TransitionToolData, + debug_output_path: str = "", + slow_request: bool = False, # noqa: U100, F841 + ) -> TransitionToolOutput: + """ + Evaluate using the EELS T8N entry point. + """ + request_data = transition_tool_data.get_request_data() + request_data_json = request_data.model_dump( + mode="json", **model_dump_config + ) + + t8n_args = [ + "t8n", + "--input.alloc=stdin", + "--input.env=stdin", + "--input.txs=stdin", + "--output.result=stdout", + "--output.body=stdout", + "--output.alloc=stdout", + f"--state.fork={request_data_json['state']['fork']}", + f"--state.chainid={request_data_json['state']['chainid']}", + f"--state.reward={request_data_json['state']['reward']}", + ] + + if transition_tool_data.state_test: + t8n_args.append("--state-test") + + temp_dir = tempfile.TemporaryDirectory() + if self.trace: + t8n_args.extend( + [ + "--trace", + "--trace.memory", + "--trace.returndata", + f"--output.basedir={temp_dir.name}", + ] + ) + + parser = create_parser() + t8n_options = parser.parse_args(t8n_args) + + out_stream = StringIO() + + in_stream = StringIO(json.dumps(request_data_json["input"])) + + t8n = T8N(t8n_options, out_stream, in_stream) + t8n.run() + + output_dict = json.loads(out_stream.getvalue()) + output: TransitionToolOutput = TransitionToolOutput.model_validate( + output_dict, context={"exception_mapper": self.exception_mapper} + ) + + if debug_output_path: + dump_files_to_directory( + debug_output_path, + { + "input/alloc.json": request_data.input.alloc, + "input/env.json": request_data.input.env, + "input/txs.json": [ + tx.model_dump(mode="json", **model_dump_config) + for tx in request_data.input.txs + ], + }, + ) + + dump_files_to_directory( + debug_output_path, + { + "output/alloc.json": output.alloc, + "output/result.json": output.result, + }, + ) + + if self.trace: + self.collect_traces( + output.result.receipts, temp_dir, debug_output_path + ) + temp_dir.cleanup() + + return output diff --git a/whitelist.txt b/whitelist.txt index 62cef423cc..7edf451b1b 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -494,4 +494,7 @@ SECP256R1P secp256r1 sig -CLZ \ No newline at end of file +CLZ +EELST8N +clis +T8 \ No newline at end of file From 11e829fcfb0c8c52234774119a63f2f241dbc486 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Wed, 9 Jul 2025 11:25:47 +0200 Subject: [PATCH 7/7] update clz gas cost --- src/ethereum/osaka/vm/instructions/bitwise.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ethereum/osaka/vm/instructions/bitwise.py b/src/ethereum/osaka/vm/instructions/bitwise.py index 019827e73a..cc96b9da0e 100644 --- a/src/ethereum/osaka/vm/instructions/bitwise.py +++ b/src/ethereum/osaka/vm/instructions/bitwise.py @@ -15,7 +15,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas from ..stack import pop, push @@ -256,7 +256,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GAS_LOW) # OPERATION bit_length = U256(x.bit_length())