diff --git a/common/version/version.go b/common/version/version.go index 83bff50de..57588b9c0 100644 --- a/common/version/version.go +++ b/common/version/version.go @@ -5,7 +5,7 @@ import ( "runtime/debug" ) -var tag = "v4.4.72" +var tag = "v4.4.73" var commit = func() string { if info, ok := debug.ReadBuildInfo(); ok { diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index b90e70f9e..879c4da9a 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -568,8 +568,26 @@ func (r *Layer2Relayer) ProcessPendingBundles() { switch status { case types.ProvingTaskUnassigned, types.ProvingTaskAssigned: if r.cfg.EnableTestEnvBypassFeatures && utils.NowUTC().Sub(bundle.CreatedAt) > time.Duration(r.cfg.FinalizeBundleWithoutProofTimeoutSec)*time.Second { + // check if last batch is finalized, because in fake finalize bundle mode, the contract does not verify if the previous bundle or batch is finalized. + if bundle.StartBatchIndex == 0 { + log.Error("invalid args: start batch index of bundle is 0", "bundle index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex) + return + } + + lastBatch, err := r.batchOrm.GetBatchByIndex(r.ctx, bundle.StartBatchIndex-1) + if err != nil { + log.Error("failed to get last batch", "batch index", bundle.StartBatchIndex-1, "err", err) + return + } + + if types.RollupStatus(lastBatch.RollupStatus) != types.RollupFinalized { + log.Error("previous bundle or batch is not finalized", "batch index", lastBatch.Index, "batch hash", lastBatch.Hash, "rollup status", types.RollupStatus(lastBatch.RollupStatus)) + return + } + if err := r.finalizeBundle(bundle, false); err != nil { - log.Error("Failed to finalize timeout bundle without proof", "index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, "err", err) + log.Error("failed to finalize timeout bundle without proof", "bundle index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, "err", err) + return } } @@ -577,7 +595,8 @@ func (r *Layer2Relayer) ProcessPendingBundles() { log.Info("Start to roll up zk proof", "bundle hash", bundle.Hash) r.metrics.rollupL2RelayerProcessPendingBundlesFinalizedTotal.Inc() if err := r.finalizeBundle(bundle, true); err != nil { - log.Error("Failed to finalize bundle with proof", "index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, "err", err) + log.Error("failed to finalize bundle with proof", "bundle index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, "err", err) + return } case types.ProvingTaskFailed: @@ -589,7 +608,7 @@ func (r *Layer2Relayer) ProcessPendingBundles() { // stop the ledger, fix the limit, revert all the violating blocks, // chunks, batches, bundles and all subsequent ones, and resume, // i.e. this case requires manual resolution. - log.Error("bundle proving failed", "index", bundle.Index, "hash", bundle.Hash, "proved at", bundle.ProvedAt, "proof time sec", bundle.ProofTimeSec) + log.Error("bundle proving failed", "bundle index", bundle.Index, "bundle hash", bundle.Hash, "proved at", bundle.ProvedAt, "proof time sec", bundle.ProofTimeSec) default: log.Error("encounter unreachable case in ProcessPendingBundles", "proving status", status)