Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
7282b64
feat(specs): Implement EIP-7928: Block-Level Access Lists
fselmo Nov 11, 2025
6de5318
fix(specs): Fix zero value withdrawals BAL tracking (#29)
fselmo Oct 30, 2025
69e182e
fix(specs): static upfront check for create + selfdestruct (#22)
nerolation Oct 30, 2025
ab9cf9f
feat(tests): Implement more EIP-7928 tests
raxhvl Oct 29, 2025
786fdbb
fix(specs): Ensure tracking before first access (#1722)
nerolation Oct 31, 2025
0642045
fix(spec-specs): duplicate storage writes in state tracker (#1743)
fselmo Nov 4, 2025
68e1714
fix(test-specs): validate t8n BAL independent of expectation existenc…
fselmo Nov 13, 2025
5e7249d
feat(specs): EIP-7928 refactoring
nerolation Nov 5, 2025
e87d13a
fix(spec-specs): require and use blockenv for state tracking
fselmo Nov 5, 2025
873710c
refactor(spec-specs): track BAL changes via frames
fselmo Nov 6, 2025
2ec75b2
fix(spec-specs): Mark original addr warm before delegation
fselmo Nov 11, 2025
18472bf
fix(spec-specs): Make sure we account for no changes
fselmo Nov 11, 2025
0f8bc3b
fix(spec-specs): Better tracking for code changes; ensure with BAL test
fselmo Nov 12, 2025
ab4f8f7
fix(spec-specs): Use child frame for create message
fselmo Nov 12, 2025
1c119fb
fix(spec-specs): Normalize transaction before merging to block frame
fselmo Nov 12, 2025
4e8cbcc
fix(spec-specs): Early static check for SSTORE before any reads
fselmo Nov 12, 2025
eb3ac57
fix(spec-specs): Track storage writes more appropriately wrt index
fselmo Nov 13, 2025
e668cc3
fix(spec-specs): Use functions, not methods; fix create revert
fselmo Nov 13, 2025
37edacd
fix(spec-specs): Default code to b"" in tracker, skip empty setting
fselmo Nov 14, 2025
f9c58f3
fix(spec-specs): Fix BAL cross-transaction tracking and nonce dedup
fselmo Nov 14, 2025
54b574f
fix(spec-specs): Move destroy_account before BAL normalization
fselmo Nov 14, 2025
7c39948
fix(spec-specs): Check delegation access gas before reading
fselmo Nov 14, 2025
ad4c8ee
fix(spec-specs): Track code per auth; filter pre at tx frame
fselmo Nov 15, 2025
0bf53c6
fix(spec-specs): Use proper frames for system transactions
fselmo Nov 16, 2025
20321c8
fix(spec-specs): Track address at init collision
fselmo Nov 21, 2025
771ad19
chore(spec-specs): Add Amsterdam docstring; update prepare msg
fselmo Nov 21, 2025
080df16
chore: Add pre-amsterdam BAL tests to doc for tracking
fselmo Nov 21, 2025
325b338
fix(spec-specs): Calculate all gas we can before accessing state
fselmo Nov 24, 2025
09b1524
fix(test-tools): Remove named forks from blobSchedule; turn off BPOs
fselmo Nov 25, 2025
4d36e86
fix(cli): add bal exception for erigon (#1809)
felix314159 Nov 26, 2025
05ca48f
feat(test): Better describe the BAL for selfdestruct revert
fselmo Nov 26, 2025
b5d922e
test(eip7928): add EXTCODECOPY OOG memory expansion BAL test
qu0b Nov 30, 2025
854ee19
refactor(test-tests): parametrize existing test oog case instead
fselmo Dec 1, 2025
355c575
test(eip7928): add cross-block precompile state leak test
qu0b Dec 1, 2025
6606aff
refactor(test-tests): Add BAL expectation to state leak test; fix lint
fselmo Dec 1, 2025
0f9ef2d
feat(test): add SELFDESTRUCT OOG BAL test
qu0b Dec 4, 2025
89232f2
refactor(tests): move selfdestruct bal tests to oog file; add gas bou…
fselmo Dec 4, 2025
09ec902
feat(tests): Port oog create refund test; add BAL >= Amsterdam
fselmo Dec 1, 2025
c40db83
refactor(spec-specs): Refactor state changes and frame hierarchy (#1841)
fselmo Dec 8, 2025
cfa66a2
fix(spec,tests): Change BAL to List[AccountChange] (#1844)
gurukamath Dec 8, 2025
a6745fa
fix(spec-specs): Fix issues after rebasing with forks/osaka
fselmo Dec 8, 2025
2eb8a61
feat(test): add more bal test cases (#1812)
qu0b Dec 8, 2025
f6d51e8
feat(test-tests): BAL test for nested storage write reset same tx (#1…
fselmo Dec 8, 2025
acaca8d
fix(spec-specs): post-exec net-zero filtering post specs refactor
fselmo Dec 9, 2025
7eb798b
feat(test-tests): Expand BAL CALL opcode OOG boundary test cases (#1882)
fselmo Dec 12, 2025
28ef367
feat(spec): update eip7928 to latest rlp specs wrt storage; rename tx…
fselmo Dec 12, 2025
632044a
fix(test-tests): Avoid hard-coding precompile range for lexicographic…
fselmo Dec 12, 2025
35a4bb5
feat(specs): EIP-7928 move bal from payload (#1917)
nerolation Dec 17, 2025
7339217
fix(test-tests): Use `ZeroPaddedHexNumber` instead of `HexNumber` for…
fselmo Dec 30, 2025
bd0f217
refactor(spec-specs): Refactor specs to be more coherent wrt gas acco…
fselmo Dec 30, 2025
368ac87
feat(tests): add more 7928 test descriptions (#1815)
nerolation Dec 31, 2025
ad7be9e
feat(tests): EIP-7928 tests targeting EIP-4788 (#1887)
raxhvl Jan 7, 2026
19a3960
feat(tests): add invalid BAL tests for spurious block_access_index (#…
nerolation Jan 7, 2026
059f38d
feat(tests): EIP-7928 tests targeting EIP-7002 (#1918)
raxhvl Jan 7, 2026
ba6e884
feat(tests): Test extraneous entries for BAL (#1992)
raxhvl Jan 8, 2026
1075f15
refactor(eip7928): refactor net zero filtering in BALs (#1899)
gurukamath Jan 12, 2026
9f2237a
feat(test): OOG and success selfdestruct tests to all precompiles
fselmo Dec 29, 2025
dcca0f4
refactor(test): `Tangerine` -> `TangerineWhistle`; comments on PR #1954
fselmo Dec 30, 2025
6e74073
fix(tool): Fix EvmOneTransitionTool parsing for TangerineWhistle (add…
fselmo Dec 31, 2025
c288a16
feat(test): Extend selfdestruct tests to all Amsterdam gas boundaries
fselmo Jan 6, 2026
c2c020b
refactor(test): fork.supports_protected_txs() instead of direct compa…
fselmo Jan 8, 2026
a21221e
refactor: address comments from PR #1954
fselmo Jan 8, 2026
d7324de
feat(test): Add selfdestruct to system contracts + to self from initcode
fselmo Jan 9, 2026
a0ae1db
feat(test-commands): Allow pytest valid fork markers as params; add u…
fselmo Jan 9, 2026
fe25717
refactor(spec): Remove `check_gas` where unnecessary for instructions
fselmo Jan 12, 2026
aa9f253
fix(test-fill): organize alloc groups by pytest param (enginex)
fselmo Jan 12, 2026
4f6006c
fix(tests): remove bal from block body (#2017)
gurukamath Jan 13, 2026
a378636
feat(spec-tests): Update json_infra tests version (#1939)
fselmo Jan 15, 2026
0313063
chore: clean up based on comments on PR #1719
fselmo Jan 15, 2026
1d11d8d
tests(eip-7928): generalize eip-7934 tests (#2022)
gurukamath Jan 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Test fixtures for use by clients are available for each release on the [Github r

### 📋 Misc

- ✨ Implement EIP-7928 Block-Level Access Lists ([#1719](https://github.com/ethereum/execution-specs/pull/1719)).

### 🧪 Test Cases

- ✨ Add missing fuzzy-compute benchmark configurations for `KECCAK256`, `CODECOPY`, `CALLDATACOPY`, `RETURNDATACOPY`, `MLOAD`, `MSTORE`, `MSTORE8`, `MCOPY`, `LOG*`, `CALLDATASIZE`, `CALLDATALOAD`, and `RETURNDATASIZE` opcodes ([#1956](https://github.com/ethereum/execution-specs/pull/1956)).
Expand Down Expand Up @@ -57,6 +59,7 @@ Test fixtures for use by clients are available for each release on the [Github r
### 📋 Misc

- 🐞 WELDed the EEST tox environments relevant to producing documentation into EELS, and added a tool to cleanly add codespell whitelist entries. ([#1695](https://github.com/ethereum/execution-specs/pull/1659)).
- 🐞 Fix duplicate storage write issues for block access lists EIP-7928 implementation ([#1743](https://github.com/ethereum/execution-specs/pull/1743)).

### 🧪 Test Cases

Expand All @@ -76,6 +79,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ Add tests that EIP-1559 and EIP-2930 typed txs are invalid and void before their fork ([#1754](https://github.com/ethereum/execution-specs/pull/1754)).
- ✨ Add tests for an old validation rule for gas limit above 5000 ([#1731](https://github.com/ethereum/execution-specs/pull/1731)).
- ✨ Add tests for OOG in EXP, LOG and others ([#1686](https://github.com/ethereum/execution-specs/pull/1686)).
- ✨ Make EIP-7934 tests more dynamic and able to handle new header fields added in future forks ([#2022](https://github.com/ethereum/execution-specs/pull/2022)).

## [v5.3.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.3.0) - 2025-10-09

Expand Down
2 changes: 2 additions & 0 deletions packages/testing/src/execution_testing/base_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from .pydantic import CamelModel, EthereumTestBaseModel, EthereumTestRootModel
from .reference_spec import ReferenceSpec
from .serialization import RLPSerializable, SignableRLPSerializable
from .typing_utils import unwrap_annotation

__all__ = (
"AccessList",
Expand Down Expand Up @@ -88,4 +89,5 @@
"to_bytes",
"to_hex",
"to_json",
"unwrap_annotation",
)
33 changes: 33 additions & 0 deletions packages/testing/src/execution_testing/base_types/typing_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Utilities for working with Python type annotations."""

from typing import Any, get_args


def unwrap_annotation(hint: Any) -> Any:
"""
Recursively unwrap Annotated and Union types to find the actual type.

This function is useful for introspecting complex type annotations like:
- `Annotated[int, ...]` -> `int`
- `int | None` -> `int`
- `Annotated[int, ...] | None` -> `int`

Args:
hint: Type annotation to unwrap

Returns:
The unwrapped base type
"""
type_args = get_args(hint)
if not type_args:
# Base case: simple type with no parameters
return hint

# For Union types (including Optional), find the first non-None type
for arg in type_args:
if arg is not type(None):
# Recursively unwrap (handles nested Annotated/Union)
return unwrap_annotation(arg)

# All args were None (shouldn't happen in practice)
return hint
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Mainnet:
Frontier: 0
Homestead: 1150000
DAOFork: 1920000
Tangerine: 2463000
TangerineWhistle: 2463000
SpuriousDragon: 2675000
Byzantium: 4370000
Constantinople: 7280000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@
Frontier: 0
Homestead: 1150000
DAOFork: 1920000
Tangerine: 2463000
TangerineWhistle: 2463000
SpuriousDragon: 2675000
Byzantium: 4370000
Constantinople: 7280000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1208,3 +1208,54 @@ def parametrize_fork(
metafunc.parametrize(
param_names, param_values, scope="function", indirect=indirect
)


def pytest_collection_modifyitems(
config: pytest.Config, items: List[pytest.Item]
) -> None:
"""
Filter tests based on param-level validity markers.

The pytest_generate_tests hook only considers function-level validity markers.
This hook runs after parametrization and can access all markers including
param-level ones, allowing us to properly filter tests based on param-level
valid_from/valid_until markers.
"""
items_to_remove = []

for i, item in enumerate(items):
# Get fork from params if available
params = None
if hasattr(item, "callspec"):
params = item.callspec.params
elif hasattr(item, "params"):
params = item.params

if not params or "fork" not in params or params["fork"] is None:
continue

fork: Fork = params["fork"]

# Get all markers including param-level ones
markers = item.iter_markers()

# Calculate valid fork set from all markers
# If this raises (e.g., duplicate markers from combining function-level
# and param-level), exit immediately with error
try:
valid_fork_set = ValidityMarker.get_test_fork_set_from_markers(
markers
)
except Exception as e:
pytest.exit(
f"Error in test '{item.name}': {e}",
returncode=pytest.ExitCode.USAGE_ERROR,
)

# If the fork is not in the valid set, mark for removal
if fork not in valid_fork_set:
items_to_remove.append(i)

# Remove items in reverse order to maintain indices
for i in reversed(items_to_remove):
del items[i]
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,73 @@ def test_invalid_validity_markers(
errors=1,
)
assert error_string in "\n".join(result.stdout.lines)


# --- Tests for param-level marker errors --- #


param_level_marker_error_test_cases = (
(
"param_level_valid_from_with_function_level_valid_from",
(
"""
import pytest
@pytest.mark.parametrize(
"value",
[
pytest.param(True, marks=pytest.mark.valid_from("Paris")),
],
)
@pytest.mark.valid_from("Berlin")
def test_case(state_test, value):
assert 1
""",
"Too many 'valid_from' markers applied to test",
),
),
(
"param_level_valid_until_with_function_level_valid_until",
(
"""
import pytest
@pytest.mark.parametrize(
"value",
[
pytest.param(True, marks=pytest.mark.valid_until("Cancun")),
],
)
@pytest.mark.valid_until("Prague")
def test_case(state_test, value):
assert 1
""",
"Too many 'valid_until' markers applied to test",
),
),
)


@pytest.mark.parametrize(
"test_function, error_string",
[test_case for _, test_case in param_level_marker_error_test_cases],
ids=[test_id for test_id, _ in param_level_marker_error_test_cases],
)
def test_param_level_marker_errors(
pytester: pytest.Pytester, error_string: str, test_function: str
) -> None:
"""
Test that combining function-level and param-level validity markers
of the same type produces an error.

Unlike function-level errors (caught during test generation), param-level
errors are caught during collection and cause pytest to exit immediately.
"""
pytester.makepyfile(test_function)
pytester.copy_example(
name="src/execution_testing/cli/pytest_commands/pytest_ini_files/pytest-fill.ini"
)
result = pytester.runpytest("-c", "pytest-fill.ini")

# pytest.exit() causes the run to terminate with no test outcomes
assert result.ret != 0, "Expected non-zero exit code"
stdout = "\n".join(result.stdout.lines)
assert error_string in stdout, f"Expected '{error_string}' in output"
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ def test_all_forks({StateTest.pytest_parameter_name()}):
]
expected_skipped = 2 # eels doesn't support Constantinople
expected_passed = (
len(forks_under_test) * len(StateTest.supported_fixture_formats)
len([f for f in forks_under_test if not f.ignore()])
* len(StateTest.supported_fixture_formats)
- expected_skipped
)
stdout = "\n".join(result.stdout.lines)
for test_fork in forks_under_test:
if test_fork.ignore():
continue
for fixture_format in StateTest.supported_fixture_formats:
if isinstance(fixture_format, LabeledFixtureFormat):
fixture_format_label = fixture_format.label
Expand Down
Loading
Loading