## Description Ref: #9438 This PR performs the major work of swapping out the v1beta1 msg server and query server for the new one which can process a proposal as an array of messages. This PR still retains the legacy servers which simply wrap around the new ones, providing the same interface as before. In order to keep backwards compatibility, a new msg, `MsgExecLegacyContent` has been created which allows `Content` to become a `Msg` type and still be used as part of the new implementation. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
233 lines
8.0 KiB
Go
233 lines
8.0 KiB
Go
package gov
|
|
|
|
// DONTCOVER
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
|
"github.com/spf13/cobra"
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/types/module"
|
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
|
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta2"
|
|
)
|
|
|
|
var (
|
|
_ module.AppModule = AppModule{}
|
|
_ module.AppModuleBasic = AppModuleBasic{}
|
|
_ module.AppModuleSimulation = AppModule{}
|
|
)
|
|
|
|
// AppModuleBasic defines the basic application module used by the gov module.
|
|
type AppModuleBasic struct {
|
|
cdc codec.Codec
|
|
proposalHandlers []govclient.ProposalHandler // proposal handlers which live in governance cli and rest
|
|
}
|
|
|
|
// NewAppModuleBasic creates a new AppModuleBasic object
|
|
func NewAppModuleBasic(proposalHandlers ...govclient.ProposalHandler) AppModuleBasic {
|
|
return AppModuleBasic{
|
|
proposalHandlers: proposalHandlers,
|
|
}
|
|
}
|
|
|
|
// Name returns the gov module's name.
|
|
func (AppModuleBasic) Name() string {
|
|
return types.ModuleName
|
|
}
|
|
|
|
// RegisterLegacyAminoCodec registers the gov module's types for the given codec.
|
|
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
|
v1beta1.RegisterLegacyAminoCodec(cdc)
|
|
v1beta2.RegisterLegacyAminoCodec(cdc)
|
|
}
|
|
|
|
// DefaultGenesis returns default genesis state as raw bytes for the gov
|
|
// module.
|
|
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
|
|
return cdc.MustMarshalJSON(v1beta1.DefaultGenesisState())
|
|
}
|
|
|
|
// ValidateGenesis performs genesis state validation for the gov module.
|
|
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
|
|
var data v1beta2.GenesisState
|
|
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
|
|
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
|
}
|
|
|
|
return v1beta2.ValidateGenesis(&data)
|
|
}
|
|
|
|
// RegisterRESTRoutes registers the REST routes for the gov module.
|
|
// Deprecated: RegisterRESTRoutes is deprecated. `x/gov` legacy REST implementation
|
|
// has been removed from the SDK.
|
|
func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {}
|
|
|
|
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the gov module.
|
|
func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
|
if err := v1beta2.RegisterQueryHandlerClient(context.Background(), mux, v1beta2.NewQueryClient(clientCtx)); err != nil {
|
|
panic(err)
|
|
}
|
|
if err := v1beta1.RegisterQueryHandlerClient(context.Background(), mux, v1beta1.NewQueryClient(clientCtx)); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetTxCmd returns the root tx command for the gov module.
|
|
func (a AppModuleBasic) GetTxCmd() *cobra.Command {
|
|
proposalCLIHandlers := make([]*cobra.Command, 0, len(a.proposalHandlers))
|
|
for _, proposalHandler := range a.proposalHandlers {
|
|
proposalCLIHandlers = append(proposalCLIHandlers, proposalHandler.CLIHandler())
|
|
}
|
|
|
|
return cli.NewTxCmd(proposalCLIHandlers)
|
|
}
|
|
|
|
// GetQueryCmd returns the root query command for the gov module.
|
|
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
|
|
return cli.GetQueryCmd()
|
|
}
|
|
|
|
// RegisterInterfaces implements InterfaceModule.RegisterInterfaces
|
|
func (a AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
|
v1beta2.RegisterInterfaces(registry)
|
|
v1beta1.RegisterInterfaces(registry)
|
|
}
|
|
|
|
// AppModule implements an application module for the gov module.
|
|
type AppModule struct {
|
|
AppModuleBasic
|
|
|
|
keeper keeper.Keeper
|
|
accountKeeper types.AccountKeeper
|
|
bankKeeper types.BankKeeper
|
|
}
|
|
|
|
// NewAppModule creates a new AppModule object
|
|
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper) AppModule {
|
|
return AppModule{
|
|
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
|
keeper: keeper,
|
|
accountKeeper: ak,
|
|
bankKeeper: bk,
|
|
}
|
|
}
|
|
|
|
// Name returns the gov module's name.
|
|
func (AppModule) Name() string {
|
|
return types.ModuleName
|
|
}
|
|
|
|
// RegisterInvariants registers module invariants
|
|
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
|
|
keeper.RegisterInvariants(ir, am.keeper, am.bankKeeper)
|
|
}
|
|
|
|
// Deprecated: Route returns the message routing key for the gov module.
|
|
func (am AppModule) Route() sdk.Route {
|
|
return sdk.Route{}
|
|
}
|
|
|
|
// QuerierRoute returns the gov module's querier route name.
|
|
func (AppModule) QuerierRoute() string {
|
|
return types.QuerierRoute
|
|
}
|
|
|
|
// LegacyQuerierHandler returns no sdk.Querier.
|
|
func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
|
|
return keeper.NewQuerier(am.keeper, legacyQuerierCdc)
|
|
}
|
|
|
|
// RegisterServices registers module services.
|
|
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
|
msgServer := keeper.NewMsgServerImpl(am.keeper)
|
|
v1beta1.RegisterMsgServer(cfg.MsgServer(), keeper.NewLegacyMsgServerImpl(am.accountKeeper.GetModuleAddress(types.ModuleName).String(), msgServer))
|
|
v1beta2.RegisterMsgServer(cfg.MsgServer(), msgServer)
|
|
|
|
// TODO Register v1beta1 query server.
|
|
// https://github.com/cosmos/cosmos-sdk/issues/10951
|
|
v1beta2.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
|
|
|
m := keeper.NewMigrator(am.keeper)
|
|
err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// InitGenesis performs genesis initialization for the gov module. It returns
|
|
// no validator updates.
|
|
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
|
var genesisState v1beta2.GenesisState
|
|
cdc.MustUnmarshalJSON(data, &genesisState)
|
|
InitGenesis(ctx, am.accountKeeper, am.bankKeeper, am.keeper, &genesisState)
|
|
return []abci.ValidatorUpdate{}
|
|
}
|
|
|
|
// ExportGenesis returns the exported genesis state as raw bytes for the gov
|
|
// module.
|
|
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
|
gs := ExportGenesis(ctx, am.keeper)
|
|
return cdc.MustMarshalJSON(gs)
|
|
}
|
|
|
|
// ConsensusVersion implements AppModule/ConsensusVersion.
|
|
func (AppModule) ConsensusVersion() uint64 { return 2 }
|
|
|
|
// BeginBlock performs a no-op.
|
|
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
|
|
|
// EndBlock returns the end blocker for the gov module. It returns no validator
|
|
// updates.
|
|
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
|
EndBlocker(ctx, am.keeper)
|
|
return []abci.ValidatorUpdate{}
|
|
}
|
|
|
|
// AppModuleSimulation functions
|
|
|
|
// GenerateGenesisState creates a randomized GenState of the gov module.
|
|
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
|
simulation.RandomizedGenState(simState)
|
|
}
|
|
|
|
// ProposalContents returns all the gov content functions used to
|
|
// simulate governance proposals.
|
|
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
|
return simulation.ProposalContents()
|
|
}
|
|
|
|
// RandomizedParams creates randomized gov param changes for the simulator.
|
|
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
|
|
return simulation.ParamChanges(r)
|
|
}
|
|
|
|
// RegisterStoreDecoder registers a decoder for gov module's types
|
|
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
|
}
|
|
|
|
// WeightedOperations returns the all the gov module operations with their respective weights.
|
|
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
|
return simulation.WeightedOperations(
|
|
simState.AppParams, simState.Cdc,
|
|
am.accountKeeper, am.bankKeeper, am.keeper, simState.Contents,
|
|
)
|
|
}
|