diff --git a/bridge/l2/l2_test.go b/bridge/l2/l2_test.go index 306af608e..7a68421c0 100644 --- a/bridge/l2/l2_test.go +++ b/bridge/l2/l2_test.go @@ -77,6 +77,7 @@ func TestFunction(t *testing.T) { t.Run("TestL2RelayerProcessSaveEvents", testL2RelayerProcessSaveEvents) t.Run("testL2RelayerProcessPendingBatches", testL2RelayerProcessPendingBatches) t.Run("testL2RelayerProcessCommittedBatches", testL2RelayerProcessCommittedBatches) + t.Run("testL2RelayerSkipBatches", testL2RelayerSkipBatches) t.Run("testBatchProposer", testBatchProposer) diff --git a/bridge/l2/relayer.go b/bridge/l2/relayer.go index ec8d29636..7e5f29f67 100644 --- a/bridge/l2/relayer.go +++ b/bridge/l2/relayer.go @@ -282,6 +282,13 @@ func (r *Layer2Relayer) ProcessPendingBatches(wg *sync.WaitGroup) { // ProcessCommittedBatches submit proof to layer 1 rollup contract func (r *Layer2Relayer) ProcessCommittedBatches(wg *sync.WaitGroup) { defer wg.Done() + + // set skipped batches in a single db operation + if err := r.db.UpdateSkippedBatches(); err != nil { + log.Error("UpdateSkippedBatches failed", "err", err) + // continue anyway + } + // batches are sorted by batch index in increasing order batches, err := r.db.GetCommittedBatches(1) if err != nil { @@ -311,6 +318,8 @@ func (r *Layer2Relayer) ProcessCommittedBatches(wg *sync.WaitGroup) { return case orm.ProvingTaskFailed, orm.ProvingTaskSkipped: + // note: this is covered by UpdateSkippedBatches, but we keep it for completeness's sake + if err = r.db.UpdateRollupStatus(r.ctx, id, orm.RollupFinalizationSkipped); err != nil { log.Warn("UpdateRollupStatus failed", "id", id, "err", err) } diff --git a/bridge/l2/relayer_test.go b/bridge/l2/relayer_test.go index 84b4404d3..6ca6d6a13 100644 --- a/bridge/l2/relayer_test.go +++ b/bridge/l2/relayer_test.go @@ -203,3 +203,71 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) { assert.NoError(t, err) assert.Equal(t, orm.RollupFinalizing, status) } + +func testL2RelayerSkipBatches(t *testing.T) { + // Create db handler and reset db. + db, err := database.NewOrmFactory(cfg.DBConfig) + assert.NoError(t, err) + assert.NoError(t, migrate.ResetDB(db.GetDB().DB)) + defer db.Close() + + l2Cfg := cfg.L2Config + relayer, err := NewLayer2Relayer(context.Background(), db, l2Cfg.RelayerConfig) + assert.NoError(t, err) + defer relayer.Stop() + + createBatch := func(rollupStatus orm.RollupStatus, provingStatus orm.ProvingStatus) string { + dbTx, err := db.Beginx() + assert.NoError(t, err) + batchID, err := db.NewBatchInDBTx(dbTx, &orm.BlockInfo{}, &orm.BlockInfo{}, "0", 1, 194676) // startBlock & endBlock & parentHash & totalTxNum & totalL2Gas don't really matter here + assert.NoError(t, err) + err = dbTx.Commit() + assert.NoError(t, err) + + err = db.UpdateRollupStatus(context.Background(), batchID, rollupStatus) + assert.NoError(t, err) + + tProof := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} + tInstanceCommitments := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} + err = db.UpdateProofByID(context.Background(), batchID, tProof, tInstanceCommitments, 100) + assert.NoError(t, err) + err = db.UpdateProvingStatus(batchID, provingStatus) + assert.NoError(t, err) + + return batchID + } + + skipped := []string{ + createBatch(orm.RollupCommitted, orm.ProvingTaskSkipped), + createBatch(orm.RollupCommitted, orm.ProvingTaskFailed), + } + + notSkipped := []string{ + createBatch(orm.RollupPending, orm.ProvingTaskSkipped), + createBatch(orm.RollupCommitting, orm.ProvingTaskSkipped), + createBatch(orm.RollupFinalizing, orm.ProvingTaskSkipped), + createBatch(orm.RollupFinalized, orm.ProvingTaskSkipped), + createBatch(orm.RollupPending, orm.ProvingTaskFailed), + createBatch(orm.RollupCommitting, orm.ProvingTaskFailed), + createBatch(orm.RollupFinalizing, orm.ProvingTaskFailed), + createBatch(orm.RollupFinalized, orm.ProvingTaskFailed), + createBatch(orm.RollupCommitted, orm.ProvingTaskVerified), + } + + var wg = sync.WaitGroup{} + wg.Add(1) + relayer.ProcessCommittedBatches(&wg) + wg.Wait() + + for _, id := range skipped { + status, err := db.GetRollupStatus(id) + assert.NoError(t, err) + assert.Equal(t, orm.RollupFinalizationSkipped, status) + } + + for _, id := range notSkipped { + status, err := db.GetRollupStatus(id) + assert.NoError(t, err) + assert.NotEqual(t, orm.RollupFinalizationSkipped, status) + } +} diff --git a/common/version/version.go b/common/version/version.go index 0c440dc7a..ec0eb6ba6 100644 --- a/common/version/version.go +++ b/common/version/version.go @@ -5,7 +5,7 @@ import ( "runtime/debug" ) -var tag = "prealpha-v11.4" +var tag = "prealpha-v11.5" var commit = func() string { if info, ok := debug.ReadBuildInfo(); ok { diff --git a/database/orm/block_batch.go b/database/orm/block_batch.go index 1ba467131..d9e35f2bb 100644 --- a/database/orm/block_batch.go +++ b/database/orm/block_batch.go @@ -406,3 +406,8 @@ func (o *blockBatchOrm) GetAssignedBatchIDs() ([]string, error) { return ids, rows.Close() } + +func (o *blockBatchOrm) UpdateSkippedBatches() error { + _, err := o.db.Exec(o.db.Rebind("update block_batch set rollup_status = ? where (proving_status = ? or proving_status = ?) and rollup_status = ?;"), RollupFinalizationSkipped, ProvingTaskSkipped, ProvingTaskFailed, RollupCommitted) + return err +} diff --git a/database/orm/interface.go b/database/orm/interface.go index 01c014d38..b02c2c798 100644 --- a/database/orm/interface.go +++ b/database/orm/interface.go @@ -151,6 +151,7 @@ type BlockBatchOrm interface { UpdateCommitTxHashAndRollupStatus(ctx context.Context, id string, commitTxHash string, status RollupStatus) error UpdateFinalizeTxHashAndRollupStatus(ctx context.Context, id string, finalizeTxHash string, status RollupStatus) error GetAssignedBatchIDs() ([]string, error) + UpdateSkippedBatches() error GetCommitTxHash(id string) (sql.NullString, error) // for unit tests only GetFinalizeTxHash(id string) (sql.NullString, error) // for unit tests only