Skip to content

Commit d245558

Browse files
committed
Updates
1 parent 9df4ff9 commit d245558

9 files changed

Lines changed: 74 additions & 16 deletions

File tree

block/internal/da/forced_inclusion_retriever.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var ErrForceInclusionNotConfigured = errors.New("forced inclusion namespace not
1818
// ForcedInclusionRetriever defines the interface for retrieving forced inclusion transactions from DA.
1919
type ForcedInclusionRetriever interface {
2020
RetrieveForcedIncludedTxs(ctx context.Context, daHeight uint64) (*ForcedInclusionEvent, error)
21+
Start(ctx context.Context)
2122
Stop()
2223
}
2324

@@ -59,7 +60,6 @@ func NewForcedInclusionRetriever(
5960
daStartHeight,
6061
daEpochSize*2, // prefetch window: 2x epoch size
6162
)
62-
asyncFetcher.Start(ctx)
6363

6464
base := &forcedInclusionRetriever{
6565
client: client,
@@ -74,6 +74,11 @@ func NewForcedInclusionRetriever(
7474
return base
7575
}
7676

77+
// Start begins the background prefetcher.
78+
func (r *forcedInclusionRetriever) Start(ctx context.Context) {
79+
r.asyncFetcher.Start(ctx)
80+
}
81+
7782
// Stop stops the background prefetcher.
7883
func (r *forcedInclusionRetriever) Stop() {
7984
r.asyncFetcher.Stop()

block/internal/da/forced_inclusion_tracing.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ func (t *tracedForcedInclusionRetriever) RetrieveForcedIncludedTxs(ctx context.C
4949
return event, nil
5050
}
5151

52+
func (t *tracedForcedInclusionRetriever) Start(ctx context.Context) {
53+
t.inner.Start(ctx)
54+
}
55+
5256
func (t *tracedForcedInclusionRetriever) Stop() {
5357
t.inner.Stop()
5458
}

block/internal/da/subscriber.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ func (s *Subscriber) runSubscription(ctx context.Context) error {
201201

202202
err = s.handler.HandleEvent(ctx, ev, isInline)
203203
if isInline {
204-
if err != nil {
204+
if err == nil {
205+
s.headReached.Store(true)
206+
} else {
205207
s.localDAHeight.Store(local)
206208
s.logger.Debug().Err(err).Uint64("da_height", ev.Height).
207209
Msg("inline processing skipped/failed, rolling back")
208-
} else {
209-
s.headReached.Store(true)
210210
}
211211
}
212212

block/internal/syncing/da_follower.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ func (f *daFollower) HasReachedHead() bool {
9898
// them inline — avoiding a DA re-fetch round trip. Otherwise, it just lets
9999
// the catchup loop handle retrieval.
100100
func (f *daFollower) HandleEvent(ctx context.Context, ev datypes.SubscriptionEvent, isInline bool) error {
101-
if !isInline || len(ev.Blobs) == 0 {
102-
return nil // skip
101+
if !isInline {
102+
return nil // skip: let subscriber just update highestSeenDAHeight
103+
}
104+
if len(ev.Blobs) == 0 {
105+
return errors.New("skip inline: no blobs") // subscriber rolls back, catch-up loop will retry
103106
}
104107

105108
events := f.retriever.ProcessBlobs(ctx, ev.Blobs, ev.Height)
@@ -122,12 +125,6 @@ func (f *daFollower) HandleEvent(ctx context.Context, ev datypes.SubscriptionEve
122125

123126
// HandleCatchup retrieves events at a single DA height and pipes them
124127
// to the event sink. Checks priority heights first.
125-
//
126-
// ErrHeightFromFuture is handled here rather than in fetchAndPipeHeight because
127-
// the two call sites need different behaviour:
128-
// - Normal catchup: mark head reached and return da.ErrCaughtUp to stop the loop.
129-
// - Priority hint: the hint points to a future height — ignore it without
130-
// skipping the current daHeight or stopping catchup.
131128
func (f *daFollower) HandleCatchup(ctx context.Context, daHeight uint64) error {
132129
// 1. Drain stale or future priority heights from P2P hints
133130
for priorityHeight := f.popPriorityHeight(); priorityHeight != 0; priorityHeight = f.popPriorityHeight() {

block/internal/syncing/syncer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ func (s *Syncer) Start(ctx context.Context) (err error) {
182182
}
183183

184184
s.fiRetriever = da.NewForcedInclusionRetriever(ctx, s.daClient, s.logger, s.config.DA.BlockTime.Duration, s.config.Instrumentation.IsTracingEnabled(), s.genesis.DAStartHeight, s.genesis.DAEpochForcedInclusion)
185+
s.fiRetriever.Start(ctx)
185186
s.p2pHandler = NewP2PHandler(s.headerStore, s.dataStore, s.cache, s.genesis, s.logger)
186187

187188
currentHeight, initErr := s.store.Height(ctx)

block/internal/syncing/syncer_backoff_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ func TestDAFollower_InlineProcessing(t *testing.T) {
315315
}
316316

317317
daRetriever.On("ProcessBlobs", mock.Anything, blobs, uint64(10)).Return(expectedEvents).Once()
318-
daRetriever.On("RetrieveFromDA", mock.Anything, uint64(10)).Return(expectedEvents, nil).Maybe()
318+
// Mock RetrieveFromDA for height 10 in case background catch-up fires before HandleEvent.
319+
daRetriever.On("RetrieveFromDA", mock.Anything, uint64(10)).Return(nil, datypes.ErrHeightFromFuture).Maybe()
319320

320321
// Simulate catchup loop to verify it advances naturally
321322
require.NoError(t, follower.Start(t.Context()))
@@ -367,7 +368,7 @@ func TestDAFollower_InlineProcessing(t *testing.T) {
367368

368369
pipeEvent := func(_ context.Context, _ common.DAHeightEvent) error { return nil }
369370

370-
daClient, _ := setupMockDAClient(t)
371+
daClient, eventCh := setupMockDAClient(t)
371372
follower := NewDAFollower(DAFollowerConfig{
372373
Client: daClient,
373374
Retriever: daRetriever,
@@ -377,15 +378,23 @@ func TestDAFollower_InlineProcessing(t *testing.T) {
377378
StartDAHeight: 10,
378379
DABlockTime: 500 * time.Millisecond,
379380
}).(*daFollower)
381+
382+
// Mock RetrieveFromDA because falling through inline processing triggers catchup.
383+
daRetriever.On("RetrieveFromDA", mock.Anything, uint64(10)).Return(nil, datypes.ErrHeightFromFuture).Maybe()
384+
require.NoError(t, follower.Start(t.Context()))
385+
380386
// HandleEvent at current height but no blobs — should fall through
381387
// Subscriber.HandleEvent updates highest internally even if not processed.
382-
follower.HandleEvent(t.Context(), datypes.SubscriptionEvent{
388+
eventCh <- datypes.SubscriptionEvent{
383389
Height: 10,
384390
Blobs: nil,
385-
}, true)
391+
}
386392

387393
// ProcessBlobs should NOT have been called
388394
daRetriever.AssertNotCalled(t, "ProcessBlobs", mock.Anything, mock.Anything, mock.Anything)
395+
require.Eventually(t, func() bool {
396+
return follower.subscriber.LocalDAHeight() == 10 && follower.subscriber.HighestSeenDAHeight() == 10
397+
}, 100*time.Millisecond, 2*time.Millisecond)
389398
assert.Equal(t, uint64(10), follower.subscriber.LocalDAHeight(), "localDAHeight should not change")
390399
assert.Equal(t, uint64(10), follower.subscriber.HighestSeenDAHeight(), "highestSeen should be updated")
391400
})

block/public.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type ForcedInclusionEvent = da.ForcedInclusionEvent
7878
type ForcedInclusionRetriever interface {
7979
RetrieveForcedIncludedTxs(ctx context.Context, daHeight uint64) (*ForcedInclusionEvent, error)
8080
Stop()
81+
Start(ctx context.Context)
8182
}
8283

8384
// NewForcedInclusionRetriever creates a new forced inclusion retriever.

pkg/sequencers/common/forced_inclusion_retriever_mock.go

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sequencers/single/sequencer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ func (c *Sequencer) GetNextBatch(ctx context.Context, req coresequencer.GetNextB
203203
c.fiRetriever.Stop()
204204
}
205205
c.fiRetriever = block.NewForcedInclusionRetriever(ctx, c.daClient, c.cfg, c.logger, c.getInitialDAStartHeight(ctx), c.genesis.DAEpochForcedInclusion)
206+
c.fiRetriever.Start(ctx)
206207
}
207208

208209
// If we have no cached transactions or we've consumed all from the current epoch,

0 commit comments

Comments
 (0)