Skip to content

Align EEST validation mappings and fixture coverage - #12717

Draft
flcl42 wants to merge 6 commits into
glamsterdam-devnet-8from
glam-nonce-overflow-mapping
Draft

Align EEST validation mappings and fixture coverage#12717
flcl42 wants to merge 6 commits into
glamsterdam-devnet-8from
glam-nonce-overflow-mapping

Conversation

@flcl42

@flcl42 flcl42 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Map the legacy EEST TransactionException.NONCE_TOO_BIG and current TransactionException.NONCE_IS_MAX max-nonce cases to Nethermind's NonceTooHigh validation error in transaction and blockchain fixtures.
  • Reject transaction nonce fields wider than 64 bits during RLP deserialization with a distinct NonceOverflow error, and map EEST TransactionException.NONCE_OVERFLOW to that error instead of aliasing it to the max-nonce case.
  • Reject non-canonical deposit-event ABI offsets in ExecutionRequestsProcessor, so the EEST swapped-offset deposit fixture receives the intended DepositsInvalid validation error at the consensus boundary.
  • Keep requests-hash and block-access-list-hash diagnostics strict; no client-specific aliases mask those failures in the EEST mapper.
  • Pause automatic tests-zkevm@v0.6.2 execution until a fixture release compatible with the current Amsterdam gas schedule is available. The reusable workflow and manual dispatch support remain available.

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Notes on testing

  • nonce-boundary transaction fixtures: 98/98, including NONCE_TOO_BIG, NONCE_IS_MAX, and NONCE_OVERFLOW
  • transaction fixtures: 180/180 on the pinned Glamsterdam set
  • max-nonce blockchain cases: 23/23
  • swapped-deposit-offset engine cases: 3/3 with the default configuration and 3/3 with Flat DB sequential execution
  • TxDecoderTests: 120/120, including 9-byte and 33-byte nonce-overflow regressions
  • ExecutionProcessorTests: 4/4, including the non-canonical deposit-offset regression
  • EthereumTests.slnx builds in Release with warnings treated as errors and zero warnings or errors
  • workflow YAML parses successfully

Documentation

Requires documentation update

  • Yes
  • No

Requires explanation in Release Notes

  • Yes
  • No

Remarks

EEST distinguishes an exactly-maximum nonce (NONCE_IS_MAX, with the older fixture spelling NONCE_TOO_BIG) from a nonce that does not fit in 64 bits (NONCE_OVERFLOW). Nethermind now returns NonceTooHigh only for the former and rejects the latter at RLP deserialization with NonceOverflow.

The EEST test_invalid_layout_with_swapped_decodable_offsets fixture uses valid field lengths but non-canonical ABI offsets. The previous mapper aliases accepted downstream InvalidRequestsHash or BAL-hash diagnostics as INVALID_DEPOSIT_EVENT_LAYOUT, which could hide a real consensus defect. The client now rejects those offsets directly and reports DepositsInvalid: Invalid deposit event layout.

tests-zkevm@v0.6.2 was published before the current Amsterdam gas schedule. Its fixture corpus contains 25,994 Amsterdam cases and 110 Amsterdam-transition cases; 15,504 now produce a different stateless success result. There is no compatible official release yet, so continuing to run this corpus automatically reports expected fixture drift rather than current client correctness.

@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Claude finished @flcl42's task in 4m 3s —— View job


Review: Map nonce overflow transaction test errors

  • Gather context (diff, base branch origin/glamsterdam-devnet-8)
  • Verify EEST NONCE_OVERFLOW token and Nethermind error string
  • Cross-check blockchain-test mapping for consistency
  • Check matching semantics / edge cases
  • Post review

Verdict

The fix is correct and minimal. One Medium follow-up: the change closes the gap on the transaction-test side while leaving the mirror-image gap open on the blockchain-test side.

What I verified

The mapping is right. NonceCapTxValidator (TxValidator.cs:415-422, EIP-2681) returns TxErrorMessages.NonceTooHigh = "NonceTooHigh: Nonce exceeds max nonce", so the "NonceTooHigh" fragment substring-matches case-insensitively at TransactionTestBase.cs:90.

All 15 fork variants are genuinely covered. NonceCapTxValidator.Instance is registered for every tx type (TxValidator.cs:27, 39, 50, 62, 76) and is not gated on releaseSpec, so the error surfaces uniformly across forks — consistent with the reported 15/15.

Zero regression risk. The change adds a new dictionary key. ExceptionMatches looks up by exact token, so no other fixture token's matching behavior can change. Test-harness code only — no production or hot path touched. TransactionTestBase isn't shipped in the runtime assemblies.

Regression coverage is real. txTest is a first-class test type in run-nethtest.yml, so the EEST fixture standing in for a hand-written unit test is defensible here — the harness's only meaningful input is the external fixture. No objection to the "no test written" box.

Findings

Medium — token coverage diverges between the two mapping tables

After this change:

Token TransactionTestBase BlockchainTestBase
NONCE_OVERFLOW ✅ (this PR)
NONCE_IS_MAX ✅ (line 581)

Nethermind cannot distinguish the two: transaction.Nonce < ulong.MaxValue rejects both nonce == 2^64-1 (NONCE_IS_MAX) and nonce > 2^64-1 (NONCE_OVERFLOW) with the identical message. Each table therefore spuriously fails whichever token it doesn't list — exactly the bug this PR fixes, still latent on the other side. Since EEST typically emits blockchain-test and transaction-test formats from the same source test, a NONCE_OVERFLOW blockchain fixture in the same release is plausibly failing already (or masked by the BAL-mismatch escape hatch at BlockchainTestBase.cs:562, which would be worse — a silent pass).

Two lines close the class of bug rather than one instance:

  • ["TransactionException.NONCE_IS_MAX"] = ["NonceTooHigh"], in TransactionTestBase
  • ("TransactionException.NONCE_OVERFLOW", "NonceTooHigh"), in BlockchainTestBase

This is squarely within the PR's own stated goal ("Align transaction-test exception handling with the existing blockchain-test mapping"). Worth running blockTest on the same EEST release to confirm the blockchain side's current state. Fix this →

Low — mirrored tables are the root cause (follow-up, not blocking)

The comment at TransactionTestBase.cs:106-111 says the table "Mirrors BlockchainTestBase's mapping" — a promise the code structure can't enforce, and the divergence above is the second time it has been broken. A single shared token→fragment table would make this class of failure impossible. Out of scope for a one-line bug fix per AGENTS.md ("keep changes minimal"), but worth a tracking issue.

Low — hardcoded "NonceTooHigh" literal

nameof(TxErrorMessages.NonceTooHigh) would yield the same string and survive a rename of the message constant. The other 12 entries all use free-text fragments though, so the literal is the locally consistent choice. Take it or leave it.

Low (informational) — the -1 in the diff is a trailing blank line

The deletion is the extra blank line at EOF, not a removed mapping. Harmless, matches what dotnet format whitespace produces, and the file still ends with a newline. Flagging only so reviewers don't go looking for a dropped entry.

Not applicable

  • Security: none — test-harness string matching over trusted fixture data.
  • Performance: none — static dictionary, one extra entry, initialized once.
  • Consensus correctness: unaffected. The validator behavior was already correct; only the test harness's interpretation of the fixture token changed. Notably, the pre-existing failure mode was the safe direction — a correctly-rejected transaction reported as a fixture failure, never the reverse.

Summary: 0 Critical, 0 High, 1 Medium, 3 Low. The change is correct as written; I'd fold in the two symmetric mapping entries before merge since they're one line each and address the same latent defect.
· Branch glam-nonce-overflow-mapping

["TransactionException.TYPE_3_TX_INVALID_BLOB_VERSIONED_HASH"] = ["InvalidBlobVersionedHashVersion"],
["TransactionException.TYPE_3_TX_CONTRACT_CREATION"] = ["blob transaction of type create"],
["TransactionException.INSUFFICIENT_MAX_FEE_PER_BLOB_GAS"] = ["max fee per blob gas less than block blob gas fee"],
["TransactionException.NONCE_OVERFLOW"] = ["NonceTooHigh"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium — the two mapping tables now diverge in opposite directions.

The mapping itself is correct: NonceCapTxValidator (TxValidator.cs:415-422, EIP-2681) returns TxErrorMessages.NonceTooHigh = "NonceTooHigh: Nonce exceeds max nonce", so the "NonceTooHigh" fragment substring-matches at line 90.

But after this change:

  • TransactionTestBase knows NONCE_OVERFLOW, not NONCE_IS_MAX
  • BlockchainTestBase.cs:581 knows NONCE_IS_MAX, not NONCE_OVERFLOW

Nethermind cannot distinguish the two cases — transaction.Nonce < ulong.MaxValue rejects both nonce == 2^64-1 (NONCE_IS_MAX) and nonce > 2^64-1 (NONCE_OVERFLOW) with the identical message. So each table will spuriously fail whichever of the two tokens it doesn't list. EEST commonly emits both blockchain-test and transaction-test formats from the same source test, so a NONCE_OVERFLOW blockchain fixture in the same release is likely already failing (or being masked by the BAL-mismatch escape hatch at BlockchainTestBase.cs:562).

Listing both tokens on both sides costs one line each and closes the class of bug rather than one instance:

Suggested change
["TransactionException.NONCE_OVERFLOW"] = ["NonceTooHigh"],
["TransactionException.NONCE_OVERFLOW"] = ["NonceTooHigh"],
["TransactionException.NONCE_IS_MAX"] = ["NonceTooHigh"],

...plus ("TransactionException.NONCE_OVERFLOW", "NonceTooHigh"), next to BlockchainTestBase.cs:581.

Worth also running blockTest against the same EEST release to confirm whether the blockchain side is currently failing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 4b0b3a1. I removed the broad INVALID_DEPOSIT_EVENT_LAYOUT aliases for InvalidRequestsHash and InvalidBlockLevelAccessListHash. The swapped-offset fixture exposed a real consensus-side gap: the deposit ABI decoder validated field sizes but accepted non-canonical offsets. ExecutionRequestsProcessor now enforces fixed EIP-6110 offsets (160, 256, 320, 384, 512), with a focused regression test; the mapper accepts only the canonical DepositsInvalid diagnostic. Release ExecutionProcessorTests pass 4/4.

@flcl42 flcl42 changed the title Map nonce overflow transaction test errors Align EEST validation error mappings Aug 6, 2026
@flcl42 flcl42 changed the title Align EEST validation error mappings Align EEST validation mappings and fixture coverage Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant