diff --git a/internal/models/mock/rollback.go b/internal/models/mock/rollback.go index 514194161..74aabd507 100644 --- a/internal/models/mock/rollback.go +++ b/internal/models/mock/rollback.go @@ -356,6 +356,44 @@ func (c *RollbackLastDiffCall) DoAndReturn(f func(context.Context, int64, string return c } +// Protocols mocks base method. +func (m *MockRollback) Protocols(ctx context.Context, level int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Protocols", ctx, level) + ret0, _ := ret[0].(error) + return ret0 +} + +// Protocols indicates an expected call of Protocols. +func (mr *MockRollbackMockRecorder) Protocols(ctx, level any) *RollbackProtocolsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocols", reflect.TypeOf((*MockRollback)(nil).Protocols), ctx, level) + return &RollbackProtocolsCall{Call: call} +} + +// RollbackProtocolsCall wrap *gomock.Call +type RollbackProtocolsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackProtocolsCall) Return(arg0 error) *RollbackProtocolsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackProtocolsCall) Do(f func(context.Context, int64) error) *RollbackProtocolsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackProtocolsCall) DoAndReturn(f func(context.Context, int64) error) *RollbackProtocolsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + // Rollback mocks base method. func (m *MockRollback) Rollback() error { m.ctrl.T.Helper() diff --git a/internal/models/rollback.go b/internal/models/rollback.go index 74e1ed6dc..63e58a3b5 100644 --- a/internal/models/rollback.go +++ b/internal/models/rollback.go @@ -27,6 +27,7 @@ type Rollback interface { GlobalConstants(ctx context.Context, level int64) ([]contract.GlobalConstant, error) Scripts(ctx context.Context, level int64) ([]contract.Script, error) DeleteScriptsConstants(ctx context.Context, scriptIds []int64, constantsIds []int64) error + Protocols(ctx context.Context, level int64) error Commit() error Rollback() error diff --git a/internal/postgres/rollback.go b/internal/postgres/rollback.go index 167e35979..3afe929f4 100644 --- a/internal/postgres/rollback.go +++ b/internal/postgres/rollback.go @@ -8,6 +8,7 @@ import ( "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/uptrace/bun" ) @@ -133,3 +134,24 @@ func (r Rollback) DeleteScriptsConstants(ctx context.Context, scriptIds []int64, _, err := query.Exec(ctx) return err } + +func (r Rollback) Protocols(ctx context.Context, level int64) error { + result, err := r.tx.NewDelete().Model((*protocol.Protocol)(nil)).Where("start_level >= ?", level).Exec(ctx) + if err != nil { + return err + } + count, err := result.RowsAffected() + if err != nil { + return err + } + if count == 0 { + return nil + } + + _, err = r.tx.NewUpdate(). + Model((*protocol.Protocol)(nil)). + Where("start_level < ?", level). + Set("end_level = 0"). + Exec(ctx) + return err +} diff --git a/internal/postgres/tests/rollback_test.go b/internal/postgres/tests/rollback_test.go index 580ee9b8f..d188c55fe 100644 --- a/internal/postgres/tests/rollback_test.go +++ b/internal/postgres/tests/rollback_test.go @@ -9,6 +9,7 @@ import ( "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/postgres" "github.com/baking-bad/bcdhub/internal/postgres/core" @@ -67,24 +68,26 @@ func (s *RollbackTestSuite) TearDownSuite() { s.Require().NoError(s.psqlContainer.Terminate(ctx)) } -func TestSuiteRollback_Run(t *testing.T) { - suite.Run(t, new(RollbackTestSuite)) -} - -func (s *RollbackTestSuite) TestDeleteAll() { +func (s *RollbackTestSuite) SetupTest() { db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) s.Require().NoError(err) fixtures, err := testfixtures.New( testfixtures.Database(db), testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/blocks.yml"), + testfixtures.Directory("./fixtures"), testfixtures.UseAlterConstraint(), ) s.Require().NoError(err) s.Require().NoError(fixtures.Load()) s.Require().NoError(db.Close()) +} + +func TestSuiteRollback_Run(t *testing.T) { + suite.Run(t, new(RollbackTestSuite)) +} +func (s *RollbackTestSuite) TestDeleteAll() { saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -105,19 +108,6 @@ func (s *RollbackTestSuite) TestDeleteAll() { } func (s *RollbackTestSuite) TestStatesChangedAtLevel() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/big_map_states.yml"), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -133,19 +123,6 @@ func (s *RollbackTestSuite) TestStatesChangedAtLevel() { } func (s *RollbackTestSuite) TestLastDiff() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/big_map_diffs.yml"), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -168,19 +145,6 @@ func (s *RollbackTestSuite) TestLastDiff() { } func (s *RollbackTestSuite) TestDeleteBigMapState() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/big_map_states.yml"), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -199,19 +163,6 @@ func (s *RollbackTestSuite) TestDeleteBigMapState() { } func (s *RollbackTestSuite) TestSaveBigMapState() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/big_map_states.yml"), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -243,19 +194,6 @@ func (s *RollbackTestSuite) TestSaveBigMapState() { } func (s *RollbackTestSuite) TestGetOperations() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files("./fixtures/operations.yml"), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -272,23 +210,6 @@ func (s *RollbackTestSuite) TestGetOperations() { } func (s *RollbackTestSuite) TestGetContractLastActions() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files( - "./fixtures/operations.yml", - "./fixtures/accounts.yml", - "./fixtures/contracts.yml", - ), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -310,23 +231,6 @@ func (s *RollbackTestSuite) TestGetContractLastActions() { } func (s *RollbackTestSuite) TestUpdateContractStats() { - db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) - s.Require().NoError(err) - - fixtures, err := testfixtures.New( - testfixtures.Database(db), - testfixtures.Dialect("postgres"), - testfixtures.Files( - "./fixtures/operations.yml", - "./fixtures/accounts.yml", - "./fixtures/contracts.yml", - ), - testfixtures.UseAlterConstraint(), - ) - s.Require().NoError(err) - s.Require().NoError(fixtures.Load()) - s.Require().NoError(db.Close()) - saver, err := postgres.NewRollback(s.storage.DB) s.Require().NoError(err) @@ -347,3 +251,23 @@ func (s *RollbackTestSuite) TestUpdateContractStats() { s.Require().EqualValues(0, cntrct.TxCount) s.Require().EqualValues(ts.Format(time.RFC3339), cntrct.LastAction.Format(time.RFC3339)) } + +func (s *RollbackTestSuite) TestProtocols() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = saver.Protocols(ctx, 2) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var proto protocol.Protocol + err = s.storage.DB.NewSelect().Model(&proto).Order("id desc").Limit(1).Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(0, proto.EndLevel) + s.Require().EqualValues("Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P", proto.Hash) +} diff --git a/internal/rollback/big_map_states.go b/internal/rollback/big_map_states.go new file mode 100644 index 000000000..4c49b5abe --- /dev/null +++ b/internal/rollback/big_map_states.go @@ -0,0 +1,52 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/logger" +) + +func (rm Manager) rollbackBigMapState(ctx context.Context, level int64) error { + logger.Info().Msg("rollback big map states...") + states, err := rm.rollback.StatesChangedAtLevel(ctx, level) + if err != nil { + return err + } + + for i, state := range states { + diff, err := rm.rollback.LastDiff(ctx, state.Ptr, state.KeyHash, false) + if err != nil { + if rm.storage.IsRecordNotFound(err) { + if err := rm.rollback.DeleteBigMapState(ctx, states[i]); err != nil { + return err + } + continue + } + return err + } + states[i].LastUpdateLevel = diff.Level + states[i].LastUpdateTime = diff.Timestamp + states[i].IsRollback = true + + if len(diff.Value) > 0 { + states[i].Value = diff.ValueBytes() + states[i].Removed = false + } else { + states[i].Removed = true + valuedDiff, err := rm.rollback.LastDiff(ctx, state.Ptr, state.KeyHash, true) + if err != nil { + if !rm.storage.IsRecordNotFound(err) { + return err + } + } else { + states[i].Value = valuedDiff.ValueBytes() + } + } + + if err := rm.rollback.SaveBigMapState(ctx, states[i]); err != nil { + return err + } + } + + return nil +} diff --git a/internal/rollback/operations.go b/internal/rollback/operations.go new file mode 100644 index 000000000..2a5a53e26 --- /dev/null +++ b/internal/rollback/operations.go @@ -0,0 +1,73 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/logger" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/types" +) + +func (rm Manager) rollbackOperations(ctx context.Context, level int64) error { + logger.Info().Msg("rollback operations...") + + ops, err := rm.rollback.GetOperations(ctx, level) + if err != nil { + return err + } + if len(ops) == 0 { + return nil + } + + if err := rm.rollback.DeleteAll(ctx, (*operation.Operation)(nil), level); err != nil { + return err + } + + contracts := make(map[int64]int64) + for i := range ops { + if ops[i].IsOrigination() { + continue + } + if ops[i].Destination.Type == types.AccountTypeContract { + if _, ok := contracts[ops[i].DestinationID]; !ok { + contracts[ops[i].DestinationID] = 1 + } else { + contracts[ops[i].DestinationID] += 1 + } + } + if ops[i].Source.Type == types.AccountTypeContract { + if _, ok := contracts[ops[i].SourceID]; !ok { + contracts[ops[i].SourceID] = 1 + } else { + contracts[ops[i].SourceID] += 1 + } + } + } + + if len(contracts) == 0 { + return nil + } + + addresses := make([]int64, 0, len(contracts)) + for address := range contracts { + addresses = append(addresses, address) + } + + actions, err := rm.rollback.GetContractsLastAction(ctx, addresses...) + if err != nil { + return err + } + + for i := range actions { + count, ok := contracts[actions[i].AccountId] + if !ok { + count = 1 + } + + if err := rm.rollback.UpdateContractStats(ctx, actions[i].AccountId, actions[i].Time, count); err != nil { + return err + } + } + + return nil +} diff --git a/internal/rollback/rollback.go b/internal/rollback/rollback.go index 83836636e..26a25dafa 100644 --- a/internal/rollback/rollback.go +++ b/internal/rollback/rollback.go @@ -11,7 +11,6 @@ import ( "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" - "github.com/baking-bad/bcdhub/internal/models/operation" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" @@ -22,7 +21,7 @@ import ( type Manager struct { storage models.GeneralRepository blockRepo block.Repository - saver models.Rollback + rollback models.Rollback } // NewManager - @@ -48,17 +47,16 @@ func (rm Manager) Rollback(ctx context.Context, network types.Network, fromState return err } - if err := rm.rollback(ctx, level); err != nil { + if err := rm.rollbackBlock(ctx, level); err != nil { logger.Error().Err(err).Str("network", network.String()).Msg("rollback error") - return rm.saver.Rollback() + return rm.rollback.Rollback() } } - return rm.saver.Commit() + return rm.rollback.Commit() } -// TODO: rollback protocol -func (rm Manager) rollback(ctx context.Context, level int64) error { +func (rm Manager) rollbackBlock(ctx context.Context, level int64) error { if err := rm.rollbackOperations(ctx, level); err != nil { return err } @@ -71,6 +69,9 @@ func (rm Manager) rollback(ctx context.Context, level int64) error { if err := rm.rollbackAll(ctx, level); err != nil { return err } + if err := rm.rollback.Protocols(ctx, level); err != nil { + return err + } return nil } @@ -85,7 +86,7 @@ func (rm Manager) rollbackAll(ctx context.Context, level int64) error { (*migration.Migration)(nil), (*account.Account)(nil), } { - if err := rm.saver.DeleteAll(ctx, model, level); err != nil { + if err := rm.rollback.DeleteAll(ctx, model, level); err != nil { return err } logger.Info(). @@ -93,150 +94,3 @@ func (rm Manager) rollbackAll(ctx context.Context, level int64) error { } return nil } - -func (rm Manager) rollbackBigMapState(ctx context.Context, level int64) error { - logger.Info().Msg("rollback big map states...") - states, err := rm.saver.StatesChangedAtLevel(ctx, level) - if err != nil { - return err - } - - for i, state := range states { - diff, err := rm.saver.LastDiff(ctx, state.Ptr, state.KeyHash, false) - if err != nil { - if rm.storage.IsRecordNotFound(err) { - if err := rm.saver.DeleteBigMapState(ctx, states[i]); err != nil { - return err - } - continue - } - return err - } - states[i].LastUpdateLevel = diff.Level - states[i].LastUpdateTime = diff.Timestamp - states[i].IsRollback = true - - if len(diff.Value) > 0 { - states[i].Value = diff.ValueBytes() - states[i].Removed = false - } else { - states[i].Removed = true - valuedDiff, err := rm.saver.LastDiff(ctx, state.Ptr, state.KeyHash, true) - if err != nil { - if !rm.storage.IsRecordNotFound(err) { - return err - } - } else { - states[i].Value = valuedDiff.ValueBytes() - } - } - - if err := rm.saver.SaveBigMapState(ctx, states[i]); err != nil { - return err - } - } - - return nil -} - -func (rm Manager) rollbackOperations(ctx context.Context, level int64) error { - logger.Info().Msg("rollback operations...") - - ops, err := rm.saver.GetOperations(ctx, level) - if err != nil { - return err - } - if len(ops) == 0 { - return nil - } - - if err := rm.saver.DeleteAll(ctx, (*operation.Operation)(nil), level); err != nil { - return err - } - - contracts := make(map[int64]int64) - for i := range ops { - if ops[i].IsOrigination() { - continue - } - if ops[i].Destination.Type == types.AccountTypeContract { - if _, ok := contracts[ops[i].DestinationID]; !ok { - contracts[ops[i].DestinationID] = 1 - } else { - contracts[ops[i].DestinationID] += 1 - } - } - if ops[i].Source.Type == types.AccountTypeContract { - if _, ok := contracts[ops[i].SourceID]; !ok { - contracts[ops[i].SourceID] = 1 - } else { - contracts[ops[i].SourceID] += 1 - } - } - } - - if len(contracts) == 0 { - return nil - } - - addresses := make([]int64, 0, len(contracts)) - for address := range contracts { - addresses = append(addresses, address) - } - - actions, err := rm.saver.GetContractsLastAction(ctx, addresses...) - if err != nil { - return err - } - - for i := range actions { - count, ok := contracts[actions[i].AccountId] - if !ok { - count = 1 - } - - if err := rm.saver.UpdateContractStats(ctx, actions[i].AccountId, actions[i].Time, count); err != nil { - return err - } - } - - return nil -} - -func (rm Manager) rollbackScripts(ctx context.Context, level int64) error { - logger.Info().Msg("rollback scripts and global constants...") - constants, err := rm.saver.GlobalConstants(ctx, level) - if err != nil { - return err - } - scripts, err := rm.saver.Scripts(ctx, level) - if err != nil { - return err - } - - constantIds := make([]int64, len(constants)) - for i := range constants { - constantIds[i] = constants[i].ID - } - scriptIds := make([]int64, len(scripts)) - for i := range scripts { - scriptIds[i] = scripts[i].ID - } - - if err := rm.saver.DeleteScriptsConstants(ctx, scriptIds, constantIds); err != nil { - return err - } - - if len(scripts) > 0 { - if err := rm.saver.DeleteAll(ctx, (*contract.Script)(nil), level); err != nil { - return err - } - } - if len(constants) > 0 { - if err := rm.saver.DeleteAll(ctx, (*contract.GlobalConstant)(nil), level); err != nil { - return err - } - } - - return nil -} diff --git a/internal/rollback/rollback_test.go b/internal/rollback/rollback_test.go index a32dc535e..1d00353bf 100644 --- a/internal/rollback/rollback_test.go +++ b/internal/rollback/rollback_test.go @@ -34,7 +34,7 @@ func TestManager_Rollback(t *testing.T) { Return(block.Block{ Level: 11, }, nil). - MaxTimes(1) + Times(1) storage.EXPECT().IsRecordNotFound(sql.ErrNoRows).Return(true).AnyTimes() @@ -113,12 +113,12 @@ func TestManager_Rollback(t *testing.T) { Kind: types.OperationKindTransaction, }, }, nil). - MaxTimes(1) + Times(1) rb.EXPECT(). DeleteAll(gomock.Any(), (*operation.Operation)(nil), level). Return(nil). - MaxTimes(1) + Times(1) ts := time.Now().UTC() rb.EXPECT(). @@ -132,17 +132,17 @@ func TestManager_Rollback(t *testing.T) { Time: ts, }, }, nil). - MaxTimes(1) + Times(1) rb.EXPECT(). UpdateContractStats(gomock.Any(), int64(4), ts, int64(1)). Return(nil). - MaxTimes(1) + Times(1) rb.EXPECT(). UpdateContractStats(gomock.Any(), int64(1), ts, int64(2)). Return(nil). - MaxTimes(1) + Times(1) rb.EXPECT(). StatesChangedAtLevel(gomock.Any(), level). @@ -171,7 +171,7 @@ func TestManager_Rollback(t *testing.T) { Removed: false, }, }, nil). - MaxTimes(1) + Times(1) ptr := int64(10) rb.EXPECT(). @@ -188,12 +188,12 @@ func TestManager_Rollback(t *testing.T) { ProtocolID: 2, OperationID: 10, }, nil). - MaxTimes(1) + Times(1) rb.EXPECT(). LastDiff(gomock.Any(), ptr, "key_hash_2", false). Return(bigmapdiff.BigMapDiff{}, sql.ErrNoRows). - MaxTimes(1) + Times(1) rb.EXPECT(). DeleteBigMapState(gomock.Any(), bigmapdiff.BigMapState{ @@ -209,7 +209,7 @@ func TestManager_Rollback(t *testing.T) { Removed: false, }). Return(nil). - MaxTimes(1) + Times(1) rb.EXPECT(). SaveBigMapState(gomock.Any(), bigmapdiff.BigMapState{ @@ -226,7 +226,7 @@ func TestManager_Rollback(t *testing.T) { IsRollback: true, }). Return(nil). - MaxTimes(1) + Times(1) rb.EXPECT(). GlobalConstants(gomock.Any(), level). @@ -256,6 +256,11 @@ func TestManager_Rollback(t *testing.T) { Return(nil). Times(9) + rb.EXPECT(). + Protocols(gomock.Any(), level). + Return(nil). + Times(1) + rb.EXPECT(). Commit(). Return(nil). diff --git a/internal/rollback/scripts.go b/internal/rollback/scripts.go new file mode 100644 index 000000000..ba94d2637 --- /dev/null +++ b/internal/rollback/scripts.go @@ -0,0 +1,46 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/logger" + "github.com/baking-bad/bcdhub/internal/models/contract" +) + +func (rm Manager) rollbackScripts(ctx context.Context, level int64) error { + logger.Info().Msg("rollback scripts and global constants...") + constants, err := rm.rollback.GlobalConstants(ctx, level) + if err != nil { + return err + } + scripts, err := rm.rollback.Scripts(ctx, level) + if err != nil { + return err + } + + constantIds := make([]int64, len(constants)) + for i := range constants { + constantIds[i] = constants[i].ID + } + scriptIds := make([]int64, len(scripts)) + for i := range scripts { + scriptIds[i] = scripts[i].ID + } + + if err := rm.rollback.DeleteScriptsConstants(ctx, scriptIds, constantIds); err != nil { + return err + } + + if len(scripts) > 0 { + if err := rm.rollback.DeleteAll(ctx, (*contract.Script)(nil), level); err != nil { + return err + } + } + if len(constants) > 0 { + if err := rm.rollback.DeleteAll(ctx, (*contract.GlobalConstant)(nil), level); err != nil { + return err + } + } + + return nil +}