Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
0c62196
feat(engine): introduce REST based + SSZ serialized `new-payload-with…
Dyslex7c May 15, 2026
45710c8
register handler in DI
Dyslex7c May 15, 2026
f5631ea
fix test and formatting
Dyslex7c May 15, 2026
c4028c5
address deep review comments
Dyslex7c May 15, 2026
1e31a1f
add JSON-RPC method
Dyslex7c May 15, 2026
6671f99
fix taiko tests
Dyslex7c May 15, 2026
1d382f4
address review comments
Dyslex7c May 16, 2026
5ded051
address review comments
Dyslex7c May 17, 2026
8d10573
fix taiko tests and build
Dyslex7c May 17, 2026
2997bad
remove double block execution
Dyslex7c May 20, 2026
56551a1
merge with upstream
Dyslex7c May 20, 2026
bf1ccb1
fix CI build error
Dyslex7c May 20, 2026
792a296
address prev review comments
Dyslex7c May 20, 2026
13a70ee
address claude review comments
Dyslex7c May 20, 2026
6ec0663
address claude review
Dyslex7c May 21, 2026
5e43a8f
bug fixes
Dyslex7c May 21, 2026
77b72af
fix(witness): forward default IWorldState members to inner
LukaszRozmej May 22, 2026
384fd60
revert CodeInfoRepository code-lookup order swap
LukaszRozmej May 22, 2026
c9af935
restore SSZ MaxBodySize to spec value (16 MiB)
LukaszRozmej May 22, 2026
6e2b729
make NewPayloadWithWitnessV1Result IDisposable to return pool buffers
LukaszRozmej May 22, 2026
488d613
handle witness-capture cancellation on duplicate ArmCapture
LukaszRozmej May 22, 2026
53ff5e6
remove unused PayloadStatus.InvalidBlockHash
LukaszRozmej May 22, 2026
d7bb6a2
introduce WitnessCaptureSession to remove witness arm/disarm flags
LukaszRozmej May 22, 2026
4558ff1
inject Lazy<IEngineRpcModule> into NewPayloadWithWitnessHandler
LukaszRozmej May 22, 2026
13696e6
use Configure helper for newPayloadWithWitness; trim SSZ Union comment
LukaszRozmej May 22, 2026
8556efa
revert cosmetic refactor in EngineRpcModule
LukaszRozmej May 22, 2026
bbb6876
parameterize three Handler_calls_DisarmCapture tests
LukaszRozmej May 22, 2026
d2946c5
factor witness state-node proof collection into shared helper
LukaszRozmej May 22, 2026
b691335
share body-read/metrics/error path between versioned and witness SSZ …
LukaszRozmej May 22, 2026
56cc9f1
tighten SSZ codec/handler edges
LukaszRozmej May 22, 2026
43892c0
remove now-unused Nethermind.State.Proofs using in WitnessGeneratingW…
LukaszRozmej May 22, 2026
f81dac2
fix Arm() double-arm semantics and IDE0028 lint
LukaszRozmej May 22, 2026
90edb7d
disarm capture if BranchProcessor did not run for VALID payload
LukaszRozmej May 22, 2026
a2d6273
drop redundant inner using of Witness in SSZ writer
LukaszRozmej May 22, 2026
56ed6be
address deep-review fixes for newPayloadWithWitness
LukaszRozmej May 22, 2026
ffb03e3
disarm capture on engine_newPayloadV5 exception; flip Disarm order
LukaszRozmej May 22, 2026
e290bd6
snapshot proxy tracking dicts to drop ! non-null assertions
LukaszRozmej May 22, 2026
7018bbf
update Disarm comment after recorders moved to snapshot model
LukaszRozmej May 22, 2026
6148859
trim verbose comments across witness/SSZ surface
LukaszRozmej May 22, 2026
3f598dd
parameterize SSZ codec witness-union and middleware error-response tests
LukaszRozmej May 22, 2026
2035776
address review nits — uint32 offsets, namespace match
LukaszRozmej May 22, 2026
b7592f0
fold witness registry into proxy; drop registry param from BranchProc…
LukaszRozmej May 22, 2026
9b68f6a
inject witness handler directly into SszMiddleware; logger one-liners…
LukaszRozmej May 22, 2026
624fe3a
move witness arm/drain out of BranchProcessor; collapse IWitnessCaptu…
LukaszRozmej May 22, 2026
1c81852
remove unused usings flagged by IDE0005 in CI
LukaszRozmej May 22, 2026
45979e8
Collapse witness Arm/Drain into per-call recorder
LukaszRozmej May 22, 2026
891debf
remove unused Nethermind.Logging using flagged by IDE0005 in CI
LukaszRozmej May 22, 2026
b67b746
drop unused Nethermind.State using from witness proxy
LukaszRozmej May 22, 2026
73c86cc
wip: integrate new EEST tests
Dyslex7c May 23, 2026
c0a7e14
fix pyspec zkevm tests
Dyslex7c May 25, 2026
4eaa290
fix ci build error
Dyslex7c May 25, 2026
3295932
fix ci build error ethereum tests
Dyslex7c May 25, 2026
678540b
fixing failing zkevm tests checkpoint
Dyslex7c May 26, 2026
581ffcd
fix zkevm failing tests
Dyslex7c May 26, 2026
31c7d04
update known failing tests
Dyslex7c May 27, 2026
a3ec13e
use known-failing-hive-tests.txt
Dyslex7c May 27, 2026
2aad6ea
Merge remote-tracking branch 'origin/master' into new-payload-with-wi…
LukaszRozmej May 27, 2026
ecebc49
Merge remote-tracking branch 'origin/master' into new-payload-with-wi…
LukaszRozmej May 27, 2026
c13e577
Merge remote-tracking branch 'origin/master' into new-payload-with-wi…
LukaszRozmej May 27, 2026
bb6f8d8
fix zkevm tests after merge
Dyslex7c May 27, 2026
80e9198
use `_innerWorldState.RecordBytecodeAccess directly`
Dyslex7c May 28, 2026
ec15292
use `WitnessCapturingTrieStore`
Dyslex7c May 28, 2026
861b3b8
Merge remote-tracking branch 'origin/master' into pr-11623
LukaszRozmej Jun 2, 2026
b9fae05
fix(merge): forward IWorldState.HintBal in WitnessCapturingWorldState…
LukaszRozmej Jun 2, 2026
dbe9a8f
Merge branch 'master' into new-payload-with-witness-ssz
hudem1 Jun 9, 2026
48ce9c4
chore: Remove stale amsterdam tests folder
hudem1 Jun 9, 2026
ee86148
chore: Remove partial pyspec zkevm tests support
hudem1 Jun 9, 2026
51b7e31
chore: Remove partial witness recording fixes
hudem1 Jun 9, 2026
d93e81f
chore: Create WitnessCapturingTrieStore directly where needed
hudem1 Jun 9, 2026
35b8d8f
fix: Wire capturing trie store + capturing header finder + no-cache C…
hudem1 Jun 12, 2026
02c5ec0
fix: Use WitnessExecutionPredicate for BAL
hudem1 Jun 15, 2026
fe7a6a7
fix: Record trie nodes on flat db via ITrieNodeReadObserver
hudem1 Jun 15, 2026
7c94a7d
Merge branch 'master' into new-payload-with-witness-ssz
hudem1 Jun 15, 2026
20d6be0
fix: Remove double container configuration in tests
hudem1 Jun 15, 2026
2673738
fix: Register only a distinct instance of each block validation and m…
hudem1 Jun 15, 2026
ae9e585
fix: Format
hudem1 Jun 15, 2026
65073e0
temporary: logs for debugging tests on CI
hudem1 Jun 15, 2026
040db57
Revert "temporary: logs for debugging tests on CI"
hudem1 Jun 17, 2026
6a5eaad
Revert "fix: Record trie nodes on flat db via ITrieNodeReadObserver"
hudem1 Jun 18, 2026
a7ba75f
feat(trie): bulkset-style stateless witness generator
asdacap Jun 16, 2026
4287512
feat(witness): generate the stateless witness from the pre-state trie
asdacap Jun 17, 2026
5b5fc97
chore(witness): address review feedback
asdacap Jun 17, 2026
d8af02a
fix: Remove all references to witness capturing trie store and record…
hudem1 Jun 18, 2026
689cecf
fix: Interface typo
hudem1 Jun 18, 2026
74a6727
fix: Add BeginScope call for flat db
hudem1 Jun 18, 2026
2a02f76
fix: lint
hudem1 Jun 18, 2026
910fbe3
temporary: logs for debugging tests on CI
hudem1 Jun 15, 2026
0b0f005
Revert "temporary: logs for debugging tests on CI"
hudem1 Jun 18, 2026
fbece84
temporary: logs for debugging tests on CI v2
hudem1 Jun 18, 2026
50ef5f2
temporary: Add debug logs in assertion directly
hudem1 Jun 18, 2026
1a40f60
fix: Remove temporary logs in test file
hudem1 Jun 22, 2026
91c9c73
fix: Bad request body sends back a 400 instead of 500
hudem1 Jun 22, 2026
1a727cb
fix: Set validation error to 1024 bytes inside response
hudem1 Jun 22, 2026
50d6bcc
fix: Dispose trie store when not needed anymore
hudem1 Jun 22, 2026
9bb6c4f
fix: WitnessCaptureSession arms all recorders atomically
hudem1 Jun 22, 2026
7acbcb9
fix: Remove useless registration of NewPayloadWithWitnessSszHandler a…
hudem1 Jun 22, 2026
f975547
chore: Better check against casting issues when registering concrete …
hudem1 Jun 22, 2026
0dc05ba
chore: Resolve all parameters for BlockAccessListManager automaticall…
hudem1 Jun 22, 2026
f91f102
fix: build
hudem1 Jun 22, 2026
c8833d8
refactor(witness): capture via a second BlockProcessor graph, not run…
asdacap Jun 23, 2026
81bf010
Merge branch 'master' into new-payload-with-witness-ssz
hudem1 Jun 23, 2026
396b66e
refactor: Generify NewPayloadWithWitnessSszHandler as a ISszEndpointH…
hudem1 Jun 24, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Threading;
using BenchmarkDotNet.Attributes;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
using Nethermind.Db;
using Nethermind.Logging;
using Nethermind.Trie;
using Nethermind.Trie.Pruning;

namespace Nethermind.Benchmarks.Store
{
/// <summary>
/// Compares the new mutation-free <see cref="PatriciaTrieWitnessGenerator"/> (sequential and parallel) against
/// the old "capture trie reads during the actual mutation" technique it replaces.
/// </summary>
[MemoryDiagnoser]
[MinIterationTime(1000)]
public class PatriciaTrieWitnessGeneratorBenchmarks
{
[Params(100_000)]
public int TrieSize { get; set; }

[Params(1_000, 5_000)]
public int TouchedCount { get; set; }

[Params(0.0, 0.5)]
public double DeleteFraction { get; set; }

private MemDb _db;
private Hash256 _root;
private PatriciaTrieWitnessGenerator.PathEntry[] _entries;
private Hash256[] _reads;
private Hash256[] _deletes;

[GlobalSetup]
public void Setup()
{
Random rng = new(0);

MemDb db = new();
RawScopedTrieStore store = new(db);
PatriciaTree tree = new(store, LimboLogs.Instance);

Hash256[] keys = new Hash256[TrieSize];
using ArrayPoolListRef<PatriciaTree.BulkSetEntry> bulk = new(TrieSize);
for (int i = 0; i < TrieSize; i++)
{
byte[] keyBuf = new byte[32];
rng.NextBytes(keyBuf);
byte[] valueBuf = new byte[32];
rng.NextBytes(valueBuf);
keys[i] = new Hash256(keyBuf);
bulk.Add(new PatriciaTree.BulkSetEntry(keys[i], valueBuf));
}
tree.BulkSet(bulk);
tree.Commit();

_db = db;
_root = tree.RootHash;

int deleteCount = (int)(TouchedCount * DeleteFraction);
_entries = new PatriciaTrieWitnessGenerator.PathEntry[TouchedCount];
List<Hash256> reads = [];
List<Hash256> deletes = [];
for (int i = 0; i < TouchedCount; i++)
{
Hash256 key = keys[rng.Next(TrieSize)];
bool isDeleted = i < deleteCount;
_entries[i] = new PatriciaTrieWitnessGenerator.PathEntry(
key,
isDeleted ? PatriciaTrieWitnessGenerator.AccessType.Delete : PatriciaTrieWitnessGenerator.AccessType.Read);
(isDeleted ? deletes : reads).Add(key);
}

_reads = [.. reads];
_deletes = [.. deletes];
}

[Benchmark(Baseline = true)]
public int Old_CaptureDuringMutation()
{
CapturingScopedTrieStore store = new(new RawScopedTrieStore(_db));
PatriciaTree tree = new(store, LimboLogs.Instance) { RootHash = _root };
foreach (Hash256 key in _reads) tree.Get(key.Bytes);
foreach (Hash256 key in _deletes) tree.Set(key.Bytes, (byte[])null);
tree.UpdateRootHash();
return store.Captured.Count;
}

[Benchmark]
public int New_Sequential()
{
CountingSink sink = new();
PatriciaTrieWitnessGenerator.Generate(new RawScopedTrieStore(_db), _root, _entries, sink, parallelize: false);
return sink.Count;
}

[Benchmark]
public int New_Parallel()
{
CountingSink sink = new();
PatriciaTrieWitnessGenerator.Generate(new RawScopedTrieStore(_db), _root, _entries, sink, parallelize: true);
return sink.Count;
}

private sealed class CountingSink : PatriciaTrieWitnessGenerator.ISink
{
private int _count;
public int Count => _count;
public void Add(in TreePath path, TrieNode node) => Interlocked.Increment(ref _count);
}

private sealed class CapturingScopedTrieStore(IScopedTrieStore baseStore) : IScopedTrieStore
{
public Dictionary<Hash256AsKey, byte[]> Captured { get; } = [];

public TrieNode FindCachedOrUnknown(in TreePath path, Hash256 hash) => baseStore.FindCachedOrUnknown(in path, hash);

public byte[] LoadRlp(in TreePath path, Hash256 hash, ReadFlags flags = ReadFlags.None) => Capture(hash, baseStore.LoadRlp(in path, hash, flags));

public byte[] TryLoadRlp(in TreePath path, Hash256 hash, ReadFlags flags = ReadFlags.None) => Capture(hash, baseStore.TryLoadRlp(in path, hash, flags));

private byte[] Capture(Hash256 hash, byte[] rlp)
{
if (rlp is not null) Captured[hash] = rlp;
return rlp;
}

public ITrieNodeResolver GetStorageTrieNodeResolver(Hash256 address) => baseStore.GetStorageTrieNodeResolver(address);

public INodeStorage.KeyScheme Scheme => baseStore.Scheme;

public ICommitter BeginCommit(TrieNode root, WriteFlags writeFlags = WriteFlags.None) => baseStore.BeginCommit(root, writeFlags);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,17 @@ public void PrepareForProcessing(Block suggestedBlock, IReleaseSpec spec, Proces

// Parallel execution needs the decoded BAL body (RLP fixtures only carry the hash)
// and an active state scope (so we can capture the parent state root for workers).
//
// Witness-mode managers force sequential: parallel workers read pre-state through pooled
// parent-reader snapshots that bypass the recording world state, so their accesses would be
// missing from the witness. Only the witness-processing graph sets witnessMode, so regular
// blocks on EIP-7928 chains keep parallel execution.
ParallelExecutionEnabled = Enabled
&& blocksConfig.ParallelExecution
&& !_isBuilding
&& suggestedBlock.BlockAccessList is not null
&& stateProvider.IsInScope;
&& stateProvider.IsInScope
&& !witnessMode;

// BAL-driven read warming: mirrors BlockCachePreWarmer.IsBalReadWarmingEnabled so
// HintBal honours the same opt-in config as the prewarmer path.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ private BlockProcessor GetProcessor()
ParallelExecutionBatchRead = false
},
new WithdrawalProcessorFactory(logManager),
// Stateless execution must resolve code only from the witness-backed state, never the
// shared cache — so it always runs in witness mode (non-caching code reads).
witnessMode: true
);
BlockProcessor.ParallelBlockValidationTransactionsExecutor txExecutor = new(
Expand Down
Loading
Loading