diff --git a/x/ccv/consumer/types/keys.go b/x/ccv/consumer/types/keys.go index c9a3d3f5b0..379f52246c 100644 --- a/x/ccv/consumer/types/keys.go +++ b/x/ccv/consumer/types/keys.go @@ -106,6 +106,9 @@ const ( // SlashRecordByteKey is the single byte key storing the consumer's slash record. SlashRecordByteKey + // ParametersKey is the is the single byte key for storing consumer's parameters. + ParametersByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -113,6 +116,10 @@ const ( // Fully defined key func section // +func ParametersKey() []byte { + return []byte{ParametersByteKey} +} + // PortKey returns the key to the port ID in the store func PortKey() []byte { return []byte{PortByteKey} diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index a8cebee284..e1fcbcf733 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -43,6 +43,7 @@ func getAllKeyPrefixes() []byte { PrevStandaloneChainByteKey, PendingPacketsIndexByteKey, SlashRecordByteKey, + ParametersByteKey, } } diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index 1240e242f0..119ee90b82 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -33,7 +33,7 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand(CmdThrottleState()) cmd.AddCommand(CmdThrottledConsumerPacketData()) cmd.AddCommand(CmdRegisteredConsumerRewardDenoms()) - + cmd.AddCommand(CmdProviderParams()) return cmd } @@ -292,7 +292,7 @@ func CmdThrottledConsumerPacketData() *cobra.Command { Short: "Query pending VSCMatured and slash packet data for a consumer chainId", Long: strings.TrimSpace( fmt.Sprintf(`Returns the current pending VSCMatured and slash packet data instances for a consumer chainId. - Queue is ordered by ibc sequence number. + Queue is ordered by ibc sequence number. Example: $ %s query provider throttled-consumer-packet-data foochain `, @@ -356,3 +356,40 @@ $ %s query provider registered-consumer-reward-denoms return cmd } + +// NewQuerySubspaceParamsCmd returns a CLI command handler for querying subspace +// parameters managed by the x/params module. +func CmdProviderParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params [flags]", + Short: "Query values set as provider parameters", + /* Long: strings.TrimSpace( + fmt.Sprintf(`Returns the registered consumer reward denoms. + Example: + $ %s query provider registered-consumer-reward-denoms + `, + version.AppName, + ), + ), */ + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := types.QueryParamsRequest{} + res, err := queryClient.QueryParams(cmd.Context(), &req) + if err != nil { + return err + } + + return clientCtx.PrintProto(&res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/provider/keeper/migrations.go b/x/ccv/provider/keeper/migrations.go new file mode 100644 index 0000000000..3b6db16463 --- /dev/null +++ b/x/ccv/provider/keeper/migrations.go @@ -0,0 +1,28 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" +) + +type Migrator struct { + keeper Keeper +} + +// NewMigrator returns a new Migrator. +func NewMigrator(keeper Keeper) Migrator { + return Migrator{ + keeper: keeper, + } +} + +// MigrateParams migrates the provider module's parameters from the x/params to self store. +func (m Migrator) MigrateParams(ctx sdk.Context, paramSpace paramtypes.Subspace) error { + var params types.Params + paramSpace.GetParamSet(ctx, ¶ms) + + m.keeper.SetParams(ctx, params) + m.keeper.Logger(ctx).Info("successfully migrated provider parameters") + return nil +} diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 491e585f60..2e8098cc5d 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -10,6 +10,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" @@ -27,6 +28,20 @@ func NewMsgServerImpl(keeper *Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} +// UpdateParams updates the params. +func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if k.GetAuthority() != msg.Signer { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Signer) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := k.Keeper.SetParams(ctx, msg.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} + // CreateValidator defines a method for creating a new validator func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssignConsumerKey) (*types.MsgAssignConsumerKeyResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index cfc4e9dfe0..12eba7dab8 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -119,6 +119,15 @@ func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { func (am AppModule) RegisterServices(cfg module.Configurator) { providertypes.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) providertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) + + migrator := keeper.NewMigrator(*am.keeper) + err := cfg.RegisterMigration(am.Name(), 2, + func(ctx sdk.Context) error { + return migrator.MigrateParams(ctx, am.paramSpace) + }) + if err != nil { + panic(err) + } } // InitGenesis performs genesis initialization for the provider module. It returns no validator updates. diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index b33a390c5f..300a83f1db 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -31,6 +31,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { &MsgConsumerAddition{}, &MsgConsumerRemoval{}, &MsgChangeRewardDenoms{}, + &MsgUpdateParams{}, ) registry.RegisterImplementations( (*govv1beta1.Content)(nil), diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index ee4c11015b..f34f29bc4c 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -138,6 +138,9 @@ const ( // handled in the current block VSCMaturedHandledThisBlockBytePrefix + // ParametersKey is the is the single byte key for storing consumer's parameters. + ParametersByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -145,6 +148,10 @@ const ( // Fully defined key func section // +func ParametersKey() []byte { + return []byte{ParametersByteKey} +} + // PortKey returns the key to the port ID in the store func PortKey() []byte { return []byte{PortByteKey} diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index 9f470f4a82..fbdfe1f267 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -54,6 +54,7 @@ func getAllKeyPrefixes() []byte { providertypes.ConsumerAddrsToPruneBytePrefix, providertypes.SlashLogBytePrefix, providertypes.VSCMaturedHandledThisBlockBytePrefix, + providertypes.ParametersByteKey, } }