github.com/Finschia/finschia-sdk@v0.48.1/types/module/configurator.go (about) 1 package module 2 3 import ( 4 "fmt" 5 6 "github.com/gogo/protobuf/grpc" 7 8 "github.com/Finschia/finschia-sdk/codec" 9 sdk "github.com/Finschia/finschia-sdk/types" 10 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 11 ) 12 13 // Configurator provides the hooks to allow modules to configure and register 14 // their services in the RegisterServices method. It is designed to eventually 15 // support module object capabilities isolation as described in 16 // https://github.com/cosmos/cosmos-sdk/issues/7093 17 type Configurator interface { 18 // MsgServer returns a grpc.Server instance which allows registering services 19 // that will handle TxBody.messages in transactions. These Msg's WILL NOT 20 // be exposed as gRPC services. 21 MsgServer() grpc.Server 22 23 // QueryServer returns a grpc.Server instance which allows registering services 24 // that will be exposed as gRPC services as well as ABCI query handlers. 25 QueryServer() grpc.Server 26 27 // RegisterMigration registers an in-place store migration for a module. The 28 // handler is a migration script to perform in-place migrations from version 29 // `forVersion` to version `forVersion+1`. 30 // 31 // EACH TIME a module's ConsensusVersion increments, a new migration MUST 32 // be registered using this function. If a migration handler is missing for 33 // a particular function, the upgrade logic (see RunMigrations function) 34 // will panic. If the ConsensusVersion bump does not introduce any store 35 // changes, then a no-op function must be registered here. 36 RegisterMigration(moduleName string, forVersion uint64, handler MigrationHandler) error 37 } 38 39 type configurator struct { 40 cdc codec.Codec 41 msgServer grpc.Server 42 queryServer grpc.Server 43 44 // migrations is a map of moduleName -> forVersion -> migration script handler 45 migrations map[string]map[uint64]MigrationHandler 46 } 47 48 // NewConfigurator returns a new Configurator instance 49 func NewConfigurator(cdc codec.Codec, msgServer grpc.Server, queryServer grpc.Server) Configurator { 50 return configurator{ 51 cdc: cdc, 52 msgServer: msgServer, 53 queryServer: queryServer, 54 migrations: map[string]map[uint64]MigrationHandler{}, 55 } 56 } 57 58 var _ Configurator = configurator{} 59 60 // MsgServer implements the Configurator.MsgServer method 61 func (c configurator) MsgServer() grpc.Server { 62 return c.msgServer 63 } 64 65 // QueryServer implements the Configurator.QueryServer method 66 func (c configurator) QueryServer() grpc.Server { 67 return c.queryServer 68 } 69 70 // RegisterMigration implements the Configurator.RegisterMigration method 71 func (c configurator) RegisterMigration(moduleName string, forVersion uint64, handler MigrationHandler) error { 72 if forVersion == 0 { 73 return sdkerrors.Wrap(sdkerrors.ErrInvalidVersion, "module migration versions should start at 1") 74 } 75 76 if c.migrations[moduleName] == nil { 77 c.migrations[moduleName] = map[uint64]MigrationHandler{} 78 } 79 80 if c.migrations[moduleName][forVersion] != nil { 81 return sdkerrors.Wrapf(sdkerrors.ErrLogic, "another migration for module %s and version %d already exists", moduleName, forVersion) 82 } 83 84 c.migrations[moduleName][forVersion] = handler 85 86 return nil 87 } 88 89 // runModuleMigrations runs all in-place store migrations for one given module from a 90 // version to another version. 91 func (c configurator) runModuleMigrations(ctx sdk.Context, moduleName string, fromVersion, toVersion uint64) error { 92 // No-op if toVersion is the initial version or if the version is unchanged. 93 if toVersion <= 1 || fromVersion == toVersion { 94 return nil 95 } 96 97 moduleMigrationsMap, found := c.migrations[moduleName] 98 if !found { 99 return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "no migrations found for module %s", moduleName) 100 } 101 102 // Run in-place migrations for the module sequentially until toVersion. 103 for i := fromVersion; i < toVersion; i++ { 104 migrateFn, found := moduleMigrationsMap[i] 105 if !found { 106 return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "no migration found for module %s from version %d to version %d", moduleName, i, i+1) 107 } 108 ctx.Logger().Info(fmt.Sprintf("migrating module %s from version %d to version %d", moduleName, i, i+1)) 109 110 err := migrateFn(ctx) 111 if err != nil { 112 return err 113 } 114 } 115 116 return nil 117 }