From e6baa9d785f468315fc28d4991959db311be5551 Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Fri, 15 Nov 2024 17:46:12 +0800 Subject: [PATCH 1/4] fix(rollup-relayer): check parent batch version before committing --- rollup/internal/controller/relayer/l2_relayer.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 964275722f..1eb9bf7012 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -415,6 +415,11 @@ func (r *Layer2Relayer) ProcessPendingBatches() { return } + if dbParentBatch.CodecVersion > dbBatch.CodecVersion { + log.Error("parent batch codec version is greater than current batch codec version", "index", dbBatch.Index, "hash", dbBatch.Hash, "parent codec version", dbParentBatch.CodecVersion, "current codec version", dbBatch.CodecVersion) + return + } + var calldata []byte var blob *kzg4844.Blob codecVersion := encoding.CodecVersion(dbBatch.CodecVersion) From 67da2df8dd667b78e50a51d70723827f8fcccd12 Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Sat, 16 Nov 2024 15:29:11 +0800 Subject: [PATCH 2/4] add more checks --- .../internal/controller/relayer/l2_relayer.go | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 1eb9bf7012..2eed8266fd 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -394,6 +394,14 @@ func (r *Layer2Relayer) ProcessPendingBatches() { return } + // check codec version + for _, dbChunk := range dbChunks { + if dbBatch.CodecVersion != dbChunk.CodecVersion { + log.Error("batch codec version is different from chunk codec version", "batch index", dbBatch.Index, "chunk index", dbChunk.Index, "batch codec version", dbBatch.CodecVersion, "chunk codec version", dbChunk.CodecVersion) + return + } + } + chunks := make([]*encoding.Chunk, len(dbChunks)) for i, c := range dbChunks { blocks, getErr := r.l2BlockOrm.GetL2BlocksInRange(r.ctx, c.StartBlockNumber, c.EndBlockNumber) @@ -534,13 +542,20 @@ func (r *Layer2Relayer) ProcessPendingBundles() { func (r *Layer2Relayer) finalizeBundle(bundle *orm.Bundle, withProof bool) error { // Check batch status before sending `finalizeBundle` tx. - if r.cfg.ChainMonitor.Enabled { - for batchIndex := bundle.StartBatchIndex; batchIndex <= bundle.EndBatchIndex; batchIndex++ { - tmpBatch, getErr := r.batchOrm.GetBatchByIndex(r.ctx, batchIndex) - if getErr != nil { - log.Error("failed to get batch by index", "batch index", batchIndex, "error", getErr) - return getErr - } + for batchIndex := bundle.StartBatchIndex; batchIndex <= bundle.EndBatchIndex; batchIndex++ { + tmpBatch, getErr := r.batchOrm.GetBatchByIndex(r.ctx, batchIndex) + if getErr != nil { + log.Error("failed to get batch by index", "batch index", batchIndex, "error", getErr) + return getErr + } + + // check codec version + if tmpBatch.CodecVersion != bundle.CodecVersion { + log.Error("bundle codec version is different from batch codec version", "bundle index", bundle.Index, "batch index", tmpBatch.Index, "bundle codec version", bundle.CodecVersion, "batch codec version", tmpBatch.CodecVersion) + return errors.New("bundle codec version is different from batch codec version") + } + + if r.cfg.ChainMonitor.Enabled { batchStatus, getErr := r.getBatchStatusByIndex(tmpBatch) if getErr != nil { r.metrics.rollupL2ChainMonitorLatestFailedCall.Inc() From 873d9d9980615acd53887731fd46694ade9ec56e Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Mon, 18 Nov 2024 17:57:27 +0800 Subject: [PATCH 3/4] add bundle codec check --- .../internal/controller/relayer/l2_relayer.go | 17 +++++++++++++++++ rollup/internal/orm/bundle.go | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 2eed8266fd..41b012a8ca 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -541,6 +541,23 @@ func (r *Layer2Relayer) ProcessPendingBundles() { } func (r *Layer2Relayer) finalizeBundle(bundle *orm.Bundle, withProof bool) error { + // Check if current bundle codec version is not less than the preceding one + if bundle.Index > 0 { + prevBundle, err := r.bundleOrm.GetBundleByIndex(r.ctx, bundle.Index-1) + if err != nil { + log.Error("failed to get previous bundle", "current bundle index", bundle.Index, "error", err) + return err + } + if bundle.CodecVersion < prevBundle.CodecVersion { + log.Error("current bundle codec version is less than the preceding one", + "current bundle index", bundle.Index, + "current codec version", bundle.CodecVersion, + "prev bundle index", prevBundle.Index, + "prev codec version", prevBundle.CodecVersion) + return errors.New("current bundle codec version cannot be less than the preceding one") + } + } + // Check batch status before sending `finalizeBundle` tx. for batchIndex := bundle.StartBatchIndex; batchIndex <= bundle.EndBatchIndex; batchIndex++ { tmpBatch, getErr := r.batchOrm.GetBatchByIndex(r.ctx, batchIndex) diff --git a/rollup/internal/orm/bundle.go b/rollup/internal/orm/bundle.go index 3d35be29db..526511798f 100644 --- a/rollup/internal/orm/bundle.go +++ b/rollup/internal/orm/bundle.go @@ -75,6 +75,22 @@ func (o *Bundle) getLatestBundle(ctx context.Context) (*Bundle, error) { return &latestBundle, nil } +// GetBundleByIndex retrieves a bundle by its index from the database. +func (o *Bundle) GetBundleByIndex(ctx context.Context, index uint64) (*Bundle, error) { + db := o.db.WithContext(ctx) + db = db.Model(&Bundle{}) + db = db.Where("index = ?", index) + + var bundle Bundle + if err := db.First(&bundle).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, fmt.Errorf("bundle not found with index: %d", index) + } + return nil, fmt.Errorf("failed to get bundle by index %d: %w", index, err) + } + return &bundle, nil +} + // GetBundles retrieves selected bundles from the database. // The returned bundles are sorted in ascending order by their index. // only used in unit tests. From ea62c6b4d28c73ce008323ad1ae9c8af31fc30e1 Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Mon, 18 Nov 2024 18:37:39 +0800 Subject: [PATCH 4/4] fix unit tests --- .../internal/controller/relayer/l2_relayer.go | 19 +++++++++++-------- rollup/internal/orm/bundle.go | 16 ---------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 41b012a8ca..4d68bf872f 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -542,19 +542,22 @@ func (r *Layer2Relayer) ProcessPendingBundles() { func (r *Layer2Relayer) finalizeBundle(bundle *orm.Bundle, withProof bool) error { // Check if current bundle codec version is not less than the preceding one - if bundle.Index > 0 { - prevBundle, err := r.bundleOrm.GetBundleByIndex(r.ctx, bundle.Index-1) + if bundle.StartBatchIndex > 0 { + prevBatch, err := r.batchOrm.GetBatchByIndex(r.ctx, bundle.StartBatchIndex-1) if err != nil { - log.Error("failed to get previous bundle", "current bundle index", bundle.Index, "error", err) + log.Error("failed to get previous batch", + "current bundle index", bundle.Index, + "start batch index", bundle.StartBatchIndex, + "error", err) return err } - if bundle.CodecVersion < prevBundle.CodecVersion { - log.Error("current bundle codec version is less than the preceding one", + if bundle.CodecVersion < prevBatch.CodecVersion { + log.Error("current bundle codec version is less than the preceding batch", "current bundle index", bundle.Index, "current codec version", bundle.CodecVersion, - "prev bundle index", prevBundle.Index, - "prev codec version", prevBundle.CodecVersion) - return errors.New("current bundle codec version cannot be less than the preceding one") + "prev batch index", prevBatch.Index, + "prev codec version", prevBatch.CodecVersion) + return errors.New("current bundle codec version cannot be less than the preceding batch") } } diff --git a/rollup/internal/orm/bundle.go b/rollup/internal/orm/bundle.go index 526511798f..3d35be29db 100644 --- a/rollup/internal/orm/bundle.go +++ b/rollup/internal/orm/bundle.go @@ -75,22 +75,6 @@ func (o *Bundle) getLatestBundle(ctx context.Context) (*Bundle, error) { return &latestBundle, nil } -// GetBundleByIndex retrieves a bundle by its index from the database. -func (o *Bundle) GetBundleByIndex(ctx context.Context, index uint64) (*Bundle, error) { - db := o.db.WithContext(ctx) - db = db.Model(&Bundle{}) - db = db.Where("index = ?", index) - - var bundle Bundle - if err := db.First(&bundle).Error; err != nil { - if err == gorm.ErrRecordNotFound { - return nil, fmt.Errorf("bundle not found with index: %d", index) - } - return nil, fmt.Errorf("failed to get bundle by index %d: %w", index, err) - } - return &bundle, nil -} - // GetBundles retrieves selected bundles from the database. // The returned bundles are sorted in ascending order by their index. // only used in unit tests.