From 933a6d723104f15478b6c58a1238507f5f144472 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 4 Mar 2026 17:57:55 +0100 Subject: [PATCH] feat: add `Syncer.PendingCount` and use it to ensure the sync pipeline is drained before marking the node as caught up in failover. --- block/internal/syncing/syncer.go | 5 +++++ node/failover.go | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index 848ae9825..69c7fef1b 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -467,6 +467,11 @@ func (s *Syncer) fetchDAUntilCaughtUp(ctx context.Context) error { } } +// PendingCount returns the number of unprocessed height events in the pipeline. +func (s *Syncer) PendingCount() int { + return len(s.heightInCh) +} + func (s *Syncer) pendingWorkerLoop(ctx context.Context) { defer s.wg.Done() diff --git a/node/failover.go b/node/failover.go index f6e0c8d9f..f6fd09a3a 100644 --- a/node/failover.go +++ b/node/failover.go @@ -315,7 +315,8 @@ func (f *failoverState) waitForCatchup(ctx context.Context) (bool, error) { p2pCaughtUp = true } - if daCaughtUp && p2pCaughtUp { + pipelineDrained := f.bc.Syncer == nil || f.bc.Syncer.PendingCount() == 0 + if daCaughtUp && p2pCaughtUp && pipelineDrained { f.logger.Info(). Uint64("store_height", storeHeight). Uint64("max_p2p_height", maxP2PHeight).