github.com/cosmos/cosmos-sdk@v0.50.10/x/crisis/module.go (about)

     1  package crisis
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  
     8  	gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
     9  	"github.com/spf13/cast"
    10  	"github.com/spf13/cobra"
    11  
    12  	modulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
    13  	"cosmossdk.io/core/address"
    14  	"cosmossdk.io/core/appmodule"
    15  	"cosmossdk.io/core/store"
    16  	"cosmossdk.io/depinject"
    17  
    18  	"github.com/cosmos/cosmos-sdk/client"
    19  	"github.com/cosmos/cosmos-sdk/codec"
    20  	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    21  	"github.com/cosmos/cosmos-sdk/server"
    22  	servertypes "github.com/cosmos/cosmos-sdk/server/types"
    23  	sdk "github.com/cosmos/cosmos-sdk/types"
    24  	"github.com/cosmos/cosmos-sdk/types/module"
    25  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    26  	"github.com/cosmos/cosmos-sdk/x/crisis/exported"
    27  	"github.com/cosmos/cosmos-sdk/x/crisis/keeper"
    28  	"github.com/cosmos/cosmos-sdk/x/crisis/types"
    29  	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
    30  )
    31  
    32  // ConsensusVersion defines the current x/crisis module consensus version.
    33  const ConsensusVersion = 2
    34  
    35  var (
    36  	_ module.AppModuleBasic = AppModule{}
    37  	_ module.HasGenesis     = AppModule{}
    38  	_ module.HasServices    = AppModule{}
    39  
    40  	_ appmodule.AppModule     = AppModule{}
    41  	_ appmodule.HasEndBlocker = AppModule{}
    42  )
    43  
    44  // Module init related flags
    45  const (
    46  	FlagSkipGenesisInvariants = "x-crisis-skip-assert-invariants"
    47  )
    48  
    49  // AppModuleBasic defines the basic application module used by the crisis module.
    50  type AppModuleBasic struct{}
    51  
    52  // Name returns the crisis module's name.
    53  func (AppModuleBasic) Name() string {
    54  	return types.ModuleName
    55  }
    56  
    57  // RegisterLegacyAminoCodec registers the crisis module's types on the given LegacyAmino codec.
    58  func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    59  	types.RegisterLegacyAminoCodec(cdc)
    60  }
    61  
    62  // DefaultGenesis returns default genesis state as raw bytes for the crisis
    63  // module.
    64  func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
    65  	return cdc.MustMarshalJSON(types.DefaultGenesisState())
    66  }
    67  
    68  // ValidateGenesis performs genesis state validation for the crisis module.
    69  func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
    70  	var data types.GenesisState
    71  	if err := cdc.UnmarshalJSON(bz, &data); err != nil {
    72  		return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
    73  	}
    74  
    75  	return types.ValidateGenesis(&data)
    76  }
    77  
    78  // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the crisis module.
    79  func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *gwruntime.ServeMux) {}
    80  
    81  // RegisterInterfaces registers interfaces and implementations of the crisis
    82  // module.
    83  func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    84  	types.RegisterInterfaces(registry)
    85  }
    86  
    87  // AppModule implements an application module for the crisis module.
    88  type AppModule struct {
    89  	AppModuleBasic
    90  
    91  	// NOTE: We store a reference to the keeper here so that after a module
    92  	// manager is created, the invariants can be properly registered and
    93  	// executed.
    94  	keeper *keeper.Keeper
    95  
    96  	// legacySubspace is used solely for migration of x/params managed parameters
    97  	legacySubspace exported.Subspace
    98  
    99  	skipGenesisInvariants bool
   100  }
   101  
   102  // NewAppModule creates a new AppModule object. If initChainAssertInvariants is set,
   103  // we will call keeper.AssertInvariants during InitGenesis (it may take a significant time)
   104  // - which doesn't impact the chain security unless 66+% of validators have a wrongly
   105  // modified genesis file.
   106  func NewAppModule(keeper *keeper.Keeper, skipGenesisInvariants bool, ss exported.Subspace) AppModule {
   107  	return AppModule{
   108  		AppModuleBasic: AppModuleBasic{},
   109  		keeper:         keeper,
   110  		legacySubspace: ss,
   111  
   112  		skipGenesisInvariants: skipGenesisInvariants,
   113  	}
   114  }
   115  
   116  // IsOnePerModuleType implements the depinject.OnePerModuleType interface.
   117  func (am AppModule) IsOnePerModuleType() {}
   118  
   119  // IsAppModule implements the appmodule.AppModule interface.
   120  func (am AppModule) IsAppModule() {}
   121  
   122  // AddModuleInitFlags implements servertypes.ModuleInitFlags interface.
   123  func AddModuleInitFlags(startCmd *cobra.Command) {
   124  	startCmd.Flags().Bool(FlagSkipGenesisInvariants, false, "Skip x/crisis invariants check on startup")
   125  }
   126  
   127  // RegisterServices registers module services.
   128  func (am AppModule) RegisterServices(cfg module.Configurator) {
   129  	types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
   130  
   131  	m := keeper.NewMigrator(am.keeper, am.legacySubspace)
   132  	if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
   133  		panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err))
   134  	}
   135  }
   136  
   137  // InitGenesis performs genesis initialization for the crisis module. It returns
   138  // no validator updates.
   139  func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) {
   140  	var genesisState types.GenesisState
   141  	cdc.MustUnmarshalJSON(data, &genesisState)
   142  
   143  	am.keeper.InitGenesis(ctx, &genesisState)
   144  	if !am.skipGenesisInvariants {
   145  		am.keeper.AssertInvariants(ctx)
   146  	}
   147  }
   148  
   149  // ExportGenesis returns the exported genesis state as raw bytes for the crisis
   150  // module.
   151  func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
   152  	gs := am.keeper.ExportGenesis(ctx)
   153  	return cdc.MustMarshalJSON(gs)
   154  }
   155  
   156  // ConsensusVersion implements AppModule/ConsensusVersion.
   157  func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }
   158  
   159  // EndBlock returns the end blocker for the crisis module. It returns no validator
   160  // updates.
   161  func (am AppModule) EndBlock(ctx context.Context) error {
   162  	EndBlocker(ctx, *am.keeper)
   163  	return nil
   164  }
   165  
   166  // App Wiring Setup
   167  
   168  func init() {
   169  	appmodule.Register(
   170  		&modulev1.Module{},
   171  		appmodule.Provide(ProvideModule),
   172  	)
   173  }
   174  
   175  type ModuleInputs struct {
   176  	depinject.In
   177  
   178  	Config       *modulev1.Module
   179  	StoreService store.KVStoreService
   180  	Cdc          codec.Codec
   181  	AppOpts      servertypes.AppOptions `optional:"true"`
   182  
   183  	BankKeeper   types.SupplyKeeper
   184  	AddressCodec address.Codec
   185  
   186  	// LegacySubspace is used solely for migration of x/params managed parameters
   187  	LegacySubspace exported.Subspace `optional:"true"`
   188  }
   189  
   190  type ModuleOutputs struct {
   191  	depinject.Out
   192  
   193  	Module       appmodule.AppModule
   194  	CrisisKeeper *keeper.Keeper
   195  }
   196  
   197  func ProvideModule(in ModuleInputs) ModuleOutputs {
   198  	var invalidCheckPeriod uint
   199  	if in.AppOpts != nil {
   200  		invalidCheckPeriod = cast.ToUint(in.AppOpts.Get(server.FlagInvCheckPeriod))
   201  	}
   202  
   203  	feeCollectorName := in.Config.FeeCollectorName
   204  	if feeCollectorName == "" {
   205  		feeCollectorName = authtypes.FeeCollectorName
   206  	}
   207  
   208  	// default to governance authority if not provided
   209  	authority := authtypes.NewModuleAddress(govtypes.ModuleName)
   210  	if in.Config.Authority != "" {
   211  		authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
   212  	}
   213  
   214  	k := keeper.NewKeeper(
   215  		in.Cdc,
   216  		in.StoreService,
   217  		invalidCheckPeriod,
   218  		in.BankKeeper,
   219  		feeCollectorName,
   220  		authority.String(),
   221  		in.AddressCodec,
   222  	)
   223  
   224  	var skipGenesisInvariants bool
   225  	if in.AppOpts != nil {
   226  		skipGenesisInvariants = cast.ToBool(in.AppOpts.Get(FlagSkipGenesisInvariants))
   227  	}
   228  
   229  	m := NewAppModule(k, skipGenesisInvariants, in.LegacySubspace)
   230  
   231  	return ModuleOutputs{CrisisKeeper: k, Module: m}
   232  }