Skip to content

Commit a0dfdef

Browse files
committed
fix: prevent uint64 underflow in ListFinalizedSlots on short-lived chains
When the finalized epoch is smaller than historical_epoch_count (e.g. on a freshly started devnet or kurtosis enclave), the previous expression `latestSlot - SlotsPerEpoch*HistoricalEpochCount` underflows uint64 and produces a value near 2^64, so the loop never executes and the /checkpointz/v1/beacon/slots endpoint returns an empty list — leaving the UI's historical checkpoints table blank until the chain has produced HistoricalEpochCount epochs. Clamp the lower bound at 0 so we return every available finalized epoch-boundary slot, regardless of chain age. Same fix as #241 but targeted at release/gloas so gloas devnets can pick it up without waiting for a master merge.
1 parent 9326d5c commit a0dfdef

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

pkg/beacon/default.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,18 @@ func (d *Default) ListFinalizedSlots(ctx context.Context) ([]phase0.Slot, error)
748748
return slots, errors.New("no finalized checkpoint available")
749749
}
750750

751-
latestSlot := phase0.Slot(uint64(finality.Finalized.Epoch) * uint64(sp.SlotsPerEpoch))
752-
751+
latestSlot := uint64(finality.Finalized.Epoch) * uint64(sp.SlotsPerEpoch)
753752
//nolint:gosec // HistoricalEpochCount is validated as positive in config.
754-
for i, val := uint64(latestSlot), uint64(latestSlot)-uint64(sp.SlotsPerEpoch)*uint64(d.config.HistoricalEpochCount); i > val; i -= uint64(sp.SlotsPerEpoch) {
753+
lookback := uint64(sp.SlotsPerEpoch) * uint64(d.config.HistoricalEpochCount)
754+
755+
// Clamp the lower bound at 0 so short-lived chains (finalized epoch <
756+
// HistoricalEpochCount) don't underflow uint64 and skip the loop entirely.
757+
var earliest uint64
758+
if latestSlot > lookback {
759+
earliest = latestSlot - lookback
760+
}
761+
762+
for i := latestSlot; i > earliest; i -= uint64(sp.SlotsPerEpoch) {
755763
slots = append(slots, phase0.Slot(i))
756764
}
757765

0 commit comments

Comments
 (0)