Skip to content

Conversation

@chatton
Copy link
Contributor

@chatton chatton commented Jan 14, 2026

Overview

Follows the same pattern as before and extracts a BlockProducer interface and introduces a tracing implementation which wraps the real one and is wrapped when telemetry is enabled.

@claude
Copy link
Contributor

claude bot commented Jan 14, 2026

Claude finished @chatton's task in 2m 37s —— View job


Code Review: Block Production Tracing

I've completed a comprehensive review of the tracing implementation. Overall, this is a well-designed and thoughtfully implemented PR that follows solid architectural patterns. Here's my detailed feedback:


✅ Strengths

1. Excellent Architectural Design

  • The decorator pattern with the BlockProducer interface is clean and maintainable
  • Zero-dependency interface follows the project's core package philosophy
  • Conditional tracing via SetBlockProducer allows runtime configuration (block/components.go:223-225)
  • Interface segregation is appropriate - includes only block production methods

2. Comprehensive Test Coverage

  • 91.75% patch coverage is excellent
  • All traced methods have both success and error test cases
  • Tests verify span names, status codes, and attributes correctly
  • Good use of test helpers (setupBlockProducerTrace, requireAttribute)
  • Mock implementation is clean and follows testify patterns

3. Context Propagation is Correct

  • Note: Gemini's review comment about ValidateBlock context is incorrect
  • The interface DOES accept context.Context (block_producer.go:26)
  • Context is properly propagated through all tracing wrappers
  • Child spans correctly inherit parent context

4. Span Attributes Are Well-Chosen

  • Block height, transaction count, and state root provide good observability
  • Attributes are added at the right time (before execution for request data, after for results)
  • Hex encoding for state root is appropriate for readability

🔍 Issues & Recommendations

Critical Issues

1. Missing Coverage in executor.go (block/internal/executing/executor.go:672)

The ValidateBlock implementation ignores the context parameter using _:

func (e *Executor) ValidateBlock(_ context.Context, lastState types.State, header *types.SignedHeader, data *types.Data) error {

Issue: This means the context with trace span information is not being used. While this doesn't break tracing (the span is still created), it misses opportunities for:

  • Cancellation propagation
  • Deadline enforcement
  • Passing trace context to any future sub-operations

Recommendation: Change _ to ctx and pass it to any operations that accept context. If there are currently no such operations, this is a minor issue but should be fixed for consistency and future-proofing.

Fix this →


Medium Priority Issues

2. Incomplete Error Context in tracing.go

Lines tracing.go:54-58 check for nil batch data but don't capture this in spans:

if batchData != nil && batchData.Batch != nil {
    span.SetAttributes(
        attribute.Int("batch.tx_count", len(batchData.Transactions)),
    )
}

Issue: When batchData or batchData.Batch is nil, no attribute is set. Observers can't distinguish between "0 transactions" and "nil batch".

Recommendation: Add an attribute even for nil cases:

if batchData != nil && batchData.Batch != nil {
    span.SetAttributes(
        attribute.Int("batch.tx_count", len(batchData.Transactions)),
    )
} else {
    span.SetAttributes(attribute.Bool("batch.is_nil", true))
}

3. Transaction Count Calculation Duplication (tracing.go:62-66)

txCount := 0
if batchData != nil && batchData.Batch != nil {
    txCount = len(batchData.Transactions)
}

Issue: This logic is duplicated from RetrieveBatch. If the access pattern changes, they could get out of sync.

Recommendation: Extract to a helper method or use a consistent pattern. Consider:

func getTxCount(batchData *BatchData) int {
    if batchData != nil && batchData.Batch != nil {
        return len(batchData.Transactions)
    }
    return 0
}

4. Tracer Name Consistency

Line tracing.go:27:

tracer: otel.Tracer("ev-node/block-executor"),

Issue: Other components might use different naming schemes. Is this consistent with the project's telemetry naming conventions?

Recommendation: Verify this matches the naming scheme used in other traced components (Store, P2P, Config per PR #2972). Consider extracting tracer names to a constants file for consistency.


Minor Issues / Suggestions

5. Missing godoc for Exported Function

WithTracingBlockProducer (tracing.go:24) is exported but has minimal documentation.

Recommendation: Add comprehensive godoc:

// WithTracingBlockProducer decorates the provided BlockProducer with OpenTelemetry tracing spans.
// Each block production operation (ProduceBlock, RetrieveBatch, CreateBlock, ApplyBlock, ValidateBlock)
// will be wrapped in a span with relevant attributes like block height, transaction count, and state root.
// Errors are automatically recorded in spans with error status codes.
//
// This decorator should be applied when telemetry is enabled in the node configuration.
func WithTracingBlockProducer(inner BlockProducer) BlockProducer {

6. Test Mock Can Be Simplified

tracing_test.go:19-26 - The mock uses function fields for each method. Consider using testify's mock.Mock for more idiomatic mocking, or document why function fields were chosen.

Current pattern is fine if it's intentional for simplicity, but testify mocks would provide:

  • Automatic call counting
  • Argument verification
  • Return value sequencing

7. Missing Span Events for Key Milestones

The tracing implementation only uses attributes and error recording. Consider adding span events for important milestones:

func (t *tracedBlockProducer) ApplyBlock(ctx context.Context, header types.Header, data *types.Data) (types.State, error) {
    ctx, span := t.tracer.Start(ctx, "BlockExecutor.ApplyBlock", ...)
    defer span.End()
    
    span.AddEvent("applying_transactions")
    state, err := t.inner.ApplyBlock(ctx, header, data)
    
    if err != nil {
        span.RecordError(err)
        span.SetStatus(codes.Error, err.Error())
        return types.State{}, err
    }
    
    span.AddEvent("transactions_applied")
    span.SetAttributes(attribute.String("state_root", hex.EncodeToString(state.AppHash)))
    return state, nil
}

This would provide more granular timing information in distributed traces.


📊 Code Quality Assessment

Aspect Rating Notes
Architecture ⭐⭐⭐⭐⭐ Excellent use of decorator pattern
Context Handling ⭐⭐⭐⭐ Correct propagation, minor unused context in Executor
Error Handling ⭐⭐⭐⭐⭐ Comprehensive error recording with status codes
Test Coverage ⭐⭐⭐⭐⭐ 91.75% coverage with thorough test cases
Documentation ⭐⭐⭐ Good interface docs, could improve exported function docs
Observability ⭐⭐⭐⭐ Good span attributes, could add events for granularity
Performance ⭐⭐⭐⭐⭐ Minimal overhead, no blocking operations in hot path
Security ⭐⭐⭐⭐⭐ No security concerns, proper handling of sensitive data

🔒 Security Review

  • ✅ No secrets or sensitive data logged in spans
  • ✅ State root is hex-encoded (safe for observability)
  • ✅ Transaction data is not logged (only counts)
  • ✅ No injection vulnerabilities in trace attributes
  • ✅ Context cancellation properly respected

⚡ Performance Review

  • ✅ Tracing decorator adds minimal overhead
  • ✅ No allocations in hot path beyond span creation
  • ✅ Deferred span.End() ensures cleanup
  • ✅ Attribute setting is done efficiently with OTel APIs
  • ✅ No blocking operations introduced

🧪 Testing Review

Coverage Analysis:

  • Missing coverage in executor.go lines related to nil checks and edge cases
  • All tracing wrapper methods have dedicated tests
  • Both success and error paths are tested
  • Span attributes are verified correctly

Test Quality:

  • Tests are well-structured and readable
  • Good use of table-driven patterns (though not used here, individual tests are clear)
  • Mock setup is clean with helper function
  • Assertions are specific and meaningful

📝 Summary & Recommendation

Overall Assessment: ✅ APPROVE with minor suggestions

This PR introduces high-quality tracing instrumentation that follows best practices and integrates cleanly with the existing codebase. The decorator pattern is well-executed, tests are comprehensive, and the implementation adds valuable observability without compromising performance or security.

Before Merging:

  1. Required: Fix the ignored context parameter in Executor.ValidateBlock (line 672)
  2. 🔶 Recommended: Add attributes for nil batch cases in RetrieveBatch
  3. 🔶 Recommended: Improve godoc for WithTracingBlockProducer
  4. 🔶 Optional: Verify tracer naming consistency with other components
  5. 🔶 Optional: Consider adding span events for finer-grained timing

Gemini's Review Feedback:
The Gemini review comment about ValidateBlock context propagation is incorrect. The interface already accepts context.Context and the tracing wrapper correctly propagates it. No changes to the interface are needed.


Great work on maintaining consistency with the tracing pattern established in previous PRs! 🎉


@github-actions
Copy link
Contributor

github-actions bot commented Jan 14, 2026

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedJan 15, 2026, 10:39 AM

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @chatton, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the observability of the block production process by integrating OpenTelemetry tracing. It achieves this through a clean architectural change, introducing a BlockProducer interface and a tracedBlockProducer decorator. This design allows for the instrumentation of critical block creation, retrieval, application, and validation steps, providing invaluable insights into the system's behavior and performance characteristics, all configurable at runtime.

Highlights

  • Tracing Integration: Introduced OpenTelemetry tracing for block production operations, allowing for detailed performance monitoring and debugging.
  • Decorator Pattern for BlockProducer: Refactored the Executor to implement a new BlockProducer interface, enabling the use of a decorator pattern to inject tracing logic without altering core business logic.
  • Conditional Tracing: Tracing can now be enabled or disabled via configuration, providing flexibility for different deployment environments.
  • Detailed Span Attributes: Tracing spans capture relevant attributes such as block height, transaction count, and state root, offering rich context for each traced operation.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 91.75258% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.48%. Comparing base (3146f0c) to head (4577312).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
block/internal/executing/executor.go 75.00% 5 Missing and 1 partial ⚠️
block/components.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2980      +/-   ##
==========================================
+ Coverage   58.19%   58.48%   +0.28%     
==========================================
  Files          99      100       +1     
  Lines        9543     9619      +76     
==========================================
+ Hits         5554     5626      +72     
- Misses       3379     3382       +3     
- Partials      610      611       +1     
Flag Coverage Δ
combined 58.48% <91.75%> (+0.28%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces OpenTelemetry tracing for the block production process, which is a great addition for observability. The implementation uses a clean decorator pattern by defining a BlockProducer interface and wrapping the Executor with a tracedBlockProducer. This approach is well-executed and enhances modularity. Additionally, the changes include several important fixes for context propagation, improving the overall robustness of the code. The new tracing logic is also well-tested. I have one suggestion to improve trace context propagation for the ValidateBlock step to ensure the trace hierarchy is correctly maintained.

Base automatically changed from tracing-part-6 to main January 15, 2026 10:33
logger: logger.With().Str("component", "executor").Logger(),
}, nil
}
e.blockProducer = e
Copy link
Contributor Author

@chatton chatton Jan 15, 2026

Choose a reason for hiding this comment

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

this is a bit "weird" since the non tracing implemention of the interface is the Executor itself, but I didn't want to create one giant Executor interface, we can maybe do that in a followup where we have

type Executor interface {
BlockProducer
BlockSycner
....
}

and we don't need to do this, but for now it can keep the scope of the PR smaller.

@chatton chatton marked this pull request as ready for review January 15, 2026 10:47
@chatton chatton added this pull request to the merge queue Jan 15, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 15, 2026
@chatton chatton added this pull request to the merge queue Jan 15, 2026
Merged via the queue into main with commit 01dcada Jan 15, 2026
33 checks passed
@chatton chatton deleted the tracing-part-7 branch January 15, 2026 14:14
@claude claude bot mentioned this pull request Jan 15, 2026
alpe added a commit that referenced this pull request Jan 15, 2026
* main:
  chore: adding syncing tracing (#2981)
  feat(tracing): adding block production tracing (#2980)
  feat(tracing): Add Store, P2P and Config tracing (#2972)
  chore: fix upgrade test (#2979)
  build(deps): Bump github.com/ethereum/go-ethereum from 1.16.7 to 1.16.8 in /execution/evm/test in the go_modules group across 1 directory (#2974)
  feat(tracing): adding tracing to DA client (#2968)
  chore: create onboarding skill  (#2971)
  test: add e2e tests for force inclusion (part 2) (#2970)
  feat(tracing): adding eth client tracing (#2960)
  test: add e2e tests for force inclusion (#2964)
  build(deps): Bump the all-go group across 4 directories with 10 updates (#2969)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants