@@ -213,6 +213,24 @@ type Server struct {
213213 // The success rate can be calculated as: catchupSuccesses / catchupAttempts.
214214 // The value persists for the lifetime of the server and is never reset.
215215 catchupSuccesses atomic.Int64
216+
217+ // activeCatchupCtx stores the current catchup context for status reporting to the dashboard.
218+ // This is updated when a catchup operation starts and cleared when it completes.
219+ // Protected by activeCatchupCtxMu for thread-safe access.
220+ activeCatchupCtx * CatchupContext
221+ activeCatchupCtxMu sync.RWMutex
222+
223+ // catchupProgress tracks the current progress through block headers during catchup.
224+ // blocksFetched and blocksValidated are updated as blocks are processed.
225+ // These counters are reset at the start of each catchup operation.
226+ // Protected by activeCatchupCtxMu for thread-safe access.
227+ blocksFetched atomic.Int64
228+ blocksValidated atomic.Int64
229+
230+ // previousCatchupAttempt stores details about the last failed catchup attempt.
231+ // This is used to display in the dashboard why we switched from one peer to another.
232+ // Protected by activeCatchupCtxMu for thread-safe access.
233+ previousCatchupAttempt * PreviousAttempt
216234}
217235
218236// New creates a new block validation server with the provided dependencies.
@@ -427,6 +445,61 @@ func (u *Server) HealthGRPC(ctx context.Context, _ *blockvalidation_api.EmptyMes
427445 }, errors .WrapGRPC (err )
428446}
429447
448+ // GetCatchupStatus returns the current catchup status via gRPC.
449+ // This method provides real-time information about ongoing catchup operations
450+ // for monitoring and dashboard display purposes.
451+ //
452+ // The response includes details about the peer being synced from, progress metrics,
453+ // and timing information. If no catchup is active, the response will indicate
454+ // IsCatchingUp=false and other fields will be empty/zero.
455+ //
456+ // This method is thread-safe and can be called concurrently with catchup operations.
457+ //
458+ // Parameters:
459+ // - ctx: Context for the gRPC request
460+ // - _: Empty request message (unused but required by gRPC interface)
461+ //
462+ // Returns:
463+ // - *blockvalidation_api.CatchupStatusResponse: Current catchup status
464+ // - error: Any error encountered (always nil for this method)
465+ func (u * Server ) GetCatchupStatus (ctx context.Context , _ * blockvalidation_api.EmptyMessage ) (* blockvalidation_api.CatchupStatusResponse , error ) {
466+ status := u .getCatchupStatusInternal ()
467+
468+ resp := & blockvalidation_api.CatchupStatusResponse {
469+ IsCatchingUp : status .IsCatchingUp ,
470+ PeerId : status .PeerID ,
471+ PeerUrl : status .PeerURL ,
472+ TargetBlockHash : status .TargetBlockHash ,
473+ TargetBlockHeight : status .TargetBlockHeight ,
474+ CurrentHeight : status .CurrentHeight ,
475+ TotalBlocks : int32 (status .TotalBlocks ),
476+ BlocksFetched : status .BlocksFetched ,
477+ BlocksValidated : status .BlocksValidated ,
478+ StartTime : status .StartTime ,
479+ DurationMs : status .DurationMs ,
480+ ForkDepth : status .ForkDepth ,
481+ CommonAncestorHash : status .CommonAncestorHash ,
482+ CommonAncestorHeight : status .CommonAncestorHeight ,
483+ }
484+
485+ // Add previous attempt if available
486+ if status .PreviousAttempt != nil {
487+ resp .PreviousAttempt = & blockvalidation_api.PreviousCatchupAttempt {
488+ PeerId : status .PreviousAttempt .PeerID ,
489+ PeerUrl : status .PreviousAttempt .PeerURL ,
490+ TargetBlockHash : status .PreviousAttempt .TargetBlockHash ,
491+ TargetBlockHeight : status .PreviousAttempt .TargetBlockHeight ,
492+ ErrorMessage : status .PreviousAttempt .ErrorMessage ,
493+ ErrorType : status .PreviousAttempt .ErrorType ,
494+ AttemptTime : status .PreviousAttempt .AttemptTime ,
495+ DurationMs : status .PreviousAttempt .DurationMs ,
496+ BlocksValidated : status .PreviousAttempt .BlocksValidated ,
497+ }
498+ }
499+
500+ return resp , nil
501+ }
502+
430503// Init initializes the block validation server with required dependencies and services.
431504// It establishes connections to subtree validation services, configures UTXO store access,
432505// and starts background processing components. This method must be called before Start().
0 commit comments