From 141a8df143f0b32c1a7fa8c353ec213f9eec9795 Mon Sep 17 00:00:00 2001 From: Jonas Theis <4181434+jonastheis@users.noreply.github.com> Date: Wed, 21 May 2025 16:36:14 +0800 Subject: [PATCH] fix(rollup verifier): nil pointer due to missing `CommittedBatchMeta` (#1188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix nil pointer due to CommittedBatchMeta not being found in the DB and add rewind of L1 sync height to recover from missing CommittedBatchMeta * chore: auto version bump [bot] * formatting * increase rewindL1height to 100 * make sure no underflow --- params/version.go | 2 +- .../rollup_sync_service.go | 35 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 7d8730ddd8..de0b4211f6 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 8 // Minor version component of the current release - VersionPatch = 48 // Patch version component of the current release + VersionPatch = 49 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/rollup_sync_service/rollup_sync_service.go b/rollup/rollup_sync_service/rollup_sync_service.go index 844147e28c..8aba65a1d4 100644 --- a/rollup/rollup_sync_service/rollup_sync_service.go +++ b/rollup/rollup_sync_service/rollup_sync_service.go @@ -42,11 +42,15 @@ const ( // defaultLogInterval is the frequency at which we print the latest processed block. defaultLogInterval = 5 * time.Minute + + // rewindL1Height is the number of blocks to rewind the L1 sync height when a missing batch event is detected. + rewindL1Height = 100 ) var ( finalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) ErrShouldResetSyncHeight = errors.New("ErrShouldResetSyncHeight") + ErrMissingBatchEvent = errors.New("ErrMissingBatchEvent") ) // RollupSyncService collects ScrollChain batch commit/revert/finalize events and stores metadata into db. @@ -223,6 +227,22 @@ func (s *RollupSyncService) fetchRollupEvents() error { return nil } + if errors.Is(err, ErrMissingBatchEvent) { + // make sure no underflow + var rewindTo uint64 + if prevL1Height > rewindL1Height { + rewindTo = prevL1Height - rewindL1Height + } + + // If there's a missing batch event, rewind the L1 sync height by some blocks to re-fetch from L1 RPC and + // replay creating corresponding CommittedBatchMeta in local DB. + // This happens recursively until the missing event has been recovered as we will call fetchRollupEvents again + // with the `L1Height = prevL1Height - rewindL1Height`. + s.callDataBlobSource.SetL1Height(rewindTo) + + return fmt.Errorf("missing batch event, rewinding L1 sync height by %d blocks to %d: %w", rewindL1Height, rewindTo, err) + } + // Reset the L1 height to the previous value to retry fetching the same data. s.callDataBlobSource.SetL1Height(prevL1Height) return fmt.Errorf("failed to parse and update rollup event logs: %w", err) @@ -297,12 +317,18 @@ func (s *RollupSyncService) updateRollupEvents(daEntries da.Entries) error { var err error if index > 0 { if parentCommittedBatchMeta, err = rawdb.ReadCommittedBatchMeta(s.db, index-1); err != nil { - return fmt.Errorf("failed to read parent committed batch meta, batch index: %v, err: %w", index-1, err) + return fmt.Errorf("failed to read parent committed batch meta, batch index: %v, err: %w", index-1, errors.Join(ErrMissingBatchEvent, err)) + } + if parentCommittedBatchMeta == nil { + return fmt.Errorf("parent committed batch meta = nil, batch index: %v, err: %w", index-1, ErrMissingBatchEvent) } } committedBatchMeta, err := rawdb.ReadCommittedBatchMeta(s.db, index) if err != nil { - return fmt.Errorf("failed to read committed batch meta, batch index: %v, err: %w", index, err) + return fmt.Errorf("failed to read committed batch meta, batch index: %v, err: %w", index, errors.Join(ErrMissingBatchEvent, err)) + } + if committedBatchMeta == nil { + return fmt.Errorf("committed batch meta = nil, batch index: %v, err: %w", index, ErrMissingBatchEvent) } chunks, err := s.getLocalChunksForBatch(committedBatchMeta.ChunkBlockRanges) @@ -447,7 +473,10 @@ func (s *RollupSyncService) getCommittedBatchMeta(commitedBatch da.EntryWithBloc if commitedBatch.Version() == encoding.CodecV7 { parentCommittedBatchMeta, err := rawdb.ReadCommittedBatchMeta(s.db, commitedBatch.BatchIndex()-1) if err != nil { - return nil, fmt.Errorf("failed to read parent committed batch meta, batch index: %v, err: %w", commitedBatch.BatchIndex()-1, err) + return nil, fmt.Errorf("failed to read parent committed batch meta, batch index: %v, err: %w", commitedBatch.BatchIndex()-1, errors.Join(ErrMissingBatchEvent, err)) + } + if parentCommittedBatchMeta == nil { + return nil, fmt.Errorf("parent committed batch meta = nil, batch index: %v, err: %w", commitedBatch.BatchIndex()-1, ErrMissingBatchEvent) } // If parent batch has a lower version this means this is the first batch of CodecV7.