Skip to content

Commit 668baf3

Browse files
committed
feat: enhanced lightnode reorg observability
1 parent 5e5c333 commit 668baf3

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

op-node/metrics/metrics.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type Metricer interface {
3535
SetSequencerState(active bool)
3636
RecordPipelineReset()
3737
RecordFollowSourceRequest(result string)
38+
RecordFollowSourceReorg(action string)
39+
RecordSuperAuthorityReorgSignal(reason string)
3840
RecordSequencingError()
3941
RecordPublishingError()
4042
RecordDerivationError()
@@ -84,8 +86,10 @@ type Metrics struct {
8486
L1SourceCache *metrics.CacheMetrics
8587
L2SourceCache *metrics.CacheMetrics
8688

87-
L2FollowSourceCache *metrics.CacheMetrics
88-
FollowSourceRequests *prometheus.CounterVec
89+
L2FollowSourceCache *metrics.CacheMetrics
90+
FollowSourceRequests *prometheus.CounterVec
91+
FollowSourceReorgs *prometheus.CounterVec
92+
SuperAuthorityReorgSignals *prometheus.CounterVec
8993

9094
DerivationIdle prometheus.Gauge
9195

@@ -198,6 +202,8 @@ func NewMetrics(procName string, labels prometheus.Labels) *Metrics {
198202
Name: "follow_source_requests_total",
199203
Help: "Count of follow source requests by result",
200204
}, []string{"result"}),
205+
FollowSourceReorgs: factory.NewCounterVec(prometheus.CounterOpts{Namespace: ns, Name: "follow_source_reorgs_total", Help: "Count of follow source reorg decisions by action"}, []string{"action"}),
206+
SuperAuthorityReorgSignals: factory.NewCounterVec(prometheus.CounterOpts{Namespace: ns, Name: "super_authority_reorg_signals_total", Help: "Count of super authority reorg signals by reason"}, []string{"reason"}),
201207

202208
DerivationIdle: factory.NewGauge(prometheus.GaugeOpts{
203209
Namespace: ns,
@@ -515,6 +521,14 @@ func (m *Metrics) RecordFollowSourceRequest(result string) {
515521
m.FollowSourceRequests.WithLabelValues(result).Inc()
516522
}
517523

524+
func (m *Metrics) RecordFollowSourceReorg(action string) {
525+
m.FollowSourceReorgs.WithLabelValues(action).Inc()
526+
}
527+
528+
func (m *Metrics) RecordSuperAuthorityReorgSignal(reason string) {
529+
m.SuperAuthorityReorgSignals.WithLabelValues(reason).Inc()
530+
}
531+
518532
func (m *Metrics) RecordSequencerReset() {
519533
m.SequencerResets.Record()
520534
}
@@ -670,6 +684,12 @@ func (n *noopMetricer) RecordPipelineReset() {
670684
func (n *noopMetricer) RecordFollowSourceRequest(result string) {
671685
}
672686

687+
func (n *noopMetricer) RecordFollowSourceReorg(action string) {
688+
}
689+
690+
func (n *noopMetricer) RecordSuperAuthorityReorgSignal(reason string) {
691+
}
692+
673693
func (n *noopMetricer) RecordSequencingError() {
674694
}
675695

op-node/rollup/engine/engine_controller.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ func (e *EngineController) resolveVerifiedAsSafe(block eth.BlockID) eth.L2BlockR
251251
}
252252
br, err := e.engine.L2BlockRefByHash(e.ctx, block.Hash)
253253
if err != nil {
254+
e.metrics.RecordSuperAuthorityReorgSignal("unknown_to_engine")
254255
e.log.Warn("super authority safe head unknown to engine (reorg signal)",
255256
"super_authority_safe", block, "err", err)
256257
return e.crossSafeFallback("el-unknown")
@@ -260,6 +261,7 @@ func (e *EngineController) resolveVerifiedAsSafe(block eth.BlockID) eth.L2BlockR
260261
"super_authority_safe", br, "err", err)
261262
return e.crossSafeFallback("canonicality-lookup-failed")
262263
} else if !canonical {
264+
e.metrics.RecordSuperAuthorityReorgSignal("non_canonical")
263265
e.log.Warn("super authority safe head non-canonical (reorg signal)",
264266
"super_authority_safe", br, "canonical", canonicalRef)
265267
return e.crossSafeFallback("non-canonical")
@@ -1602,6 +1604,12 @@ func (e *EngineController) FollowSource(eSafeBlockRef, eLocalSafeRef, eFinalized
16021604

16031605
// External local safe is found locally but differs: the follower diverged from upstream
16041606
// and must reorg onto it.
1607+
e.log.Warn("Follow Source: local safe diverged from upstream",
1608+
"external_local_safe", eLocalSafeRef,
1609+
"local_safe", e.localSafeHead,
1610+
"local_unsafe", e.unsafeHead,
1611+
"external_safe", eSafeBlockRef,
1612+
"finalized", eFinalizedRef)
16051613
if e.originSelectorResetter != nil {
16061614
// This follower is also a sequencer (the origin-selector resetter is wired only when
16071615
// sequencing is enabled). A soft unsafe-head update would be clobbered by the next
@@ -1610,12 +1618,24 @@ func (e *EngineController) FollowSource(eSafeBlockRef, eLocalSafeRef, eFinalized
16101618
// cancels the in-flight build and FCUs onto the upstream chain in one shot (head==safe);
16111619
// the sequencer then rebuilds from there.
16121620
logger.Warn("Follow Source: Reorg onto upstream chain")
1621+
e.metrics.RecordFollowSourceReorg("force_reset")
16131622
e.forceReset(e.ctx, eLocalSafeRef, eLocalSafeRef, eLocalSafeRef, eSafeBlockRef, eFinalizedRef, false)
1623+
e.log.Info("Follow Source: reorg onto upstream chain completed",
1624+
"action", "force_reset",
1625+
"local_safe", e.localSafeHead,
1626+
"local_unsafe", e.unsafeHead,
1627+
"cross_safe", e.SafeL2Head())
16141628
return
16151629
}
16161630

16171631
// Pure verifier (no local block production): a soft update suffices and may trigger or
16181632
// retarget EL sync.
1633+
e.metrics.RecordFollowSourceReorg("soft_update")
16191634
logger.Warn("Follow Source: Reorg. May Trigger EL sync")
16201635
followExternalRefs(true)
1636+
e.log.Info("Follow Source: upstream refs applied",
1637+
"action", "soft_update",
1638+
"local_safe", e.localSafeHead,
1639+
"local_unsafe", e.unsafeHead,
1640+
"cross_safe", e.SafeL2Head())
16211641
}

0 commit comments

Comments
 (0)