Skip to content

Improve logging for eth_call & eth_estimateGas JSON-RPC endpoints - #873

Merged
m-Peter merged 1 commit into
mainfrom
mpeter/logging-improvements
Sep 17, 2025
Merged

Improve logging for eth_call & eth_estimateGas JSON-RPC endpoints#873
m-Peter merged 1 commit into
mainfrom
mpeter/logging-improvements

Conversation

@m-Peter

@m-Peter m-Peter commented Sep 4, 2025

Copy link
Copy Markdown
Collaborator

Closes: #862

Description

After some effort to investigate a production issue, regarding eth_call, I realized that for errors, we only log the given args. This is not enough information, when trying to replicate a issue, either locally, or in production. We should log all other parameters, such as state overrides, block overrides, and the given block height/hash.


For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

Summary by CodeRabbit

  • Bug Fixes

    • Call and EstimateGas now default to the latest block when unspecified, preventing edge-case failures and improving reliability.
    • Argument validation consolidated with consistent typed error returns for clearer, more robust failure handling.
  • Chores

    • Improved structured JSON logging that captures request payloads and additional request metadata for better observability and debugging.

@coderabbitai

coderabbitai Bot commented Sep 4, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Defaults blockNumberOrHash/blockTag to "latest" early, validates args with short-form checks, marshals args, stateOverrides, and blockOverrides to JSON for structured RawJSON logging, routes marshal failures through handleError, and removes duplicated late defaulting in Call and EstimateGas.

Changes

Cohort / File(s) Summary of changes
API logging & defaults
api/api.go
- Default blockNumberOrHash / blockTag to "latest" at start of Call and EstimateGas
- Use short-form if err := args.Validate(); err != nil { ... } for validation
- Marshal args, stateOverrides, and blockOverrides to JSON and log as RawJSON fields (include blockTag)
- Return typed errors via handleError on marshal failures
- Remove duplicated late defaulting near height resolution

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant API as API (Call)
  participant L as Logger
  participant E as EVM Backend

  C->>API: eth_call(args, stateOverrides, blockOverrides, blockTag)
  API->>API: Default blockTag/blockNumberOrHash → "latest"
  API->>API: Validate args (short-form)
  alt invalid
    API-->>C: validation error
  else valid
    API->>API: Marshal args/stateOverrides/blockOverrides → JSON
    alt marshal error
      API-->>C: typed error via handleError
    else ok
      API->>L: Log structured RawJSON {args, stateOverrides, blockOverrides, blockTag}
      API->>E: Resolve height & execute call
      E-->>API: result / error
      API-->>C: result / error
    end
  end
Loading
sequenceDiagram
  autonumber
  participant C as Client
  participant API as API (EstimateGas)
  participant L as Logger
  participant E as EVM Backend

  C->>API: eth_estimateGas(args, stateOverrides, blockTag)
  API->>API: Default blockTag/blockNumberOrHash → "latest"
  API->>API: Validate args (short-form)
  alt invalid
    API-->>C: validation error
  else valid
    API->>API: Marshal args/stateOverrides → JSON
    alt marshal error
      API-->>C: typed error via handleError
    else ok
      API->>L: Log structured RawJSON {args, stateOverrides, blockTag}
      API->>E: Resolve height & estimate gas
      E-->>API: estimate / error
      API-->>C: estimate / error
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • peterargue
  • zhangchiqing

Poem

I nibble logs like clover crisp and green,
JSON carrots gleam—each field is seen.
BlockTag hops to "latest" on the trail,
Overrides logged so no detail will fail.
A rabbit audits calls with joyful zeal. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Although most edits are logging-focused, the PR introduces functional changes—specifically defaulting blockNumberOrHash to the "latest" tag early in Call and EstimateGas and removing a duplicated nil/default handling near height resolution—which modify runtime behavior beyond the logging objective and could affect call semantics or error paths in production. Move the behavioral changes into a separate PR or clearly document and justify the semantics change here, add unit/integration tests that demonstrate the intended behavior, and obtain reviewer confirmation of the functional impact before merging.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Improve logging for eth_call & eth_estimateGas JSON-RPC endpoints" is concise, specific, and accurately summarizes the PR's primary change (enhanced logging for those two endpoints), so it provides a clear summary for reviewers scanning history.
Linked Issues Check ✅ Passed The changes implement the linked issue #862 by marshaling and logging state overrides, block overrides, and the provided block tag/height alongside args for both eth_call and eth_estimateGas (using RawJSON fields) and by returning typed errors on marshaling failures, which aligns with the issue's request to include all request parameters in error logs for reproducibility.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mpeter/logging-improvements

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b39866 and 3b0ecdf.

📒 Files selected for processing (1)
  • api/api.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • api/api.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
api/api.go (6)

533-536: Use a local copy instead of taking the address of the package var.
Prevents any chance of shared-state mutation between concurrent requests.

Apply:

-  // Default to "latest" block tag
-  if blockNumberOrHash == nil {
-    blockNumberOrHash = &latestBlockNumberOrHash
-  }
+  // Default to "latest" block tag
+  if blockNumberOrHash == nil {
+    defaultTag := latestBlockNumberOrHash
+    blockNumberOrHash = &defaultTag
+  }

538-552: Return marshaling errors with endpoint context (and blockTag) for better diagnostics.
Right now these paths use b.logger, losing endpoint context. Keep logs consistent with the rest of the method.

Apply:

-  if err != nil {
-    return handleError[hexutil.Bytes](err, b.logger, b.collector)
-  }
+  if err != nil {
+    return handleError[hexutil.Bytes](
+      err,
+      b.logger.With().Str("endpoint", EthCall).Str("blockTag", blockNumberOrHash.String()).Logger(),
+      b.collector,
+    )
+  }
@@
-  if err != nil {
-    return handleError[hexutil.Bytes](err, b.logger, b.collector)
-  }
+  if err != nil {
+    return handleError[hexutil.Bytes](
+      err,
+      b.logger.With().Str("endpoint", EthCall).Str("blockTag", blockNumberOrHash.String()).Logger(),
+      b.collector,
+    )
+  }
@@
-  if err != nil {
-    return handleError[hexutil.Bytes](err, b.logger, b.collector)
-  }
+  if err != nil {
+    return handleError[hexutil.Bytes](
+      err,
+      b.logger.With().Str("endpoint", EthCall).Str("blockTag", blockNumberOrHash.String()).Logger(),
+      b.collector,
+    )
+  }

553-559: Log the block tag via String(), not fmt on the pointer.
fmt.Sprintf("%v", *ptr) can produce less clear output. String() yields canonical form.

Apply:

-    RawJSON("args", txArgs).
-    Str("blockTag", fmt.Sprintf("%v", blockNumberOrHash)).
+    RawJSON("args", txArgs).
+    Str("blockTag", blockNumberOrHash.String()).

715-718: Repeat the safe-local-copy pattern for EstimateGas.
Same reasoning as in Call.

Apply:

-  // Default to "latest" block tag
-  if blockNumberOrHash == nil {
-    blockNumberOrHash = &latestBlockNumberOrHash
-  }
+  // Default to "latest" block tag
+  if blockNumberOrHash == nil {
+    defaultTag := latestBlockNumberOrHash
+    blockNumberOrHash = &defaultTag
+  }

720-729: Return marshaling errors with endpoint context in EstimateGas too.
Mirror the Call improvements for consistent diagnostics.

Apply:

-  if err != nil {
-    return handleError[hexutil.Uint64](err, b.logger, b.collector)
-  }
+  if err != nil {
+    return handleError[hexutil.Uint64](
+      err,
+      b.logger.With().Str("endpoint", EthEstimateGas).Str("blockTag", blockNumberOrHash.String()).Logger(),
+      b.collector,
+    )
+  }
@@
-  if err != nil {
-    return handleError[hexutil.Uint64](err, b.logger, b.collector)
-  }
+  if err != nil {
+    return handleError[hexutil.Uint64](
+      err,
+      b.logger.With().Str("endpoint", EthEstimateGas).Str("blockTag", blockNumberOrHash.String()).Logger(),
+      b.collector,
+    )
+  }

730-735: Use String() for the block tag in logs.
Matches Call and avoids pointer formatting.

Apply:

-    RawJSON("args", txArgs).
-    Str("blockTag", fmt.Sprintf("%v", blockNumberOrHash)).
+    RawJSON("args", txArgs).
+    Str("blockTag", blockNumberOrHash.String()).
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 742085b and 6ac7a9c.

📒 Files selected for processing (1)
  • api/api.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
api/api.go (2)
api/rpc_calls.go (2)
  • EthCall (18-18)
  • EthEstimateGas (21-21)
api/debug.go (1)
  • d (134-252)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (4)
api/api.go (4)

5-5: Import for JSON marshaling looks good.
Used by new RawJSON logging; no issues.


565-565: Validate via short form: LGTM.
Concise and consistent with surrounding code.


741-741: Args.Validate short form: LGTM.
Keeps style consistent and readable.


34-34: Ignore pointer‐mutation warning for latestBlockNumberOrHash. The resolveBlockTag implementation never writes through its *rpc.BlockNumberOrHash argument, so sharing the package‐level sentinel by address does not introduce mutation or race risks.

Likely an incorrect or invalid review comment.

@m-Peter
m-Peter force-pushed the mpeter/logging-improvements branch from 6ac7a9c to 7b39866 Compare September 12, 2025 09:34
@m-Peter
m-Peter force-pushed the mpeter/logging-improvements branch from 7b39866 to 3b0ecdf Compare September 17, 2025 05:45
@m-Peter
m-Peter merged commit 41352c8 into main Sep 17, 2025
2 checks passed
@m-Peter
m-Peter deleted the mpeter/logging-improvements branch September 17, 2025 05:51
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.

Improve logging for eth_call & eth_estimateGas

2 participants