From 5f0797ee64ba9bc314dd6d2c47b80021c43d4c32 Mon Sep 17 00:00:00 2001 From: Harish Marri Date: Sat, 23 Sep 2023 23:39:34 +0530 Subject: [PATCH] add & register params migration --- app/app.go | 7 +++--- exported/onft.go | 13 ++++++++++ keeper/migrator.go | 28 +++++++++++++++++++++ migrations/v2/migrate.go | 37 ++++++++++++++++++++++++++++ migrations/v2/migrator_test.go | 45 ++++++++++++++++++++++++++++++++++ module.go | 22 ++++++++++++++--- 6 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 keeper/migrator.go create mode 100644 migrations/v2/migrate.go create mode 100644 migrations/v2/migrator_test.go diff --git a/app/app.go b/app/app.go index 5d6c594..71b86b7 100644 --- a/app/app.go +++ b/app/app.go @@ -448,7 +448,7 @@ func New( app.AccountKeeper, app.BankKeeper, app.DistrKeeper, - app.GetSubspace(onfttypes.ModuleName), + govModAddress, ) onftModule := onft.NewAppModule( appCodec, @@ -456,6 +456,7 @@ func New( app.AccountKeeper, app.BankKeeper, app.DistrKeeper, + app.GetSubspace(onfttypes.ModuleName), ) // Create static IBC router, add transfer route, then set and seal it @@ -739,7 +740,7 @@ func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { // RegisterAPIRoutes registers all application module routes with the provided // API server. -func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, _ config.APIConfig) { clientCtx := apiSvr.ClientCtx // Register new tx routes from grpc-gateway. @@ -797,7 +798,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(authtypes.ModuleName) paramsKeeper.Subspace(banktypes.ModuleName) - paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) + paramsKeeper.Subspace(stakingtypes.ModuleName) paramsKeeper.Subspace(minttypes.ModuleName) paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName) diff --git a/exported/onft.go b/exported/onft.go index 89fa975..51743a4 100644 --- a/exported/onft.go +++ b/exported/onft.go @@ -1,6 +1,7 @@ package exported import ( + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -20,3 +21,15 @@ type ONFTI interface { GetCreatedTime() time.Time GetRoyaltyShare() sdk.Dec } + +type ( + ParamSet = paramtypes.ParamSet + + // Subspace defines an interface that implements the legacy x/params Subspace + // type. + // + // NOTE: This is used solely for migration of x/params managed parameters. + Subspace interface { + GetParamSet(ctx sdk.Context, ps ParamSet) + } +) diff --git a/keeper/migrator.go b/keeper/migrator.go new file mode 100644 index 0000000..0e6d991 --- /dev/null +++ b/keeper/migrator.go @@ -0,0 +1,28 @@ +package keeper + +import ( + "github.com/OmniFlix/onft/exported" + v2 "github.com/OmniFlix/onft/migrations/v2" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Migrator is a struct for handling in-place state migrations. +type Migrator struct { + keeper Keeper + legacySubspace exported.Subspace +} + +func NewMigrator(k Keeper, ss exported.Subspace) Migrator { + return Migrator{ + keeper: k, + legacySubspace: ss, + } +} + +// Migrate1to2 migrates the onft module state from the consensus version 1 to +// version 2. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the onft +// module state. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + return v2.Migrate(ctx, ctx.KVStore(m.keeper.storeKey), m.legacySubspace, m.keeper.cdc) +} diff --git a/migrations/v2/migrate.go b/migrations/v2/migrate.go new file mode 100644 index 0000000..121670e --- /dev/null +++ b/migrations/v2/migrate.go @@ -0,0 +1,37 @@ +package v2 + +import ( + "github.com/OmniFlix/onft/exported" + "github.com/OmniFlix/onft/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + ModuleName = "onft" +) + +var ParamsKey = []byte{0x07} + +// Migrate migrates the onft module state from the consensus version 1 to +// version 2. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the onft +// module state. +func Migrate( + ctx sdk.Context, + store sdk.KVStore, + legacySubspace exported.Subspace, + cdc codec.BinaryCodec, +) error { + var currParams types.Params + legacySubspace.GetParamSet(ctx, &currParams) + + if err := currParams.ValidateBasic(); err != nil { + return err + } + + bz := cdc.MustMarshal(&currParams) + store.Set(ParamsKey, bz) + + return nil +} diff --git a/migrations/v2/migrator_test.go b/migrations/v2/migrator_test.go new file mode 100644 index 0000000..36c2f07 --- /dev/null +++ b/migrations/v2/migrator_test.go @@ -0,0 +1,45 @@ +package v2_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/OmniFlix/onft" + "github.com/OmniFlix/onft/exported" + v2 "github.com/OmniFlix/onft/migrations/v2" + "github.com/OmniFlix/onft/types" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" +) + +type mockSubspace struct { + ps types.Params +} + +func newMockSubspace(ps types.Params) mockSubspace { + return mockSubspace{ps: ps} +} + +func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) { + *ps.(*types.Params) = ms.ps +} + +func TestMigrate(t *testing.T) { + encCfg := moduletestutil.MakeTestEncodingConfig(onft.AppModuleBasic{}) + cdc := encCfg.Codec + + storeKey := sdk.NewKVStoreKey(v2.ModuleName) + tKey := sdk.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + store := ctx.KVStore(storeKey) + + legacySubspace := newMockSubspace(types.DefaultParams()) + require.NoError(t, v2.Migrate(ctx, store, legacySubspace, cdc)) + + var res types.Params + bz := store.Get(v2.ParamsKey) + require.NoError(t, cdc.Unmarshal(bz, &res)) + require.Equal(t, legacySubspace.ps, res) +} diff --git a/module.go b/module.go index 4412abb..38e3b70 100644 --- a/module.go +++ b/module.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/OmniFlix/onft/exported" "github.com/OmniFlix/onft/simulation" abci "github.com/cometbft/cometbft/abci/types" @@ -28,6 +29,9 @@ var ( _ module.AppModuleSimulation = AppModule{} ) +// ConsensusVersion defines the current onft module consensus version. +const ConsensusVersion = 2 + type AppModuleBasic struct { cdc codec.Codec } @@ -73,6 +77,7 @@ type AppModule struct { accountKeeper types.AccountKeeper bankKeeper types.BankKeeper distributionKeeper types.DistributionKeeper + legacySubspace exported.Subspace } func (am AppModule) RegisterQueryService(server grpc.Server) { @@ -80,7 +85,7 @@ func (am AppModule) RegisterQueryService(server grpc.Server) { } func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, distrKeeper types.DistributionKeeper, + bankKeeper types.BankKeeper, distrKeeper types.DistributionKeeper, ss exported.Subspace, ) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, @@ -88,6 +93,7 @@ func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.Acc accountKeeper: accountKeeper, bankKeeper: bankKeeper, distributionKeeper: distrKeeper, + legacySubspace: ss, } } @@ -99,12 +105,20 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { func (AppModule) QuerierRoute() string { return types.RouterKey } func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + // x/params migration + m := keeper.NewMigrator(am.keeper, am.legacySubspace) + + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(fmt.Sprintf("failed to migrate %s from version 1 to 2: %v", types.ModuleName, err)) + } } func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { @@ -120,7 +134,9 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw gs := ExportGenesis(ctx, am.keeper) return cdc.MustMarshalJSON(gs) } -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { + return ConsensusVersion +} func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}