Feature/parallel txs optimise prestate load#11495
Feature/parallel txs optimise prestate load#11495Marchhill merged 5 commits intobal-devnet-3-benchmarksfrom
Conversation
|
Claude finished @Marchhill's task in 8m 21s —— View job PR Review: Feature/parallel-txs-optimise-prestate-load
SummaryThis PR defers per-account prestate loading from The core concurrency design is sound: FindingsMediumNo tests for the concurrent gate mechanism [ The test changes only update the hardcoded sentinel from
Given the non-trivial concurrency design, regression protection for these paths would be valuable.
public void EnablePrestateGate() => _prestateGate ??= new ManualResetEventSlim(false);
LowStale
// Prestate is keyed at index -1, smaller than every real change, so we prepend (one realloc)
// to preserve the sorted-by-index invariant.
/// <see cref="Get(int)"/> can binary-search via <see cref="System.MemoryExtensions"/>.
stream.Encode((ushort)item.Index);The comment correctly documents the invariant ("Real indices bounded by
The method is safe to call from workers (slots 1..N) and from consumers after the parallel block completes, but calling it from slot 0 (the loader) before Unfilled PR description The PR description is the raw template with no changes listed, no type-of-change checkboxes ticked, and no testing/documentation sections filled. This makes it hard to assess scope and intent during review. Correctness notes (no action required)
|
|
|
||
| /// <summary>Storage value as visible at the start of <paramref name="blockAccessIndex"/> (i.e. last change strictly before the index).</summary> | ||
| public byte[] Get(int blockAccessIndex) | ||
| public byte[] Get(uint blockAccessIndex) |
There was a problem hiding this comment.
The class XML doc (line 15) still references <see cref="Get(int)"/> — the method signature was widened to uint in this PR. The cref will produce a broken XML doc link.
| public byte[] Get(uint blockAccessIndex) | |
| public byte[] Get(uint blockAccessIndex) |
(The fix is in the class-level <summary> — change Get(int) → Get(uint).)
| // Real indices are bounded by Eip7928Constants.MaxTxs == ushort.MaxValue, and the | ||
| // PrestateIndex sentinel is never encoded (it is only added to the suggested BAL on | ||
| // the receiving side via LoadPreStateToSuggestedBlockAccessList). | ||
| stream.Encode((ushort)item.Index); |
There was a problem hiding this comment.
Silent truncation if Index is in (ushort.MaxValue, uint.MaxValue). The invariant holds by construction today (all real indices come from ctx.DecodeUShort()), but a Debug.Assert would make violations loud:
| stream.Encode((ushort)item.Index); | |
| Debug.Assert(item.Index <= ushort.MaxValue || item.Index == Eip7928Constants.PrestateIndex, | |
| "PrestateIndex is never encoded; real indices must fit in ushort"); | |
| stream.Encode((ushort)item.Index); |
| // block on a serial pre-pass, PrepareForProcessing flips the gate on each account, slot 0 | ||
| // of the parallel loop loads prestate per-account and signals as soon as the account is | ||
| // done, and worker reads above wait per-account. Idempotent: an already-set gate stays set | ||
| // so a re-prepared block (already loaded) doesn't block workers. |
There was a problem hiding this comment.
ManualResetEventSlim implements IDisposable. While Dispose() is effectively a no-op here (the kernel handle is only allocated if .WaitHandle is accessed, which nothing in this path does), the objects accumulate — one per account per block — in the managed heap. Disposing them after the parallel block completes (FinalizeBlockProcessing or equivalent) would reduce GC pressure and follow the IDisposable contract.
Fixes Closes Resolves #
Please choose one of the keywords above to refer to the issue this PR solves followed by the issue number (e.g. Fixes #000). If no issue number, remove the line. Also, remove everything marked optional that is not applicable. Remove this note after reading.
Changes
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.