fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 2) - #8
Closed
spencer-tb wants to merge 55 commits into
Closed
fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 2)#8spencer-tb wants to merge 55 commits into
spencer-tb wants to merge 55 commits into
Conversation
* refactor(tests): make Alloc implement the PreState protocol
Add a CONSTRUCTION/LIVE/FROZEN lifecycle to the testing-side Alloc so
it directly satisfies ethereum.state.PreState. The first PreState
read transitions the alloc to LIVE and rejects further __setitem__/
__delitem__; apply_diff(BlockDiff) is the sole mutation entry point
in LIVE, and freeze() locks the allocation for assertion use.
Groundwork for the t8n refactor: with Alloc directly usable as a
PreState, fork.BlockState(pre_state=alloc) works without an adapter,
and t8n can drop its bespoke Alloc/Env/Result/Txs JSON types.
* refactor(spec-tools): rewrite T8N to consume testing pydantic types
T8N now wires the testing-package types end-to-end:
* __init__ accepts an optional ``t8n_data`` and otherwise parses the
JSON inputs into testing ``Alloc``/``Environment``/``Transaction``
via ``model_validate``. The CLI ingress is structured so the future
in-process lift only needs to swap the caller, not the constructor.
* ``env.py`` drops the bespoke ``Env`` class in favour of
``build_block_environment(fork, env, pre_state, chain_id, ommers,
state_test)`` plus a handful of ``_resolve_*`` helpers. ``Ommer``
stays as a small dataclass for the pre-PoS reward path.
* ``convert_transaction`` routes through ``TransactionLoad`` rather
than ``rlp.decode_to`` so contract-creating typed txs (Blob /
SetCode with ``to=null``) construct successfully and let
``check_transaction`` raise the canonical
``TransactionTypeContractCreationError``.
* The bespoke ``Result`` / ``Txs`` / ``Alloc`` classes are gone;
``build_result`` and ``get_receipts_from_output`` produce a
``cli_types.Result`` directly, and ``T8N.run()`` emits the
``TransitionToolOutput``-shaped JSON.
* The per-tx ``backup_state`` / ``restore_state`` pattern disappears
with the snapshot-based State: a failed ``process_transaction`` no
longer reaches ``incorporate_tx_into_block``, so ``BlockState`` is
untouched without explicit rollback. After execution the block
diff is applied in-place via ``Alloc.apply_diff``.
JSON ingress smooths two boundary mismatches: ``yParity`` on auth
tuples (duplicated by the testing serializer, rejected by the
validator) and ``secretKey`` left on already-signed txs (rejected by
``InvalidSignaturePrivateKeyError``). Unsigned txs with only a
``secretKey`` are signed post-validation; pre-Spurious-Dragon forks
get ``protected=False`` so the v-value stays in {27, 28}.
* refactor(testing): drive ExecutionSpecsTransitionTool's T8N in-process
The testing-side EELS caller no longer marshals the input through a
JSON ``StringIO`` and back. ``_evaluate`` now hands the testing
``TransitionToolInput`` directly to ``T8N`` via the existing
``t8n_data`` kwarg and assembles the ``TransitionToolOutput`` from
``T8N``'s in-memory ``alloc``/``result``/``body``.
To make the in-process path symmetric with the CLI path, ``T8N``:
* pulls ``blob_params`` from ``t8n_data.blob_params`` (camelCase dump
matches the existing parse), so BPO-fork blob schedules don't have
to be re-serialized through ``--input.blobParams=stdin``;
* refactor(spec-tools): make T8N JSON-free; CLI wrapper in t8n.cli
T8N now takes a testing ``TransitionTool.TransitionToolData`` and
nothing else from the JSON/CLI surface. The CLI plumbing
(``argparse`` namespace, ``--input.*``/``--output.*`` flags, stdin,
file paths, tracer construction from CLI flags) lives in a new
``t8n.cli`` module:
* ``build_t8n_from_cli_options(options, in_file, cache) -> T8N``
reads the JSON inputs (stdin / files), validates each piece into
testing pydantic types, resolves the fork, bundles everything into
a ``TransitionToolData``, builds tracers from the CLI flags, and
hands them to ``T8N``.
* ``write_t8n_outputs(t8n, output, options, out_file)`` serialises
the t8n output + opcode counts per ``--output.*``.
* ``run_t8n_cli(options, out_file, in_file, cache) -> int`` chains
the two for the CLI entry point.
``T8N`` internally calls ``resolve_fork(t8n_data.fork_name,
t8n_data.env)`` to translate the testing-side fork name into a spec
``Hardfork`` + optional ``ByBlockNumber`` criteria (handles both
canonical names and CLI exception aliases like ``Paris``,
``ConstantinopleFix``, ``HomesteadToDaoAt5``). ``T8N.run()`` returns
the ``TransitionToolOutput`` directly — no more out_file writing.
Callers updated:
* ``evm_tools.__init__.main`` now calls ``run_t8n_cli``.
* ``statetest`` and ``tests/json_loader`` use
``build_t8n_from_cli_options``.
* ``tests/evm_tools/test_count_opcodes`` uses ``run_t8n_cli``.
* ``ExecutionSpecsTransitionTool._evaluate`` hands its
``transition_tool_data`` straight to ``T8N`` — no argparse dance.
The CLI ↔ testing fork-name mapping is title-case + a one-entry
override for ``DAOFork`` (testing's irregular capitalisation).
``state_reward=None`` is resolved to the fork's ``BLOCK_REWARD`` (or
``-1`` for PoS forks) in the wrapper before constructing
``TransitionToolData.reward: int``.
* refactor(testing): drop duplicate State/trie in test_types
``Alloc`` used to maintain its own parallel ``State`` dataclass plus
``set_account``/``set_storage``/``state_root``/``storage_root`` free
functions to compute its root. Now that ``Alloc`` implements the
``PreState`` protocol, ``state_root()`` can route through
``_materialize_state()`` and ``ethereum.state.state_root``, so the
in-package trie machinery is redundant.
* ``Alloc.state_root()`` reduced to a one-liner over
``spec_state.state_root(self._materialize_state())``. The materialize
call doesn't transition the alloc out of ``CONSTRUCTION``, so existing
callers that compute a genesis root and then keep mutating the alloc
are unaffected.
* Local ``State`` dataclass + trie helpers (``set_account``,
``set_storage``, ``storage_root``, ``state_root``) removed; they had
no consumers outside the deleted ``Alloc.state_root`` body.
* ``test_types/trie.py`` deleted along with its now-tautological
``test_eest_trie_keccak256_matches_eels`` keccak-dispatch check
(the module just re-exported ``ethereum.crypto.hash.keccak256``).
* refactor(spec-tools): final clean up
* refactor(spec-tools): post review update
* fix(spec-tools): load txs that carry no signature material
The CLI parser builds testing `Transaction` objects and RLP-encodes
them for the returned body. A tx with neither `v`/`r`/`s` nor
`secretKey` made `Transaction.rlp` auto-sign a key-less tx and die on
`assert signing_key is not None`, failing every json_loader case that
replays such a fixture (136 in CI, all `test_bad_v_r_s`).
Default the missing signature components to zero in
`_normalize_tx_json`, matching the previous parser
(`t8n_types.Txs.parse_json_tx`): the tx then executes with an invalid
signature and the fork rejects it, which is exactly what these
fixtures assert via `expectException`. Verified against locally
filled `bad_v_r_s` fixtures for Homestead and Prague.
* chore: fix-up docstring
* chore: fix-up docstring formatting for ruff
* chore: just one more docstring fix
* refactor(test-clis): Refactor LazyAlloc
* refactor(test-clis): Update LazyAlloc
* refactor(test-clis): Refactor LazyAlloc
* post review updates
---------
Co-authored-by: danceratopz <danceratopz@gmail.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
…um#3226) Add regression tests verifying that reaching the maximum account nonce (2**64-1) during execution is valid: per EIP-2681 only a transaction whose nonce is 2**64-1 is invalid, not one that merely increments an account to that value. Ported from ipsilon/evmone#1608: * top-level CALL from a sender at nonce 2**64-2 * top-level CREATE from a sender at nonce 2**64-2 (created-account nonce fork-gated per EIP-161) * EIP-7702 self-sponsored set-code tx whose authorization drives the sender to 2**64-1
…thereum#3220) Co-authored-by: 蔡佳誠 Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>
…thereum#3221) Co-authored-by: 蔡佳誠 Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>
ethereum#3182) Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
…n multi-tx blocks (ethereum#3232) A transaction that out-of-gases on an EIP-2780/EIP-8037 top-frame charge is included in the block but must produce a failed receipt. All existing top-frame OOG tests place the failing transaction alone in a block, so a client that derives the receipt status from stale shared per-block state still passes them: the stale value in a fresh block happens to be "failed". Add a blockchain test to test_top_frame_charges.py that sandwiches the top-frame failure between two successful transactions, making the status byte load-bearing in the header receiptsRoot. Parametrized over the three top-frame charge classes: contract-creation NEW_ACCOUNT state gas, value-to-empty NEW_ACCOUNT state gas, and delegated-recipient COLD_ACCOUNT_ACCESS regular gas. Every receipt is pinned explicitly via expected_receipt (status, cumulative gas, and gas_used on the failing tx). Catches the nimbus-eth1 1f8dd2122 regression that receipted top-frame failures with the previous transaction's status and rejected canonical finalized blocks on glamsterdam-devnet-7 (receiptRoot mismatch). Claude-Session: https://claude.ai/code/session_01GpkqKnXjpdXGJ4ChNGsxEY Co-authored-by: Guruprasad Kamath <guru241987@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…or requests verification (ethereum#3235)
…st (ethereum#3233) Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
…thereum#3218) * initial commit * fix(tests): point module-level ethereum.state imports at state_mpt The State class and its helpers moved to ethereum.state_mpt, but two test files import the module itself rather than names from it, which the import rewrite missed: test_optimized_state.py aliases it for state_root calls (caught by mypy in CI) and load_vm_tests.py returns it as the fallback fork state module (hidden behind an Any return). * refactor(t8n): resolve each fork's state provider through the fork The evm tools hardcoded the MPT-backed provider: alloc loading built ethereum.state_mpt.State directly, and t8n applied diffs, serialized allocs, and backed up state by reaching into MPT trie internals. Resolve the provider through the fork instead: every fork's fork module imports its State class, so ForkLoad.state_provider derives the provider module from it. Alloc loading, diff application, serialization, and backup/restore all go through that module. The provider gains the uniform helpers this needs: copy_state, restore_state, all_accounts, and account_storage. With this, a fork whose commitment is not the Merkle Patricia Trie works with the tooling by supplying a provider with the same module surface as ethereum.state_mpt. * guru's comments * remove global _EMPTY_DIFF constant and just use `default` * style: ruff format test_alloc_prestate * minor fixes --------- Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
…um#3212) `daemon.py` defined `_UnixSocketHttpServer` by subclassing `socketserver.UnixStreamServer`, which does not exist on Windows. Since `ethereum_spec_tools.evm_tools` imports this module at load time, importing the tooling (and therefore collecting the test suite) crashed on Windows with `AttributeError`. Select the base class per platform so the module stays importable everywhere, and reject running the daemon on Windows with a clear error, as it inherently relies on Unix domain sockets. Add a regression test for the platform guard. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…es (ethereum#3209) The `eest` commands print Unicode characters (box drawing in `info`, emoji in `clean` and `make`) via `click.echo`. On a Windows console using a legacy code page such as `cp1252`, these characters cannot be encoded and the command aborts with `UnicodeEncodeError`. Reconfigure `sys.stdout`/`sys.stderr` to UTF-8 in the `eest` group callback, guarded so streams that do not support reconfiguration (for example captured output under tests) are left untouched. Add regression tests covering a legacy-encoded stdout. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…eum#3190) Without parentheses, `:=` binds after `>`, so failing_tx_count became a bool and the multi-failure check never fired.
…3189) Avoid float64 (53-bit mantissa) precision loss when scaling base_fee_per_gas by 8/7 for values beyond 2^53.
…dam EIP-8037/8038 tests (ethereum#3169) Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
* init ssz-aware testing:wq * add progressive support * add scaffolding * refactor * fix pypy problem * nits * add ssz none functionality Claude-Session: https://claude.ai/code/session_01LxVkSo6sGs8bsNz4yD8KiJ * resolve reviews
…thereum#3249) Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
…thereum#3239) * Add system-address zero-tip BAL fixture * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * Update tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py Co-authored-by: Mario Vega <marioevz@gmail.com> * fix(tests): apply ruff format to system-address coinbase BAL test --------- Co-authored-by: Mario Vega <marioevz@gmail.com>
…ransfer cost (ethereum#3214) Align the EIP-2780 implementation with the changes proposed in ethereum/EIPs#11997
…thereum#3215) Co-authored-by: spencer <spencer.tb@ethereum.org>
Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
12 tasks
* feat: implement deployed account verification * refactor: add account verification to tests * refactor: update alloc to include the pre method * refactor: verify account flag name * refactor: clean up docstring * refactor: chunk-wise early raise in deployed accounts verification * refactor: move account verification to a helper, session-scope dedup state * refactor(test-execute): verify_full_accounts internal of pre --------- Co-authored-by: marioevz <marioevz@gmail.com>
…k-derived thresholds
… and warm stipend boundary
…rmth ported tests
…ets and boundaries
…hance-ported-test
spencer-tb
force-pushed
the
ported-static-enhance-pt2
branch
from
July 30, 2026 07:54
61f83f4 to
bac43cc
Compare
Author
|
Superseded by ethereum#3264 (rebased onto forks/amsterdam after ethereum#3215 merged). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to ethereum#3215 (Part 1): un-skips the remaining 130 entries, emptying the Amsterdam ported-static skip list.