Skip to content

fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 2) - #8

Closed
spencer-tb wants to merge 55 commits into
marioevz:ported-static-enhance-skillfrom
spencer-tb:ported-static-enhance-pt2
Closed

fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 2)#8
spencer-tb wants to merge 55 commits into
marioevz:ported-static-enhance-skillfrom
spencer-tb:ported-static-enhance-pt2

Conversation

@spencer-tb

Copy link
Copy Markdown

Follow-up to ethereum#3215 (Part 1): un-skips the remaining 130 entries, emptying the Amsterdam ported-static skip list.

gurukamath and others added 30 commits July 23, 2026 17:34
* 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>
…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>
…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#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
Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
LouisTsai-Csie and others added 25 commits July 29, 2026 15:59
* 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>
@spencer-tb
spencer-tb force-pushed the ported-static-enhance-pt2 branch from 61f83f4 to bac43cc Compare July 30, 2026 07:54
@spencer-tb

Copy link
Copy Markdown
Author

Superseded by ethereum#3264 (rebased onto forks/amsterdam after ethereum#3215 merged).

@spencer-tb spencer-tb closed this Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.