Conversation
|
The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).
|
|
Claude finished @alpe's task in 2m 16s —— View job Code Review
SummaryThis is a solid architectural refactoring that centralises DA subscription lifecycle management into a shared Critical / Bugs1.
2. Prefetch in for h := daHeight + 1; h <= target; h++ {
...
if err := f.fetchAndCacheBlock(ctx, h); err != nil {
return err // returns ErrHeightFromFuture, rolls back localDAHeight
}
}The prefetch loop returns 3. func (f *asyncBlockRetriever) HandleEvent(..., isInline bool) error {
f.cacheBlock(...)
if isInline {
return errors.New("async block retriever relies on catchup state machine")
}
return nil
}The subscriber code path for Architecture / Design4. func (s *Subscriber) Stop() {
if s.cancel != nil {
s.cancel()
}
s.wg.Wait()
}If 5. Inline CAS logic is fragile — local := s.localDAHeight.Load()
isInline := ev.Height == local && s.localDAHeight.CompareAndSwap(local, local+1)The inline path is claimed when 6. for i := 1; i < len(s.namespaces); i++ {
if bytes.Equal(s.namespaces[i], s.namespaces[0]) {
continue // Same namespace, skip duplicate.
}This skips Error Handling7. f.cleanupOldBlocks(context.Background(), height)Using 8. default:
f.logger.Debug().
...
Msg("failed to retrieve block - will retry")
}
return nilUnknown status codes log a debug message and return Performance9. Priority-height queue grows unboundedly —
10. Cache cleanup uses a full scan —
Testing11. There are no tests for:
The 12. Test: assert.Equal(t, uint64(100), sub.LocalDAHeight(), "should roll back to 100 on future error")When Minor / Style13. if len(f.priorityHeights) == 0 {
f.priorityHeights = nil
}This nil-sets the slice when empty to save memory. While not wrong, it's inconsistent: 14. break // continue with daHeightThe comment says "continue with daHeight" but the 15. Deprecated The Documentation16. // Returning (false, nil) rolls back localDAHeight without triggering a backoff.The actual signature is Checklist
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
* main: fix: persist snapshot once for avoiding badger vlog (#3153) build(deps): Bump docker/setup-buildx-action from 3 to 4 (#3148) build(deps): Bump the all-go group across 5 directories with 8 updates (#3147) build(deps): Bump docker/login-action from 3 to 4 (#3149) build(deps): Bump docker/build-push-action from 6 to 7 (#3151) build(deps): Bump actions/setup-go from 6.2.0 to 6.3.0 (#3150)
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3146 +/- ##
==========================================
+ Coverage 60.20% 60.49% +0.28%
==========================================
Files 115 117 +2
Lines 11896 11939 +43
==========================================
+ Hits 7162 7222 +60
+ Misses 3923 3899 -24
- Partials 811 818 +7
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:
|
* main: chore: fix some function names in comment (#3156)
Resolves #3145
Refactor DA Subscriptions and Follower Logic
Summary
This PR introduces a unified
da.Subscriberprimitive to manage the follow and catch-up lifecycle for DA blobs. Previously, the syncing (DAFollower) and forced inclusion (asyncBlockRetriever) systems duplicated aspects of this logic, leading to subtle bugs spanning error handling, backoff retries, and cache memory leaks.By abstracting the subscription management into a dedicated Subscriber component, we centralize stream merging, height tracking, and fallback handling. Both
DAFollowerandasyncBlockRetrievernow simply implement the SubscriberHandler interface to receive HandleEvent (for inline processing) and HandleCatchup callbacks.Key Changes
da.SubscriberPrimitive: Encapsulates DA subscription logic. Manages an internal followLoop (for inline events) and a catchupLoop (for robust, sequential catch-up when falling behind). Includes support for merging events from multiple DA namespaces.DAFollower&asyncBlockRetriever: Both components now compose ada.Subscriberand implement SubscriberHandler, reducing duplicate boilerplate and abstracting away the complex gap-filling logic.syncer_backoff_test.goand replaced its indirect testing with synchronous unit tests centered aroundda_follower_test.goandda/subscriber_test.go, improving test reliability and execution speed.ErrHeightFromFutureinappropriately triggered backoff retries, and fixed memory leaks associated with stale cache heights in theasyncBlockRetriever.Architecture Overview
flowchart TD DAC[DA Client] -->|Emits SubscriptionEvents| SUB[da.Subscriber] subgraph da [da.Subscriber Component] FL["followLoop<br>Receives live events"] CL["catchupLoop<br>Fills height gaps"] FL -->|Updates highest seen| CL end SUB --> FL FL -->|"HandleEvent (inline processing)"| SH{SubscriberHandler API} CL -->|"HandleCatchup (sequential processing)"| SH ABR["asyncBlockRetriever<br>Forced Inclusions"] -.->|implements| SH DAF["DAFollower<br>Syncing"] -.->|implements| SH