Support all zkevm tests via both blockchain and engine#12177
Merged
Conversation
WitnessCapturingWorldStateProxy implemented only the explicit IWorldState methods, leaving IsNonZeroAccount, IsStorageEmpty, HasCode, GetNonce, and IsDelegatedCode to fall through to the default interface implementations. Those defaults route via TryGetAccount and see only the committed AccountStruct, while the real WorldState overrides them to consult the in-flight persistent storage provider. The mismatch broke EIP-7610 checks on SELFDESTRUCT-then-CREATE within a single block, causing the Pyspec test_recreate fixtures on Paris and Shanghai to fail with a header gas-used mismatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restore codeHash-first lookup and the parallel-BAL comment. The proxy already captures the address via GetCodeHash(Address) earlier in InternalGetCodeInfo, so the swap is not required for witness capture. Also drop the verbose comment on the new default-method forwarders and update the misleading note on GetCode(in ValueHash256). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spec MAX_REQUEST_BODY_SIZE per execution-apis#764 is 16 MiB; revert the undocumented bump to 64 MiB. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Witness owns ArrayPoolList buffers. On the JSON-RPC success path the result is wrapped in ResultWrapper -> JsonRpcSuccessResponse, whose Dispose() calls Result.TryDispose(). Implementing IDisposable here routes that into Witness.Dispose() so the pool buffers are returned instead of GC'd. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When two engine_newPayloadWithWitness calls land for the same blockHash, ArmCapture cancels the first TCS. The first caller's await captureTask then throws OperationCanceledException. The block itself executed successfully, so return VALID with a null witness rather than letting the cancellation propagate as a 500. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The INVALID_BLOCK_HASH constant and its SSZ byte mapping (4) were added but no code path produces them; Nethermind returns INVALID with a descriptive error for block-hash mismatches. Drop both until/unless we wire the status through the actual mismatch path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BranchProcessor tracked the witness-capture lifecycle with a pair of booleans and a manual finally block to disarm on exception. Replace with a `using` session struct that arms in its factory, drains on success, and disarms on Dispose if not drained. Removes the inner try/finally and the ArmWitnessCapture / DrainWitnessCapture helpers; restores the minor cosmetic edits that crept into the file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the Func<...> indirection the handler used to break the construction cycle. Now it takes `Lazy<IEngineRpcModule>` directly and calls `Value.engine_newPayloadV5(...)`, which simplifies the DI wiring to a plain type registration. Tests substitute IEngineRpcModule on the builder. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
newPayloadWithWitness already has both a JSON-RPC and SSZ-REST surface gated on the same fork, so route it through the same Configure(...) helper the other Amsterdam entries use rather than two parallel dict writes. Trim the comment in SszWireTypes that explains why NewPayloadWithWitnessResponseV1 is hand-rolled in SszCodec — keep the relevant why, drop the prose. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restore the blank line after the opening brace and the inline body of engine_getClientVersionV1 — neither was needed for the PR's witness work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three near-identical tests differing only in the engine module factory collapse into a single [TestCaseSource]-driven case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WitnessGeneratingWorldState.GetWitness and WitnessCapturingWorldStateProxy.BuildWitness both ran the same per-(address, slots) AccountProofCollector tree-walk loop. Pull the loop into WitnessProofCollector.CollectAccountProofs so both call sites share it. Also: - Swap Arm() order in the proxy to allocate the tracking dictionaries before flipping the armed flag; the prior order was safe only on the single-threaded ProcessOne path but inverted is a free correctness improvement. - Update WitnessCaptureRegistry xmldoc; the registry tolerates multiple concurrent armed entries for distinct block hashes (and cancels-and-replaces on duplicates). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dispatch SszMiddleware.InvokeAsync (versioned) and DispatchWitnessAsync (non-versioned witness path) duplicated the entire post-route pipeline: PipeReader body read, request-bytes metric, handler invocation, status-code bucketing, and the 413/400/500 error mapping. Pull the shared work into DispatchAsync(handler, version, extra) — the witness path now adds only the path-specific method/content-type/handler-not-null checks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Use Utf8JsonReader(ReadOnlySequence<byte>) in NewPayloadWithWitnessSszHandler instead of `body.ToArray()` on multi-segment bodies — saves an LOH allocation on every request. - Promote the encode-length Debug.Assert in EncodeNewPayloadWithWitnessResponse to a runtime check so a future header-size bug fails fast in Release rather than emitting silently-wrong bytes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- PatriciaTrieWitnessGenerator: fold upsert detection into the leaf/extension walks and each walked child's result; scan the bucket for an upsert only for an absent (null) child, removing the per-occupied-child scan from the hot path (behaviour-equivalent to the previous per-branch scan). - WitnessGeneratingWorldState: tag surviving accounts Upsert (not Read) so a newly-created account occupies its post-state state-trie slot and a sibling deletion in the same branch does not falsely collapse it (over-capture). - ZkEvmMutatedWitnessIndex: key the mutated index on Category::Name (not name alone) to avoid cross-dir collisions, and throw on RLP-block/engine-payload count mismatch to lock down the blocks[i] == engineNewPayloads[i] assumption. - NewPayloadWithWitnessHandler: drain the produced witness up front so the non-Success early return disposes its pooled buffers instead of leaking them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sts/witness-comparison
9bbd562 to
c339882
Compare
asdacap
previously approved these changes
Jul 2, 2026
LukaszRozmej
reviewed
Jul 2, 2026
LukaszRozmej
left a comment
Member
There was a problem hiding this comment.
verbose comments - as always
The witness block-processing envs hand-built BlockAccessListManager with a null transactionProcessorFactory, so the block-access list fell back to the plain Ethereum factory. On AuRa the chain overrides ITransactionProcessorFactory, and its contract-based withdrawal system calls touch the system-sender account that the plain factory omits, so the witness-generated BAL diverged from the main pipeline's and newPayloadWithWitness returned INVALID. Pass the container's ITransactionProcessorFactory while deliberately leaving the parallel parent-reader factories out, so the BAL still runs sequentially and every access is recorded into the witness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…to hudem1/feat/zkevm-tests/witness-comparison # Conflicts: # src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs
LukaszRozmej
previously approved these changes
Jul 5, 2026
The base branch was changed.
…ests/witness-comparison # Conflicts: # src/Nethermind/Nethermind.Consensus/Stateless/WitnessCapturingBlockProcessor.cs # src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingWorldState.cs # src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs # src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadWithWitnessHandler.cs # src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/SszRestPaths.cs # src/Nethermind/Nethermind.State.Test/PatriciaTrieWitnessGeneratorTests.cs # src/Nethermind/Nethermind.Trie/PatriciaTrieWitnessGenerator.cs
AnkushinDaniil
approved these changes
Jul 5, 2026
wurdum
approved these changes
Jul 5, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
benaadams
approved these changes
Jul 6, 2026
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.
Support all zkevm tests via both blockchain and engine using the latest zkevm release https://github.com/ethereum/execution-specs/releases/tag/tests-zkevm%40v0.4.1
Rebased on new payload with witness. We should first merge that one.
Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
Optional. Remove if not applicable.
Documentation
Requires documentation update
If yes, link the PR to the docs update or the issue with the details labeled
docs. Remove if not applicable.Requires explanation in Release Notes
If yes, fill in the details here. Remove if not applicable.
Remarks
Optional. Remove if not applicable.