Skip to content

fix(evmrpc): honor trace_timeout in profiled debug_traceBlock path (PLT-989) - #3914

Merged
amir-deris merged 3 commits into
mainfrom
amir/plt-989-honour-trace-timeout-in-trace-block-path
Aug 13, 2026
Merged

fix(evmrpc): honor trace_timeout in profiled debug_traceBlock path (PLT-989)#3914
amir-deris merged 3 commits into
mainfrom
amir/plt-989-honour-trace-timeout-in-trace-block-path

Conversation

@amir-deris

@amir-deris amir-deris commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to PLT-986 for the opt-in profiled debug_traceBlock* path (evm.enable_parallelized_block_trace = true, default struct logger).

When tracing CosmWasm-heavy blocks, non-EVM txs are replayed via TraceBlockMetadata.TraceRunnableDeliverTx. The profiled loops did not check ctx.Err() between metadata iterations, so after trace_timeout the handler could keep replaying Cosmos/Wasm txs and hold a trace semaphore slot until restart.

This adds per-iteration context checks in profiledTraceBlockSequential and profiledTraceBlockParallel, matching the pattern used in go-ethereum PR #94 and ReplayTransactionTillIndex. Both paths now return a top-level RPC error on block-level timeout/cancellation (nil, ctx.Err()), so behavior no longer depends on CPU count or traced-tx count.

Changes

  • profiledTraceBlockSequential: return on ctx.Err() at the start of each EVM-only and metadata-replay iteration
  • profiledTraceBlockParallel: break on ctx.Err() at the start of each iteration; propagate context.DeadlineExceeded / context.Canceled as a top-level RPC error (same as sequential) instead of partial results, nil
  • Comment at the sequential/parallel branch documenting the shared timeout contract
  • Tests:
    • sequential metadata and EVM-only loop cancellation in block_trace_profiled_test.go
    • parallel metadata-loop cancellation in block_trace_profiled_export_test.go (via export test hooks in export_test.go)

Out of scope

  • go-ethereum dependency bump (default trace path / PLT-986)
  • Cancelling a DeliverTx already blocked inside Wasm execution

Test plan

  • go test ./evmrpc/ -run ProfiledTraceBlock -count=1

References

…LT-989)

Stop CosmWasm metadata replay loops from ignoring the trace context after timeout, so parallelized block traces release their semaphore slot instead of running until restart.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedAug 13, 2026, 3:32 PM

@amir-deris amir-deris changed the title fix(evmrpc): honor trace_timeout in profiled debug_traceBlock path (P… fix(evmrpc): honor trace_timeout in profiled debug_traceBlock path (PLT-989) Aug 13, 2026
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.49%. Comparing base (8bbac80) to head (e921de0).

Files with missing lines Patch % Lines
evmrpc/block_trace_profiled.go 75.00% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3914      +/-   ##
==========================================
- Coverage   59.48%   58.49%   -1.00%     
==========================================
  Files        2325     2229      -96     
  Lines      198647   188027   -10620     
==========================================
- Hits       118160   109977    -8183     
+ Misses      69258    67655    -1603     
+ Partials    11229    10395     -834     
Flag Coverage Δ
sei-chain-pr 71.96% <75.00%> (?)
sei-db 70.41% <ø> (ø)
sei-db-state-db ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
evmrpc/block_trace_profiled.go 25.40% <75.00%> (+9.81%) ⬆️

... and 132 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@amir-deris
amir-deris marked this pull request as ready for review August 13, 2026 13:39
@cursor

cursor Bot commented Aug 13, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes EVM RPC trace behavior on timeout/cancellation for an opt-in path; low blast radius but affects long-running CosmWasm-heavy traces and semaphore lifetime.

Overview
Profiled debug_traceBlock* now stops replaying block txs when the trace context expires or is canceled, instead of continuing through CosmWasm/Cosmos TraceRunnable steps and holding trace resources.

profiledTraceBlockSequential checks ctx.Err() before each EVM-only tx and each metadata iteration and returns nil, err on timeout/cancellation. profiledTraceBlockParallel does the same at loop start and, on context.DeadlineExceeded / context.Canceled, returns a top-level RPC error instead of partial results. A short comment documents that both branches share this contract.

Tests cover sequential (metadata + EVM-only) and parallel metadata loops, plus export test hooks for the parallel path.

Reviewed by Cursor Bugbot for commit e921de0. Bugbot is set up for automated code reviews on this repo. Configure here.

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The fix is correct and minimal: the ctx reaching profiledTraceBlock* is the prepareTraceContext timeout context, and the new per-iteration ctx.Err() checks match the existing ReplayTransactionTillIndex pattern, closing the gap where md.TraceRunnable replays kept running past trace_timeout. No blockers; the notes concern the untested parallel half of the diff and the divergent timeout return semantics between the sequential and parallel paths.

Findings: 0 blocking | 7 non-blocking | 2 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • Test coverage covers only profiledTraceBlockSequential. Both new checks in profiledTraceBlockParallel (EVM-only and metadata branches) are untested — roughly half the behavioral change. The parallel path is reachable whenever min(NumCPU, tracedCount) > 1, i.e. the common case on real nodes, so it is the path most requests actually take; it is also the one with the surprising return contract (partial results, nil), so a test pinning that is worth more than the sequential ones.
  • On cancellation the parallel path fills untraced slots with "state advancement failed at prior tx: %v" (block_trace_profiled.go:301 and :312 — unchanged lines, so not inline-anchorable). That message is now emitted for context.DeadlineExceeded, where nothing about state advancement failed; an operator debugging a trace_timeout sees a misattributed error string. Consider branching the message on errors.Is(failed, context.DeadlineExceeded) || errors.Is(failed, context.Canceled).
  • Second-opinion passes: Codex reported "No material findings in the PR diff." cursor-review.md is empty — the Cursor pass produced no output, so treat this review as covering Claude + Codex only.
  • Nit: testProfiledTraceBlock (block_trace_profiled_test.go:77) is a fixture builder, not a test; a name like newProfiledTraceBlockFixture reads better next to the TestProfiledTraceBlock* functions it sits above.
  • Note: I could not execute go test ./evmrpc/ or go vet in this environment (command approval denied), so the findings below are from static reading of the diff and surrounding code, not from a test run.
  • 2 suggestion(s)/nit(s) flagged inline on specific lines.

Comment thread evmrpc/block_trace_profiled.go
block = gethtypes.NewBlock(block.Header(), body, nil, trie.NewStackTrie(nil))

ctx, cancel := context.WithCancel(t.Context())
cancel()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[nit] Cancelling before the call means this only exercises the guard on iteration 0 — it proves the loop never starts, not that it stops. The scenario the PR is fixing is cancellation mid-loop, which the metadata test above covers properly via cancel() inside the first TraceRunnable.

Also worth noting: the pre-fix failure mode here is a nil-interface panic in profiledTraceTx (statedb.GetNonce on the nil passed at line 144) rather than a clean assertion failure. Both points are addressed by giving iteration 0 something real to do and cancelling after it — e.g. a stub statedb — so the test fails on require.ErrorIs rather than on a panic.

amir-deris and others added 2 commits August 13, 2026 17:19
… (PLT-989)

Return a top-level RPC error from profiledTraceBlockParallel on block-level
timeout/cancellation so callers get consistent behavior regardless of CPU count.

Co-authored-by: Cursor <cursoragent@cursor.com>
@amir-deris
amir-deris added this pull request to the merge queue Aug 13, 2026
Merged via the queue into main with commit 510aa40 Aug 13, 2026
70 checks passed
@amir-deris
amir-deris deleted the amir/plt-989-honour-trace-timeout-in-trace-block-path branch August 13, 2026 16:42
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.

3 participants