-
Notifications
You must be signed in to change notification settings - Fork 245
feat(tracing): adding block production tracing #2980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Claude finished @chatton's task in 2m 37s —— View job Code Review: Block Production TracingI'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: ✅ Strengths1. Excellent Architectural Design
2. Comprehensive Test Coverage
3. Context Propagation is Correct
4. Span Attributes Are Well-Chosen
🔍 Issues & RecommendationsCritical Issues1. Missing Coverage in executor.go (block/internal/executing/executor.go:672) The 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:
Recommendation: Change Medium Priority Issues2. 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 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 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 / Suggestions5. Missing godoc for Exported Function
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 Current pattern is fine if it's intentional for simplicity, but testify mocks would provide:
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
🔒 Security Review
⚡ Performance Review
🧪 Testing ReviewCoverage Analysis:
Test Quality:
📝 Summary & RecommendationOverall 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:
Gemini's Review Feedback: Great work on maintaining consistency with the tracing pattern established in previous PRs! 🎉 |
|
The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).
|
Summary of ChangesHello @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 Highlights
🧠 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 AssistThe 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
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 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
|
Codecov Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this 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.
| logger: logger.With().Str("component", "executor").Logger(), | ||
| }, nil | ||
| } | ||
| e.blockProducer = e |
There was a problem hiding this comment.
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.
* 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)
Overview
Follows the same pattern as before and extracts a
BlockProducerinterface and introduces a tracing implementation which wraps the real one and is wrapped when telemetry is enabled.