fixes#11343
Conversation
|
@claude review |
|
Claude finished @svlachakis's task in 5m 14s —— View job PR Review
SummaryThis PR fixes several real bugs and adds defensive limits to the JavaScript tracer. The changes are well-scoped. A few issues need attention before merge. What's fixed (well done)
FindingsMedium1. Previously, 2. Missing test for The actual bug fixed was that 3. New test files instead of adding to existing files Repo rule (test-infrastructure.md): "Add tests to existing test files rather than creating new ones." Both new test files should be merged into existing counterparts. Low4.
5. Copyright year Not blocking but worth noting
|
|
Claude finished @svlachakis's task in 8m 27s —— View job PR Review
SummaryThis PR bundles four independent fixes/improvements:
Test coverage is solid: Findings
MediumM1 — When M2 — The PR's own test comment notes that a 5M-gas tight loop generates ~1.25M step callbacks, meaning the 200k limit fires at roughly 16% of the block gas limit. Complex DeFi transactions traced with a custom LowL1 — This is a process-global V8 heap budget shared across all concurrent JS traces. Per repo style, constraints like this should document units and rationale. L2 —
|
|
@claude review again |
|
Claude finished @svlachakis's task in 4m 39s —— View job PR Review
What was addressed since the previous review
Remaining findingsMediumM1 — New test file ( Per test-infrastructure.md: "Add tests to existing test files rather than creating new ones." There is no pre-existing unit-level LowL1 — This is a process-global heap cap shared across all concurrent JS-tracer instances. Per repo style, non-obvious constants should document units and rationale. L2 — Geth calls Not blocking
Summary: The substantive fixes ( |
|
@claude changed to timeout approach, I think it's better. Also for your other comment, When the timeout fires, Engine.Interrupt() causes step() to throw without invoking fault(). Geth exhibits the same behaviour on timeout (evm.Cancel skips fault), so this should be fine shouldn't it? |
|
Claude finished @svlachakis's task in 2m 37s —— View job Review update
Answer:
|
| Finding | Status |
|---|---|
_resultConstructed = true in finally |
✅ Fixed — correctly placed after result() |
using IDisposable _ misleading name |
✅ N/A — removed with step-count approach |
MaxStepCount too low |
✅ Removed — replaced by real-time timeout |
fault() not called on step-limit breach |
✅ Moot — step limit removed; timeout matches Geth behavior |
GethTraceOptions.Timeout typed as string |
✅ Fixed to TimeSpan? |
Zero PrevRandao override test |
✅ Added |
StateOverridesTests class name |
✅ Renamed from StateOverridesNonceTests |
V8MaxOldSpaceMb needs comment |
|
Indentation regression on CreateTrace() |
🔴 New — line 67 at column 0 |
The only things left are the formatting regression (should be fixed before merge) and the missing comment on the heap cap (low priority).
|
@claude review again, comment for V8MaxOldSpaceMb is not needed |
|
Claude finished @svlachakis's task in 3m 33s —— View job PR Review
Status of all prior findings
Remaining findingMedium —
|
|
@claude review again |
|
Claude finished @svlachakis's task in 2m 5s —— View job PR Review
Status of all prior findings
All findings from previous rounds have been resolved. The implementation is correct:
This PR is ready to merge. |
|
Claude finished @svlachakis's task in 1m 52s —— View job PR Review
Status of all prior findings
No remaining findingsAll substantive correctness fixes are correct and complete:
This PR is ready to merge. |
|
@claude resolved @LukaszRozmej's comments, added geth format support alongside c# time format support. review again please |
|
Claude finished @svlachakis's task in 2m 41s —— View job PR Review
What was addressed since the previous review
New code —
|
| Category | Count |
|---|---|
| Critical | 0 |
| High | 0 |
| Medium | 0 |
| Low | 0 |
All substantive fixes (PrevRandao nullable, GasLimit error message, nonce bounds check, JS tracer wall-clock timeout with Geth-compatible format support and 2-minute cap) are correct and complete. This PR is ready to merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CustomTimeDurationConverter — refactor notes (commit e72b6fd)Zero-allocation JSON paths
Unit dictionary →
|
|
@claude re-review |
|
Claude finished @LukaszRozmej's task in 5m 24s —— View job PR Review
|
| Property | Status |
|---|---|
CopyString into 64-char stack buffer instead of GetString() — zero allocation for short strings |
✅ Lines 72–75 |
Format writes into caller-provided Span<char>, fed directly to WriteStringValue(ReadOnlySpan<char>) — zero allocation |
✅ Lines 91–95 |
SearchValues<char> for SIMD-capable IndexOfAny/IndexOfAnyExcept scans |
✅ Lines 44, 47, 276, 287 |
switch expression over ReadOnlySpan<char> replaces Dictionary hashing |
✅ Lines 300–309 |
UInt128 for fractional math — exact integer arithmetic, no float rounding |
✅ Line 241 |
ulong.TryParse with built-in overflow detection on integer parts |
✅ Line 252 |
Named constants replacing magic numbers (NsPerTick, MaxNs, FormatBufferSize, etc.) |
✅ Lines 18–42 |
Pow10 table avoids recomputation for fractional scaling |
✅ Lines 50–57 |
TryParseSegment / TryTakeInteger / TakeFraction / TryTakeUnit / TakeDigits each do one thing |
✅ |
format writes right-to-left, suppresses trailing zeros — matches Go's Duration.String() |
✅ Lines 99–148 |
Both µ (U+00B5) and μ (U+03BC) accepted |
✅ Line 303 |
"0" without unit accepted as Go special case |
✅ Line 189 |
Positive-value cap: totalNs > MaxNs - 1 matches Go's d > 1<<63-1 |
✅ Line 206 |
Per-segment overflow guard: v > MaxNs / unitNs before multiply |
✅ Line 234 |
MaxFractionalDigits = 18 always fits ulong |
✅ 2^63 >> 10^18 |
| FormatBufferSize = 32, max output is 25 chars | ✅ |
Debug.Assert documents the invariant on TryParse of known-digit input |
✅ Line 270 |
| 60 test cases: valid Go formats, valid C# TimeSpan, invalid inputs, write serialization, round-trips | ✅ |
Everything checks out. The implementation is a faithful, well-tested port of Go's duration format.
All prior findings — resolved
| Finding | Status |
|---|---|
_resultConstructed = true in finally (disposal semantics) |
✅ Set after result(), not in finally — correct |
_ctsRegistration naming and dual-dispose |
✅ Disposed in BuildResult() (prevents stale interrupt) and Dispose() (idempotent fallback) |
MaxStepCount too low |
✅ Removed — replaced by wall-clock timeout |
GethTraceOptions.Timeout type breaks Geth JSON clients |
✅ [JsonConverter(typeof(CustomTimeDurationConverter))] on TimeSpan? handles both "5s" and ISO 8601 |
| Negative durations and zero rejected | ✅ Constructor guards timeout <= TimeSpan.Zero || timeout > MaxTimeout |
Zero PrevRandao override silently ignored |
✅ PrevRandao is Hash256?, && PrevRandao != Hash256.Zero guard removed |
Zero PrevRandao test |
✅ prevrandao_with_zero_override_returns_zero test case |
GasLimit error message reported ulong.MaxValue |
✅ Now correctly reports long.MaxValue |
Nonce > ulong.MaxValue not validated |
✅ MaxNonce = ulong.MaxValue at top of class, check added |
MaxNonce field between methods |
✅ At top of class |
StateOverridesTests class name and file |
✅ Correct class name, copyright 2026 |
| LukaszRozmej's Geth format compatibility question | ✅ CustomTimeDurationConverter ports Go's time.ParseDuration exactly |
| LukaszRozmej's "should it have a cap?" question | ✅ MaxTimeout = TimeSpan.FromMinutes(2) enforced in constructor |
No remaining findings
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 0 |
| Medium | 0 |
| Low | 0 |
All substantive fixes and the CustomTimeDurationConverter refactor are correct and complete. This PR is ready to merge.
|
@LukaszRozmej Thanks, LGTM! |
|
@svlachakis please merge master |
# Conflicts: # src/Nethermind/Nethermind.Evm/BlockOverride.cs # src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs
|
@claude I did some more refactoring please check. |
|
Claude finished @svlachakis's task in 2m 5s —— View job PR Review
What changed in this refactoringThe refactoring touches only Correctness fixes (all correct)1. Overflow in Previous code: ulong seconds = absTicks / TicksPerSecond;
ulong nsFraction = (absTicks % TicksPerSecond) * NsPerTick;
2. Previously the 3. Silent Previous: New: 4. The C# fallback parser was using the current thread culture, which could differ on machines with non-invariant locale settings. Added Safety improvements (both correct)5. Non-string token type check — new 6. Max-input-length throws instead of falling back to Code clarityNamed variables ( No findings
All four correctness fixes are sound, test coverage is comprehensive (correctness, edge cases, overflow, non-string tokens, extreme This PR is ready to merge. |
|
@LukaszRozmej I did some more refactoring on the go converter, please check again |
Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?