Skip to content

evmrpc: gate historical debug trace calls#3515

Open
codchen wants to merge 1 commit into
mainfrom
codex/historical-debug-trace-config
Open

evmrpc: gate historical debug trace calls#3515
codchen wants to merge 1 commit into
mainfrom
codex/historical-debug-trace-config

Conversation

@codchen
Copy link
Copy Markdown
Collaborator

@codchen codchen commented May 28, 2026

Summary

  • Reuse the existing max_trace_lookback_blocks config for all debug_trace* lookback checks.
    • -1 keeps the existing unlimited-lookback behavior.
    • 0 means only the latest block is within lookback.
    • >0 allows that many blocks behind latest.
  • Count debug_trace* attempts that exceed the configured lookback with an endpoint/connection-labelled OTel counter.
  • Preserve the existing block-number trace error semantics while extending the same guard to transaction, hash, traceCall, state access, and profile trace endpoints.

Tests

  • go test ./evmrpc/config
  • go test ./evmrpc -run 'Test(IsHistoricalDebugTraceBlock|GuardHistoricalDebugTraceHeight)$'
  • go test ./evmrpc -run 'TestTrace(Transaction|Call|BlockByNumberLookbackLimit|BlockByNumberUnlimitedLookback)$'
  • git diff --check origin/main...HEAD

@cursor
Copy link
Copy Markdown

cursor Bot commented May 28, 2026

PR Summary

Medium Risk
Changes default-off RPC behavior for expensive debug_trace* workloads; operators enabling a positive age may break clients that rely on deep historical traces.

Overview
Adds disable_historical_debug_trace_block_age to EVM RPC config (default 0 = no restriction). When set to a positive value, debug_trace* requests whose target block is more than N blocks behind the chain tip are rejected before trace work runs, with a clear error naming the method and heights.

Guards resolve the block from tx hash, block number/hash, or debug_traceCall block spec (including latest/safe/finalized), then compare against latest height. Blocked attempts increment evmrpc_historical_debug_trace_attempts_total (endpoint + connection labels). Config loading rejects invalid/negative values; unit tests cover classification and guard behavior.

Not gated: sei_traceBlock*ExcludeTraceFail and other non-debug_trace* paths in this diff.

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMay 29, 2026, 3:01 AM

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 49.25373% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.21%. Comparing base (1b322f0) to head (e9f7b71).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
evmrpc/tracers.go 44.82% 22 Missing and 10 partials ⚠️
evmrpc/trace_profile.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3515      +/-   ##
==========================================
- Coverage   59.04%   58.21%   -0.83%     
==========================================
  Files        2199     2129      -70     
  Lines      182096   173985    -8111     
==========================================
- Hits       107510   101282    -6228     
+ Misses      64935    63706    -1229     
+ Partials     9651     8997     -654     
Flag Coverage Δ
sei-chain-pr 68.15% <49.25%> (?)
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/metrics.go 96.49% <100.00%> (+0.49%) ⬆️
evmrpc/trace_profile.go 68.60% <0.00%> (-1.64%) ⬇️
evmrpc/tracers.go 68.36% <44.82%> (-3.55%) ⬇️

... and 73 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.

Copy link
Copy Markdown
Collaborator

@masih masih left a comment

Choose a reason for hiding this comment

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

Thinking out loud: Do we want to apply the limit to sei_traceBlockByHashExcludeTraceFail and sei_traceBlockByNumberExcludeTraceFail too? I would just to have consistent behaviour even though I think we disabled those endpoints by default. The edge case I am thinking of is incase someone has them enabled. If we do decide to do this then I would drop the debug_ from config names and call it something like max_trace_lookback with docs explaining where it applies etc. etc.

Comment thread evmrpc/config/config.go Outdated

// HistoricalDebugTraceBlockAge defines how many blocks behind latest a debug_trace*
// target can be before it is considered historical. Set to -1 to disable classification.
HistoricalDebugTraceBlockAge int64 `mapstructure:"historical_debug_trace_block_age"`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Instead of "Age" would it be clearer to use the term "lookback"?

Because the former usually caries a notion of time, whereas the config here is simply a counter of relative offset from latest height.

Comment thread evmrpc/config/config.go Outdated

// DisableHistoricalDebugTrace rejects debug_trace* calls whose target block is older than
// HistoricalDebugTraceBlockAge blocks behind the latest block.
DisableHistoricalDebugTrace bool `mapstructure:"disable_historical_debug_trace"`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When we use the term "historical" do we refer to an explicit system component with the same name? I think not. I think that "historical" is the lingo we used internally to talk about this subject; right?

If that's right, then my suggestion is to remove the term "historical" entirely from config and variable names. What we really mean here is a lookback limit. We can then get rid of the dual flag of one boolean and one int "lookback amount", in favour of a single config, named something like max_debug_trace_lookback. Zero means ignored. Positive value means limit is applied to whatever is configured.

That simplifies things operationally speaking.

@codchen codchen force-pushed the codex/historical-debug-trace-config branch from 22a4c8f to 28c8bbf Compare May 28, 2026 13:34
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 28c8bbf. Configure here.

Comment thread evmrpc/tracers.go
@codchen codchen force-pushed the codex/historical-debug-trace-config branch from 28c8bbf to e9f7b71 Compare May 29, 2026 02:59
Copy link
Copy Markdown
Collaborator

@masih masih left a comment

Choose a reason for hiding this comment

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

Much nicer thanks Tony 🙌

Left couple of comments on error handing.

Comment thread evmrpc/tracers.go
}
receipt, err := api.keeper.GetReceipt(api.ctxProvider(LatestCtxHeight), hash)
if err != nil || receipt == nil {
return nil
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  • Did we mean to return err if error is non-nil?
  • if not, log the error in DEBUG level or something similar?

Comment thread evmrpc/tracers.go
}
block, _, err := api.backend.BlockByHash(ctx, hash)
if err != nil || block == nil {
return nil
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ditto re returning error

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