Synopsis Cosmos SDK modules need to implement the AppModule interfaces, in order to be managed by the application’s module manager. The module manager plays an important role in message and query routing, and allows application developers to set the order of execution of a variety of functions like BeginBlocker and EndBlocker.

Application Module Interfaces

Application module interfaces exist to facilitate the composition of modules together to form a functional Cosmos SDK application. There are 4 main application module interfaces:
  • AppModuleBasic for independent module functionalities.
  • AppModule for inter-dependent module functionalities (except genesis-related functionalities).
  • AppModuleGenesis for inter-dependent genesis-related module functionalities.
  • GenesisOnlyAppModule: Defines an AppModule that only has import/export functionality
The above interfaces are mostly embedding smaller interfaces (extension interfaces), that defines specific functionalities:
  • HasName: Allows the module to provide its own name for legacy purposes.
  • HasGenesisBasics: The legacy interface for stateless genesis methods.
  • HasGenesis: The extension interface for stateful genesis methods.
  • HasInvariants: The extension interface for registering invariants.
  • HasServices: The extension interface for modules to register services.
  • HasConsensusVersion: The extension interface for declaring a module consensus version.
  • BeginBlockAppModule: The extension interface that contains information about the AppModule and BeginBlock.
  • EndBlockAppModule: The extension interface that contains information about the AppModule and EndBlock.
  • HasPrecommit: The extension interface that contains information about the AppModule and Precommit.
  • HasPrepareCheckState: The extension interface that contains information about the AppModule and PrepareCheckState.
The AppModuleBasic interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the init() function of the main application file. The AppModule interface exists to define inter-dependent module methods. Many modules need to interact with other modules, typically through keepers, which means there is a need for an interface where modules list their keepers and other methods that require a reference to another module’s object. AppModule interface extension, such as BeginBlockAppModule and EndBlockAppModule, also enables the module manager to set the order of execution between module’s methods like BeginBlock and EndBlock, which is important in cases where the order of execution between modules matters in the context of the application. The usage of extension interfaces allows modules to define only the functionalities they need. For example, a module that does not need an EndBlock does not need to define the EndBlockAppModule interface and thus the EndBlock method. AppModule and AppModuleGenesis are voluntarily small interfaces, that can take advantage of the Module patterns without having to define many placeholder functions.

AppModuleBasic

The AppModuleBasic interface defines the independent methods modules need to implement.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
Let us go through the methods:
  • RegisterLegacyAminoCodec(*codec.LegacyAmino): Registers the amino codec for the module, which is used to marshal and unmarshal structs to/from []byte in order to persist them in the module’s KVStore.
  • RegisterInterfaces(codectypes.InterfaceRegistry): Registers a module’s interface types and their concrete implementations as proto.Message.
  • RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux): Registers gRPC routes for the module.
  • GetTxCmd(): Returns the root Tx command for the module. The subcommands of this root command are used by end-users to generate new transactions containing messages defined in the module.
  • GetQueryCmd(): Return the root query command for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module.
All the AppModuleBasic of an application are managed by the BasicManager.

HasName

/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • HasName is an interface that has a method Name(). This method returns the name of the module as a string.

HasGenesisBasics

/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
Let us go through the methods:
  • DefaultGenesis(codec.JSONCodec): Returns a default GenesisState for the module, marshalled to json.RawMessage. The default GenesisState need to be defined by the module developer and is primarily used for testing.
  • ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage): Used to validate the GenesisState defined by a module, given in its json.RawMessage form. It will usually unmarshall the json before running a custom ValidateGenesis function defined by the module developer.

AppModuleGenesis

The AppModuleGenesis interface is a simple embedding of the AppModuleBasic and HasGenesis interfaces.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
It does not have its own manager, and exists separately from AppModule only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of AppModule’s methods.

HasGenesis

The HasGenesis interface is an extension interface of HasGenesisBasics.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
Let us go through the two added methods:
  • InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage): Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started).
  • ExportGenesis(sdk.Context, codec.JSONCodec): Exports the latest subset of the state managed by the module to be used in a new genesis file. ExportGenesis is called for each module when a new chain is started from the state of an existing chain.

AppModule

The AppModule interface defines a module. Modules can declare their functionalities by implementing extensions interfaces.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
AppModules are managed by the module manager, which checks which extension interfaces are implemented by the module.
Previously the AppModule interface was containing all the methods that are defined in the extensions interfaces. This was leading to much boilerplate for modules that did not need all the functionalities.

HasInvariants

This interface defines one method. It allows to checks if a module can register invariants.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • RegisterInvariants(sdk.InvariantRegistry): Registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted).

HasServices

This interface defines one method. It allows to checks if a module can register invariants.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • RegisterServices(Configurator): Allows a module to register services.

HasConsensusVersion

This interface defines one method for checking a module consensus version.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • ConsensusVersion() uint64: Returns the consensus version of the module.

BeginBlockAppModule

The BeginBlockAppModule is an extension interface from AppModule. All modules that have an BeginBlock method implement this interface.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • BeginBlock(sdk.Context, abci.RequestBeginBlock): This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module.

EndBlockAppModule

The EndBlockAppModule is an extension interface from AppModule. All modules that have an EndBlock method implement this interface.
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
  • EndBlock(sdk.Context, abci.RequestEndBlock): This method gives module developers the option to implement logic that is automatically triggered at the end of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the staking module). Implement empty if no logic needs to be triggered at the end of each block for this module.

HasPrecommit

HasPrecommit is an extension interface from AppModule. All modules that have a Precommit method implement this interface.
  • Precommit(sdk.Context): This method gives module developers the option to implement logic that is automatically triggered during [Commit'](../../learn/advanced/00-baseapp.md#commit) of each block using the [deliverState](../../learn/advanced/00-baseapp.md#state-updates) of the block to be committed. Implement empty if no logic needs to be triggered during Commit` of each block for this module.

HasPrepareCheckState

HasPrepareCheckState is an extension interface from AppModule. All modules that have a PrepareCheckState method implement this interface.
  • PrepareCheckState(sdk.Context): This method gives module developers the option to implement logic that is automatically triggered during [Commit'](../../learn/advanced/00-baseapp.md) of each block using the [checkState](../../learn/advanced/00-baseapp.md#state-updates) of the next block. Implement empty if no logic needs to be triggered during Commit` of each block for this module.

Implementing the Application Module Interfaces

Typically, the various application module interfaces are implemented in a file called module.go, located in the module’s folder (e.g. ./x/module/module.go). Almost every module needs to implement the AppModuleBasic and AppModule interfaces. If the module is only used for genesis, it will implement AppModuleGenesis instead of AppModule. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the Route() function often calls a NewMsgServerImpl(k keeper) function defined in keeper/msg_server.go and therefore needs to pass the module’s keeper as a parameter.
// example
type AppModule struct {
    AppModuleBasic
	keeper       Keeper
}
In the example above, you can see that the AppModule concrete type references an AppModuleBasic, and not an AppModuleGenesis. That is because AppModuleGenesis only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete AppModule type will have a reference to an AppModuleBasic and implement the two added methods of AppModuleGenesis directly in the AppModule type. If no parameter is required (which is often the case for AppModuleBasic), just declare an empty concrete type like so:
type AppModuleBasic struct{
}

Module Managers

Module managers are used to manage collections of AppModuleBasic and AppModule.

BasicManager

The BasicManager is a structure that lists all the AppModuleBasic of an application:
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
It implements the following methods:
  • NewBasicManager(modules ...AppModuleBasic): Constructor function. It takes a list of the application’s AppModuleBasic and builds a new BasicManager. This function is generally called in the init() function of app.go to quickly initialize the independent elements of the application’s modules (click here to see an example).
  • RegisterLegacyAminoCodec(cdc *codec.LegacyAmino): Registers the codec.LegacyAminos of each of the application’s AppModuleBasic. This function is usually called early on in the application’s construction.
  • RegisterInterfaces(registry codectypes.InterfaceRegistry): Registers interface types and implementations of each of the application’s AppModuleBasic.
  • DefaultGenesis(cdc codec.JSONCodec): Provides default genesis information for modules in the application by calling the DefaultGenesis(cdc codec.JSONCodec) function of each module. It only calls the modules that implements the HasGenesisBasics interfaces.
  • ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage): Validates the genesis information modules by calling the ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage) function of modules implementing the HasGenesisBasics interface.
  • RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux): Registers gRPC routes for modules.
  • AddTxCommands(rootTxCmd *cobra.Command): Adds modules’ transaction commands to the application’s rootTxCommand. This function is usually called function from the main.go function of the application’s command-line interface.
  • AddQueryCommands(rootQueryCmd *cobra.Command): Adds modules’ query commands to the application’s rootQueryCommand. This function is usually called function from the main.go function of the application’s command-line interface.

Manager

The Manager is a structure that holds all the AppModule of an application, and defines the order of execution between several key components of these modules:
/*
Package module contains application module patterns and associated "manager" functionality.
The module pattern has been broken down by:
  - independent module functionality (AppModuleBasic)
  - inter-dependent module genesis functionality (AppModuleGenesis)
  - inter-dependent module simulation functionality (AppModuleSimulation)
  - inter-dependent module full functionality (AppModule)

inter-dependent module functionality is module functionality which somehow
depends on other modules, typically through the module keeper.  Many of the
module keepers are dependent on each other, thus in order to access the full
set of module functionality we need to define all the keepers/params-store/keys
etc. This full set of advanced functionality is defined by the AppModule interface.

Independent module functions are separated to allow for the construction of the
basic application structures required early on in the application definition
and used to enable the definition of full module functionality later in the
process. This separation is necessary, however we still want to allow for a
high level pattern for modules to follow - for instance, such that we don't
have to manually register all of the codecs for all the modules. This basic
procedure as well as other basic patterns are handled through the use of
BasicManager.

Lastly the interface for genesis functionality (AppModuleGenesis)

has been
separated out from full module functionality (AppModule)

so that modules which
are only used for genesis can take advantage of the Module patterns without
needlessly defining many placeholder functions
*/
package module

import (
    
	"encoding/json"
    "fmt"
    "sort"
    "cosmossdk.io/core/appmodule"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "golang.org/x/exp/maps"
    "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"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
type AppModuleBasic interface {
    HasName
	RegisterLegacyAminoCodec(*codec.LegacyAmino)

RegisterInterfaces(codectypes.InterfaceRegistry)

	// client functionality
	RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)

GetTxCmd() *cobra.Command
	GetQueryCmd() *cobra.Command
}

// HasName allows the module to provide its own name for legacy purposes.
// Newer apps should specify the name for their modules using a map
// using NewManagerFromMap.
type HasName interface {
    Name()

string
}

// HasGenesisBasics is the legacy interface for stateless genesis methods.
type HasGenesisBasics interface {
    DefaultGenesis(codec.JSONCodec)

json.RawMessage
	ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)

error
}

// BasicManager is a collection of AppModuleBasic
type BasicManager map[string]AppModuleBasic

// NewBasicManager creates a new BasicManager object
func NewBasicManager(modules ...AppModuleBasic)

BasicManager {
    moduleMap := make(map[string]AppModuleBasic)
    for _, module := range modules {
    moduleMap[module.Name()] = module
}

return moduleMap
}

// RegisterLegacyAminoCodec registers all module codecs
func (bm BasicManager)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    for _, b := range bm {
    b.RegisterLegacyAminoCodec(cdc)
}
}

// RegisterInterfaces registers all module interface types
func (bm BasicManager)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    for _, m := range bm {
    m.RegisterInterfaces(registry)
}
}

// DefaultGenesis provides default genesis information for all modules
func (bm BasicManager)

DefaultGenesis(cdc codec.JSONCodec)

map[string]json.RawMessage {
    genesis := make(map[string]json.RawMessage)
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    genesis[b.Name()] = mod.DefaultGenesis(cdc)
}
	
}

return genesis
}

// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager)

ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)

error {
    for _, b := range bm {
    if mod, ok := b.(HasGenesisBasics); ok {
    if err := mod.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
    return err
}
	
}
	
}

return nil
}

// RegisterGRPCGatewayRoutes registers all module rest routes
func (bm BasicManager)

RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
    for _, b := range bm {
    b.RegisterGRPCGatewayRoutes(clientCtx, rtr)
}
}

// AddTxCommands adds all tx commands to the rootTxCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddTxCommands(rootTxCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetTxCmd(); cmd != nil {
    rootTxCmd.AddCommand(cmd)
}
	
}
}

// AddQueryCommands adds all query commands to the rootQueryCmd.
//
// TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager)

AddQueryCommands(rootQueryCmd *cobra.Command) {
    for _, b := range bm {
    if cmd := b.GetQueryCmd(); cmd != nil {
    rootQueryCmd.AddCommand(cmd)
}
	
}
}

// AppModuleGenesis is the standard form for an application module genesis functions
type AppModuleGenesis interface {
    AppModuleBasic
	HasGenesis
}

// HasGenesis is the extension interface for stateful genesis methods.
type HasGenesis interface {
    HasGenesisBasics
	InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
	ExportGenesis(sdk.Context, codec.JSONCodec)

json.RawMessage
}

// AppModule is the form for an application module. Most of
// its functionality has been moved to extension interfaces.
type AppModule interface {
    AppModuleBasic
}

// HasInvariants is the interface for registering invariants.
type HasInvariants interface {
	// RegisterInvariants registers module invariants.
	RegisterInvariants(sdk.InvariantRegistry)
}

// HasServices is the interface for modules to register services.
type HasServices interface {
	// RegisterServices allows a module to register services.
	RegisterServices(Configurator)
}

// HasConsensusVersion is the interface for declaring a module consensus version.
type HasConsensusVersion interface {
	// ConsensusVersion is a sequence number for state-breaking change of the
	// module. It should be incremented on each consensus-breaking change
	// introduced by the module. To avoid wrong/empty versions, the initial version
	// should be set to 1.
	ConsensusVersion()

uint64
}

// BeginBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock.
type BeginBlockAppModule interface {
    AppModule
	BeginBlock(sdk.Context, abci.RequestBeginBlock)
}

// EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock.
type EndBlockAppModule interface {
    AppModule
	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}

// GenesisOnlyAppModule is an AppModule that only has import/export functionality
type GenesisOnlyAppModule struct {
    AppModuleGenesis
}

// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
func NewGenesisOnlyAppModule(amg AppModuleGenesis)

GenesisOnlyAppModule {
    return GenesisOnlyAppModule{
    AppModuleGenesis: amg,
}
}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (GenesisOnlyAppModule)

IsOnePerModuleType() {
}

// IsAppModule implements the appmodule.AppModule interface.
func (GenesisOnlyAppModule)

IsAppModule() {
}

// RegisterInvariants is a placeholder function register no invariants
func (GenesisOnlyAppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

// QuerierRoute returns an empty module querier route
func (GenesisOnlyAppModule)

QuerierRoute()

string {
    return ""
}

// RegisterServices registers all services.
func (gam GenesisOnlyAppModule)

RegisterServices(Configurator) {
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (gam GenesisOnlyAppModule)

ConsensusVersion()

uint64 {
    return 1
}

// BeginBlock returns an empty module begin-block
func (gam GenesisOnlyAppModule)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
}

// EndBlock returns an empty module end-block
func (GenesisOnlyAppModule)

EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
    return []abci.ValidatorUpdate{
}
}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
    Modules            map[string]interface{
} // interface{
}

is used now to support the legacy AppModule as well as new core appmodule.AppModule.
	OrderInitGenesis   []string
	OrderExportGenesis []string
	OrderBeginBlockers []string
	OrderEndBlockers   []string
	OrderMigrations    []string
}

// NewManager creates a new Manager object.
func NewManager(modules ...AppModule) *Manager {
    moduleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(modules))
    for _, module := range modules {
    moduleMap[module.Name()] = module
		modulesStr = append(modulesStr, module.Name())
}

return &Manager{
    Modules:            moduleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
    simpleModuleMap := make(map[string]interface{
})
    modulesStr := make([]string, 0, len(simpleModuleMap))
    for name, module := range moduleMap {
    simpleModuleMap[name] = module
		modulesStr = append(modulesStr, name)
}

return &Manager{
    Modules:            simpleModuleMap,
    OrderInitGenesis:   modulesStr,
    OrderExportGenesis: modulesStr,
    OrderBeginBlockers: modulesStr,
    OrderEndBlockers:   modulesStr,
}
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager)

SetOrderInitGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)

m.OrderInitGenesis = moduleNames
}

// SetOrderExportGenesis sets the order of export genesis calls
func (m *Manager)

SetOrderExportGenesis(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderExportGenesis", moduleNames)

m.OrderExportGenesis = moduleNames
}

// SetOrderBeginBlockers sets the order of set begin-blocker calls
func (m *Manager)

SetOrderBeginBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderBeginBlockers", moduleNames)

m.OrderBeginBlockers = moduleNames
}

// SetOrderEndBlockers sets the order of set end-blocker calls
func (m *Manager)

SetOrderEndBlockers(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames)

m.OrderEndBlockers = moduleNames
}

// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager)

SetOrderMigrations(moduleNames ...string) {
    m.assertNoForgottenModules("SetOrderMigrations", moduleNames)

m.OrderMigrations = moduleNames
}

// RegisterInvariants registers all module invariants
func (m *Manager)

RegisterInvariants(ir sdk.InvariantRegistry) {
    for _, module := range m.Modules {
    if module, ok := module.(HasInvariants); ok {
    module.RegisterInvariants(ir)
}
	
}
}

// RegisterServices registers all module services
func (m *Manager)

RegisterServices(cfg Configurator) {
    for _, module := range m.Modules {
    if module, ok := module.(HasServices); ok {
    module.RegisterServices(cfg)
}
	
}
}

// InitGenesis performs init genesis functionality for modules. Exactly one
// module must return a non-empty validator set update to correctly initialize
// the chain.
func (m *Manager)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)

abci.ResponseInitChain {
    var validatorUpdates []abci.ValidatorUpdate
	ctx.Logger().Info("initializing blockchain state from genesis.json")
    for _, moduleName := range m.OrderInitGenesis {
    if genesisData[moduleName] == nil {
    continue
}
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    ctx.Logger().Debug("running initialization for module", "module", moduleName)
    moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])

			// use these validator updates if provided, the module manager assumes
			// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator InitGenesis updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}
	
}

	// a chain must initialize with a non-empty validator set
    if len(validatorUpdates) == 0 {
    panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction))
}

return abci.ResponseInitChain{
    Validators: validatorUpdates,
}
}

// ExportGenesis performs export genesis functionality for modules
func (m *Manager)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

map[string]json.RawMessage {
    return m.ExportGenesisForModules(ctx, cdc, []string{
})
}

// ExportGenesisForModules performs export genesis functionality for modules
func (m *Manager)

ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)

map[string]json.RawMessage {
    if len(modulesToExport) == 0 {
    modulesToExport = m.OrderExportGenesis
}

	// verify modules exists in app, so that we don't panic in the middle of an export
    if err := m.checkModulesExists(modulesToExport); err != nil {
    panic(err)
}
    channels := make(map[string]chan json.RawMessage)
    for _, moduleName := range modulesToExport {
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    channels[moduleName] = make(chan json.RawMessage)

go func(module HasGenesis, ch chan json.RawMessage) {
    ctx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // avoid race conditions
				ch <- module.ExportGenesis(ctx, cdc)
}(module, channels[moduleName])
}
	
}
    genesisData := make(map[string]json.RawMessage)
    for moduleName := range channels {
    genesisData[moduleName] = <-channels[moduleName]
}

return genesisData
}

// checkModulesExists verifies that all modules in the list exist in the app
func (m *Manager)

checkModulesExists(moduleName []string)

error {
    for _, name := range moduleName {
    if _, ok := m.Modules[name]; !ok {
    return fmt.Errorf("module %s does not exist", name)
}
	
}

return nil
}

// assertNoForgottenModules checks that we didn't forget any modules in the
// SetOrder* functions.
func (m *Manager)

assertNoForgottenModules(setOrderFnName string, moduleNames []string) {
    ms := make(map[string]bool)
    for _, m := range moduleNames {
    ms[m] = true
}

var missing []string
    for m := range m.Modules {
    if !ms[m] {
    missing = append(missing, m)
}
	
}
    if len(missing) != 0 {
    sort.Strings(missing)

panic(fmt.Sprintf(
			"%s: all modules must be defined when setting %s, missing: %v", setOrderFnName, setOrderFnName, missing))
}
}

// MigrationHandler is the migration function that each module registers.
type MigrationHandler func(sdk.Context)

error

// VersionMap is a map of moduleName -> version
type VersionMap map[string]uint64

// RunMigrations performs in-place store migrations for all modules. This
// function MUST be called insde an x/upgrade UpgradeHandler.
//
// Recall that in an upgrade handler, the `fromVM` VersionMap is retrieved from
// x/upgrade's store, and the function needs to return the target VersionMap
// that will in turn be persisted to the x/upgrade's store. In general,
// returning RunMigrations should be enough:
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Internally, RunMigrations will perform the following steps:
// - create an `updatedVM` VersionMap of module with their latest ConsensusVersion
// - make a diff of `fromVM` and `udpatedVM`, and for each module:
//   - if the module's `fromVM` version is less than its `updatedVM` version,
//     then run in-place store migrations for that module between those versions.
//   - if the module does not exist in the `fromVM` (which means that it's a new module,
//     because it was not in the previous x/upgrade's store), then run
//     `InitGenesis` on that module.
//
// - return the `updatedVM` to be persisted in the x/upgrade's store.
//
// Migrations are run in an order defined by `Manager.OrderMigrations` or (if not set)

defined by
// `DefaultMigrationsOrder` function.
//
// As an app developer, if you wish to skip running InitGenesis for your new
// module "foo", you need to manually pass a `fromVM` argument to this function
// foo's module version set to its latest ConsensusVersion. That way, the diff
// between the function's `fromVM` and `udpatedVM` will be empty, hence not
// running anything for foo.
//
// Example:
//
//	cfg := module.NewConfigurator(...)
//	app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
//	    // Assume "foo" is a new module.
//	    // `fromVM` is fetched from existing x/upgrade store. Since foo didn't exist
//	    // before this upgrade, `v, exists := fromVM["foo"]; exists == false`, and RunMigration will by default
//	    // run InitGenesis on foo.
//	    // To skip running foo's InitGenesis, you need set `fromVM`'s foo to its latest
//	    // consensus version:
//	    fromVM["foo"] = foo.AppModule{
}.ConsensusVersion()
//
//	    return app.mm.RunMigrations(ctx, cfg, fromVM)
//
})
//
// Please also refer to docs/core/upgrade.md for more information.
func (m Manager)

RunMigrations(ctx sdk.Context, cfg Configurator, fromVM VersionMap) (VersionMap, error) {
    c, ok := cfg.(configurator)
    if !ok {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", configurator{
}, cfg)
}
    modules := m.OrderMigrations
    if modules == nil {
    modules = DefaultMigrationsOrder(m.ModuleNames())
}
    updatedVM := VersionMap{
}
    for _, moduleName := range modules {
    module := m.Modules[moduleName]
		fromVersion, exists := fromVM[moduleName]
    toVersion := uint64(0)
    if module, ok := module.(HasConsensusVersion); ok {
    toVersion = module.ConsensusVersion()
}

		// We run migration if the module is specified in `fromVM`.
		// Otherwise we run InitGenesis.
		//
		// The module won't exist in the fromVM in two cases:
		// 1. A new module is added. In this case we run InitGenesis with an
		// empty genesis state.
		// 2. An existing chain is upgrading from version < 0.43 to v0.43+ for the first time.
		// In this case, all modules have yet to be added to x/upgrade's VersionMap store.
    if exists {
    err := c.runModuleMigrations(ctx, moduleName, fromVersion, toVersion)
    if err != nil {
    return nil, err
}
	
}

else {
    ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
    if module, ok := m.Modules[moduleName].(HasGenesis); ok {
    moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
				// The module manager assumes only one module will update the
				// validator set, and it can't be a new module.
    if len(moduleValUpdates) > 0 {
    return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
}
	
}
	
}

updatedVM[moduleName] = toVersion
}

return updatedVM, nil
}

// BeginBlock performs begin block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    for _, moduleName := range m.OrderBeginBlockers {
    module, ok := m.Modules[moduleName].(BeginBlockAppModule)
    if ok {
    module.BeginBlock(ctx, req)
}
	
}

return abci.ResponseBeginBlock{
    Events: ctx.EventManager().ABCIEvents(),
}
}

// EndBlock performs end block functionality for all modules. It creates a
// child context with an event manager to aggregate events emitted from all
// modules.
func (m *Manager)

EndBlock(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    ctx = ctx.WithEventManager(sdk.NewEventManager())
    validatorUpdates := []abci.ValidatorUpdate{
}
    for _, moduleName := range m.OrderEndBlockers {
    module, ok := m.Modules[moduleName].(EndBlockAppModule)
    if !ok {
    continue
}
    moduleValUpdates := module.EndBlock(ctx, req)

		// use these validator updates if provided, the module manager assumes
		// only one module will update the validator set
    if len(moduleValUpdates) > 0 {
    if len(validatorUpdates) > 0 {
    panic("validator EndBlock updates already set by a previous module")
}

validatorUpdates = moduleValUpdates
}
	
}

return abci.ResponseEndBlock{
    ValidatorUpdates: validatorUpdates,
    Events:           ctx.EventManager().ABCIEvents(),
}
}

// GetVersionMap gets consensus version from all modules
func (m *Manager)

GetVersionMap()

VersionMap {
    vermap := make(VersionMap)
    for name, v := range m.Modules {
    version := uint64(0)
    if v, ok := v.(HasConsensusVersion); ok {
    version = v.ConsensusVersion()
}
    name := name
		vermap[name] = version
}

return vermap
}

// ModuleNames returns list of all module names, without any particular order.
func (m *Manager)

ModuleNames() []string {
    return maps.Keys(m.Modules)
}

// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,
// except x/auth which will run last, see:
// https://github.com/cosmos/cosmos-sdk/issues/10591
func DefaultMigrationsOrder(modules []string) []string {
    const authName = "auth"
    out := make([]string, 0, len(modules))
    hasAuth := false
    for _, m := range modules {
    if m == authName {
    hasAuth = true
}

else {
    out = append(out, m)
}
	
}

sort.Strings(out)
    if hasAuth {
    out = append(out, authName)
}

return out
}
The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods:
  • NewManager(modules ...AppModule): Constructor function. It takes a list of the application’s AppModules and builds a new Manager. It is generally called from the application’s main constructor function.
  • SetOrderInitGenesis(moduleNames ...string): Sets the order in which the InitGenesis function of each module will be called when the application is first started. This function is generally called from the application’s main constructor function. To initialize modules successfully, module dependencies should be considered. For example, the genutil module must occur after staking module so that the pools are properly initialized with tokens from genesis accounts, the genutils module must also occur after auth so that it can access the params from auth, IBC’s capability module should be initialized before all other modules so that it can initialize any capabilities.
  • SetOrderExportGenesis(moduleNames ...string): Sets the order in which the ExportGenesis function of each module will be called in case of an export. This function is generally called from the application’s main constructor function.
  • SetOrderBeginBlockers(moduleNames ...string): Sets the order in which the BeginBlock() function of each module will be called at the beginning of each block. This function is generally called from the application’s main constructor function.
  • SetOrderEndBlockers(moduleNames ...string): Sets the order in which the EndBlock() function of each module will be called at the end of each block. This function is generally called from the application’s main constructor function.
  • SetOrderPrecommiters(moduleNames ...string): Sets the order in which the Precommit() function of each module will be called during commit of each block. This function is generally called from the application’s main constructor function.
  • SetOrderPrepareCheckStaters(moduleNames ...string): Sets the order in which the PrepareCheckState() function of each module will be called during commit of each block. This function is generally called from the application’s main constructor function.
  • SetOrderMigrations(moduleNames ...string): Sets the order of migrations to be run. If not set then migrations will be run with an order defined in DefaultMigrationsOrder.
  • RegisterInvariants(ir sdk.InvariantRegistry): Registers the invariants of module implementing the HasInvariants interface.
  • RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino): Registers legacy Msg and querier routes.
  • RegisterServices(cfg Configurator): Registers the services of modules implementing the HasServices interface.
  • InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage): Calls the InitGenesis function of each module when the application is first started, in the order defined in OrderInitGenesis. Returns an abci.ResponseInitChain to the underlying consensus engine, which can contain validator updates.
  • ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec): Calls the ExportGenesis function of each module, in the order defined in OrderExportGenesis. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
  • ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string): Behaves the same as ExportGenesis, except takes a list of modules to export.
  • BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock): At the beginning of each block, this function is called from BaseApp and, in turn, calls the BeginBlock function of each modules implementing the BeginBlockAppModule interface, in the order defined in OrderBeginBlockers. It creates a child context with an event manager to aggregate events emitted from all modules. The function returns an abci.ResponseBeginBlock which contains the aforementioned events.
  • EndBlock(ctx sdk.Context, req abci.RequestEndBlock): At the end of each block, this function is called from BaseApp and, in turn, calls the EndBlock function of each modules implementing the EndBlockAppModule interface, in the order defined in OrderEndBlockers. It creates a child context with an event manager to aggregate events emitted from all modules. The function returns an abci.ResponseEndBlock which contains the aforementioned events, as well as validator set updates (if any).
  • Precommit(ctx sdk.Context): During Commit, this function is called from BaseApp immediately before the deliverState is written to the underlying rootMultiStore and, in turn calls the Precommit function of each modules implementing the HasPrecommit interface, in the order defined in OrderPrecommiters. It creates a child context where the underlying CacheMultiStore is that of the newly committed block’s deliverState.
  • PrepareCheckState(ctx sdk.Context): During Commit, this function is called from BaseApp immediately after the deliverState is written to the underlying rootMultiStore and, in turn calls the PrepareCheckState function of each module implementing the HasPrepareCheckState interface, in the order defined in OrderPrepareCheckStaters. It creates a child context where the underlying CacheMultiStore is that of the next block’s checkState. Writes to this state will be present in the checkState of the next block, and therefore this method can be used to prepare the checkState for the next block.
Here’s an example of a concrete integration within an simapp:
//go:build app_v1

package simapp

import (
    
	"encoding/json"
    "io"
    "os"
    "path/filepath"

	autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
	reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
    "github.com/spf13/cast"
	abci "github.com/tendermint/tendermint/abci/types"
    "github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"

	simappparams "cosmossdk.io/simapp/params"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/client/flags"
	nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node"
    "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
    "github.com/cosmos/cosmos-sdk/codec"
    "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/runtime"
	runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services"
    "github.com/cosmos/cosmos-sdk/server"
    "github.com/cosmos/cosmos-sdk/server/api"
    "github.com/cosmos/cosmos-sdk/server/config"
	servertypes "github.com/cosmos/cosmos-sdk/server/types"
    "github.com/cosmos/cosmos-sdk/std"
    "github.com/cosmos/cosmos-sdk/store/streaming"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/version"
    "github.com/cosmos/cosmos-sdk/x/auth"
    "github.com/cosmos/cosmos-sdk/x/auth/ante"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
    "github.com/cosmos/cosmos-sdk/x/auth/posthandler"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    "github.com/cosmos/cosmos-sdk/x/auth/vesting"
	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
    "github.com/cosmos/cosmos-sdk/x/authz"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
    "github.com/cosmos/cosmos-sdk/x/bank"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
    "github.com/cosmos/cosmos-sdk/x/capability"
	capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
	consensus "github.com/cosmos/cosmos-sdk/x/consensus"
	consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
	consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
    "github.com/cosmos/cosmos-sdk/x/crisis"
	crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
	distr "github.com/cosmos/cosmos-sdk/x/distribution"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
    "github.com/cosmos/cosmos-sdk/x/evidence"
	evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
    "github.com/cosmos/cosmos-sdk/x/feegrant"
	feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
	feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
    "github.com/cosmos/cosmos-sdk/x/genutil"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    "github.com/cosmos/cosmos-sdk/x/gov"
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
	govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
	govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
    "github.com/cosmos/cosmos-sdk/x/group"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    "github.com/cosmos/cosmos-sdk/x/mint"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
    "github.com/cosmos/cosmos-sdk/x/nft"
	nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
	nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
    "github.com/cosmos/cosmos-sdk/x/params"
	paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
	paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
	paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
    "github.com/cosmos/cosmos-sdk/x/slashing"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
    "github.com/cosmos/cosmos-sdk/x/staking"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    "github.com/cosmos/cosmos-sdk/x/upgrade"
	upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

const appName = "SimApp"

var (
	// DefaultNodeHome default home directories for the application daemon
	DefaultNodeHome string

	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
	// non-dependant module elements, such as codec registration
	// and genesis verification.
	ModuleBasics = module.NewBasicManager(
		auth.AppModuleBasic{
},
		genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
		bank.AppModuleBasic{
},
		capability.AppModuleBasic{
},
		staking.AppModuleBasic{
},
		mint.AppModuleBasic{
},
		distr.AppModuleBasic{
},
		gov.NewAppModuleBasic(
			[]govclient.ProposalHandler{
    paramsclient.ProposalHandler,
				upgradeclient.LegacyProposalHandler,
				upgradeclient.LegacyCancelProposalHandler,
},
		),
		params.AppModuleBasic{
},
		crisis.AppModuleBasic{
},
		slashing.AppModuleBasic{
},
		feegrantmodule.AppModuleBasic{
},
		upgrade.AppModuleBasic{
},
		evidence.AppModuleBasic{
},
		authzmodule.AppModuleBasic{
},
		groupmodule.AppModuleBasic{
},
		vesting.AppModuleBasic{
},
		nftmodule.AppModuleBasic{
},
		consensus.AppModuleBasic{
},
	)

	// module account permissions
	maccPerms = map[string][]string{
    authtypes.FeeCollectorName:     nil,
		distrtypes.ModuleName:          nil,
		minttypes.ModuleName:           {
    authtypes.Minter
},
		stakingtypes.BondedPoolName:    {
    authtypes.Burner, authtypes.Staking
},
		stakingtypes.NotBondedPoolName: {
    authtypes.Burner, authtypes.Staking
},
		govtypes.ModuleName:            {
    authtypes.Burner
},
		nft.ModuleName:                 nil,
}
)

var (
	_ runtime.AppI            = (*SimApp)(nil)
	_ servertypes.Application = (*SimApp)(nil)
)

// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
	*baseapp.BaseApp
	legacyAmino       *codec.LegacyAmino
	appCodec          codec.Codec
	txConfig          client.TxConfig
	interfaceRegistry types.InterfaceRegistry

	// keys to access the substores
	keys    map[string]*storetypes.KVStoreKey
	tkeys   map[string]*storetypes.TransientStoreKey
	memKeys map[string]*storetypes.MemoryStoreKey

	// keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.Keeper
	CapabilityKeeper      *capabilitykeeper.Keeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             govkeeper.Keeper
	CrisisKeeper          *crisiskeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	ParamsKeeper          paramskeeper.Keeper
	AuthzKeeper           authzkeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	FeeGrantKeeper        feegrantkeeper.Keeper
	GroupKeeper           groupkeeper.Keeper
	NFTKeeper             nftkeeper.Keeper
	ConsensusParamsKeeper consensusparamkeeper.Keeper

	// the module manager
	ModuleManager *module.Manager

	// simulation manager
	sm *module.SimulationManager

	// module configurator
	configurator module.Configurator
}

func init() {
    userHomeDir, err := os.UserHomeDir()
    if err != nil {
    panic(err)
}

DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}

// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
    encodingConfig := makeEncodingConfig()
    appCodec := encodingConfig.Codec
    legacyAmino := encodingConfig.Amino
    interfaceRegistry := encodingConfig.InterfaceRegistry
    txConfig := encodingConfig.TxConfig

	// Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
	// handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
	// them.
	//
	// nonceMempool := mempool.NewSenderNonceMempool()
	// mempoolOpt   := baseapp.SetMempool(nonceMempool)
	// prepareOpt   := func(app *baseapp.BaseApp) {
	// 	app.SetPrepareProposal(app.DefaultPrepareProposal())
	//
}
	// processOpt := func(app *baseapp.BaseApp) {
	// 	app.SetProcessProposal(app.DefaultProcessProposal())
	//
}
	//
	// Further down we'd set the options in the AppBuilder like below.
	// baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)
    bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...)

bApp.SetCommitMultiStoreTracer(traceStore)

bApp.SetVersion(version.Version)

bApp.SetInterfaceRegistry(interfaceRegistry)

bApp.SetTxEncoder(txConfig.TxEncoder())
    keys := sdk.NewKVStoreKeys(
		authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey,
		minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
		govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
		evidencetypes.StoreKey, capabilitytypes.StoreKey,
		authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey,
	)
    tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
	// NOTE: The testingkey is just mounted for testing purposes. Actual applications should
	// not include this key.
    memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey")

	// load state streaming if enabled
    if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, logger, keys); err != nil {
    logger.Error("failed to load state streaming", "err", err)

os.Exit(1)
}
    app := &SimApp{
    BaseApp:           bApp,
		legacyAmino:       legacyAmino,
		appCodec:          appCodec,
		txConfig:          txConfig,
		interfaceRegistry: interfaceRegistry,
		keys:              keys,
		tkeys:             tkeys,
		memKeys:           memKeys,
}

app.ParamsKeeper = initParamsKeeper(appCodec, legacyAmino, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])

	// set the BaseApp's parameter store
	app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String())

bApp.SetParamStore(&app.ConsensusParamsKeeper)

app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
	// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
	// their scoped modules in `NewApp` with `ScopeToModule`
	app.CapabilityKeeper.Seal()

	// add keepers
	app.AccountKeeper = authkeeper.NewAccountKeeper(appCodec, keys[authtypes.StoreKey], authtypes.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.BankKeeper = bankkeeper.NewBaseKeeper(
		appCodec,
		keys[banktypes.StoreKey],
		app.AccountKeeper,
		BlockedAddresses(),
		authtypes.NewModuleAddress(govtypes.ModuleName).String(),
	)

app.StakingKeeper = stakingkeeper.NewKeeper(
		appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
	)

app.MintKeeper = mintkeeper.NewKeeper(appCodec, keys[minttypes.StoreKey], app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.DistrKeeper = distrkeeper.NewKeeper(appCodec, keys[distrtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.SlashingKeeper = slashingkeeper.NewKeeper(
		appCodec, legacyAmino, keys[slashingtypes.StoreKey], app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
	)
    invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))

app.CrisisKeeper = crisiskeeper.NewKeeper(appCodec, keys[crisistypes.StoreKey], invCheckPeriod,
		app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)

	// register the staking hooks
	// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
	app.StakingKeeper.SetHooks(
		stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
	)

app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper)
    groupConfig := group.DefaultConfig()
	/*
		Example of setting group params:
		groupConfig.MaxMetadataLen = 1000
	*/
	app.GroupKeeper = groupkeeper.NewKeeper(keys[group.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper, groupConfig)

	// get skipUpgradeHeights from the app options
    skipUpgradeHeights := map[int64]bool{
}
    for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
    skipUpgradeHeights[int64(h)] = true
}
    homePath := cast.ToString(appOpts.Get(flags.FlagHome))
	// set the governance module account as the authority for conducting upgrades
	app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())

	// Register the proposal types
	// Deprecated: Avoid adding new handlers, instead use the new proposal flow
	// by granting the governance module the right to execute the message.
	// See: https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/gov/spec/01_concepts.md#proposal-messages
    govRouter := govv1beta1.NewRouter()

govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
		AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
		AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
    govConfig := govtypes.DefaultConfig()
	/*
		Example of setting gov params:
		govConfig.MaxMetadataLen = 10000
	*/
    govKeeper := govkeeper.NewKeeper(
		appCodec, keys[govtypes.StoreKey], app.AccountKeeper, app.BankKeeper,
		app.StakingKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
	)

	// Set legacy router for backwards compatibility with gov v1beta1
	govKeeper.SetLegacyRouter(govRouter)

app.GovKeeper = *govKeeper.SetHooks(
		govtypes.NewMultiGovHooks(
		// register the governance hooks
		),
	)

app.NFTKeeper = nftkeeper.NewKeeper(keys[nftkeeper.StoreKey], appCodec, app.AccountKeeper, app.BankKeeper)

	// create evidence keeper with router
    evidenceKeeper := evidencekeeper.NewKeeper(
		appCodec, keys[evidencetypes.StoreKey], app.StakingKeeper, app.SlashingKeeper,
	)
	// If evidence needs to be handled for the app, set routes in router here and seal
	app.EvidenceKeeper = *evidenceKeeper

	/****  Module Options ****/

	// NOTE: we may consider parsing `appOpts` inside module constructors. For the moment
	// we prefer to be more strict in what arguments the modules expect.
    skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))

	// NOTE: Any module instantiated in the module manager that is later modified
	// must be passed by reference here.
	app.ModuleManager = module.NewManager(
		genutil.NewAppModule(
			app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
			encodingConfig.TxConfig,
		),
		auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
		vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
		bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
		capability.NewAppModule(appCodec, *app.CapabilityKeeper, false),
		crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)),
		feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
		gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)),
		mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)),
		slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)),
		distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)),
		staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)),
		upgrade.NewAppModule(app.UpgradeKeeper),
		evidence.NewAppModule(app.EvidenceKeeper),
		params.NewAppModule(app.ParamsKeeper),
		authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
		groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
		nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
		consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
	)

	// During begin block slashing happens after distr.BeginBlocker so that
	// there is nothing left over in the validator fee pool, so as to keep the
	// CanWithdrawInvariant invariant.
	// NOTE: staking module is required if HistoricalEntries param > 0
	// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

app.ModuleManager.SetOrderBeginBlockers(
		upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName,
		evidencetypes.ModuleName, stakingtypes.ModuleName,
		authtypes.ModuleName, banktypes.ModuleName, govtypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName,
		authz.ModuleName, feegrant.ModuleName, nft.ModuleName, group.ModuleName,
		paramstypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName,
	)

app.ModuleManager.SetOrderEndBlockers(
		crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName,
		capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName,
		slashingtypes.ModuleName, minttypes.ModuleName,
		genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
		feegrant.ModuleName, nft.ModuleName, group.ModuleName,
		paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName,
	)

	// NOTE: The genutils module must occur after staking so that pools are
	// properly initialized with tokens from genesis accounts.
	// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
	// NOTE: Capability module must occur first so that it can initialize any capabilities
	// so that other modules that want to create or claim capabilities afterwards in InitChain
	// can do so safely.
    genesisModuleOrder := []string{
    capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
		vestingtypes.ModuleName, consensusparamtypes.ModuleName,
}

app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)

app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)

	// Uncomment if you want to set a custom migration order here.
	// app.ModuleManager.SetOrderMigrations(custom order)

app.ModuleManager.RegisterInvariants(app.CrisisKeeper)

app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())

app.ModuleManager.RegisterServices(app.configurator)

	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
	// Make sure it's called after `app.ModuleManager` and `app.configurator` are set.
	app.RegisterUpgradeHandlers()

autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules))

reflectionSvc, err := runtimeservices.NewReflectionService()
    if err != nil {
    panic(err)
}

reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc)

	// add test gRPC service for testing gRPC queries in isolation
	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
})

	// create the simulation manager and define the order of the modules for deterministic simulations
	//
	// NOTE: this is not required apps that don't use the simulator for fuzz testing
	// transactions
    overrideModules := map[string]module.AppModuleSimulation{
    authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
}

app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

app.sm.RegisterStoreDecoders()

	// initialize stores
	app.MountKVStores(keys)

app.MountTransientStores(tkeys)

app.MountMemoryStores(memKeys)

	// initialize BaseApp
	app.SetInitChainer(app.InitChainer)

app.SetBeginBlocker(app.BeginBlocker)

app.SetEndBlocker(app.EndBlocker)

app.setAnteHandler(encodingConfig.TxConfig)

	// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
	// antehandlers, but are run _after_ the `runMsgs` execution. They are also
	// defined as a chain, and have the same signature as antehandlers.
	//
	// In baseapp, postHandlers are run in the same store branch as `runMsgs`,
	// meaning that both `runMsgs` and `postHandler` state will be committed if
	// both are successful, and both will be reverted if any of the two fails.
	//
	// The SDK exposes a default postHandlers chain, which comprises of only
	// one decorator: the Transaction Tips decorator. However, some chains do
	// not need it by default, so feel free to comment the next line if you do
	// not need tips.
	// To read more about tips:
	// https://docs.cosmos.network/main/core/tips.html
	//
	// Please note that changing any of the anteHandler or postHandler chain is
	// likely to be a state-machine breaking change, which needs a coordinated
	// upgrade.
	app.setPostHandler()
    if loadLatest {
    if err := app.LoadLatestVersion(); err != nil {
    logger.Error("error on loading last version", "err", err)

os.Exit(1)
}
	
}

return app
}

func (app *SimApp)

setAnteHandler(txConfig client.TxConfig) {
    anteHandler, err := ante.NewAnteHandler(
		ante.HandlerOptions{
    AccountKeeper:   app.AccountKeeper,
    BankKeeper:      app.BankKeeper,
    SignModeHandler: txConfig.SignModeHandler(),
    FeegrantKeeper:  app.FeeGrantKeeper,
    SigGasConsumer:  ante.DefaultSigVerificationGasConsumer,
},
	)
    if err != nil {
    panic(err)
}

app.SetAnteHandler(anteHandler)
}

func (app *SimApp)

setPostHandler() {
    postHandler, err := posthandler.NewPostHandler(
		posthandler.HandlerOptions{
},
	)
    if err != nil {
    panic(err)
}

app.SetPostHandler(postHandler)
}

// Name returns the name of the App
func (app *SimApp)

Name()

string {
    return app.BaseApp.Name()
}

// BeginBlocker application updates every begin block
func (app *SimApp)

BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock)

abci.ResponseBeginBlock {
    return app.ModuleManager.BeginBlock(ctx, req)
}

// EndBlocker application updates every end block
func (app *SimApp)

EndBlocker(ctx sdk.Context, req abci.RequestEndBlock)

abci.ResponseEndBlock {
    return app.ModuleManager.EndBlock(ctx, req)
}

func (a *SimApp)

Configurator()

module.Configurator {
    return a.configurator
}

// InitChainer application update at chain initialization
func (app *SimApp)

InitChainer(ctx sdk.Context, req abci.RequestInitChain)

abci.ResponseInitChain {
    var genesisState GenesisState
    if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
    panic(err)
}

app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())

return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
}

// LoadHeight loads a particular height
func (app *SimApp)

LoadHeight(height int64)

error {
    return app.LoadVersion(height)
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

LegacyAmino() *codec.LegacyAmino {
    return app.legacyAmino
}

// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

AppCodec()

codec.Codec {
    return app.appCodec
}

// InterfaceRegistry returns SimApp's InterfaceRegistry
func (app *SimApp)

InterfaceRegistry()

types.InterfaceRegistry {
    return app.interfaceRegistry
}

// TxConfig returns SimApp's TxConfig
func (app *SimApp)

TxConfig()

client.TxConfig {
    return app.txConfig
}

// DefaultGenesis returns a default genesis from the registered AppModuleBasic's.
func (a *SimApp)

DefaultGenesis()

map[string]json.RawMessage {
    return ModuleBasics.DefaultGenesis(a.appCodec)
}

// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetKey(storeKey string) *storetypes.KVStoreKey {
    return app.keys[storeKey]
}

// GetTKey returns the TransientStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetTKey(storeKey string) *storetypes.TransientStoreKey {
    return app.tkeys[storeKey]
}

// GetMemKey returns the MemStoreKey for the provided mem key.
//
// NOTE: This is solely used for testing purposes.
func (app *SimApp)

GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
    return app.memKeys[storeKey]
}

// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetSubspace(moduleName string)

paramstypes.Subspace {
    subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)

return subspace
}

// SimulationManager implements the SimulationApp interface
func (app *SimApp)

SimulationManager() *module.SimulationManager {
    return app.sm
}

// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp)

RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
    clientCtx := apiSvr.ClientCtx
	// Register new tx routes from grpc-gateway.
	authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)

	// Register new tendermint queries routes from grpc-gateway.
	tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)

	// Register node gRPC service for grpc-gateway.
	nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)

	// Register grpc-gateway routes for all modules.
	ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)

	// register swagger API from root so that other applications can override easily
    if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
    panic(err)
}
}

// RegisterTxService implements the Application.RegisterTxService method.
func (app *SimApp)

RegisterTxService(clientCtx client.Context) {
    authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}

// RegisterTendermintService implements the Application.RegisterTendermintService method.
func (app *SimApp)

RegisterTendermintService(clientCtx client.Context) {
    tmservice.RegisterTendermintService(
		clientCtx,
		app.BaseApp.GRPCQueryRouter(),
		app.interfaceRegistry,
		app.Query,
	)
}

func (app *SimApp)

RegisterNodeService(clientCtx client.Context) {
    nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter())
}

// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()

map[string][]string {
    dupMaccPerms := make(map[string][]string)
    for k, v := range maccPerms {
    dupMaccPerms[k] = v
}

return dupMaccPerms
}

// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()

map[string]bool {
    modAccAddrs := make(map[string]bool)
    for acc := range GetMaccPerms() {
    modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
}

	// allow the following addresses to receive funds
	delete(modAccAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String())

return modAccAddrs
}

// initParamsKeeper init params keeper and its subspaces
func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey)

paramskeeper.Keeper {
    paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)

paramsKeeper.Subspace(authtypes.ModuleName)

paramsKeeper.Subspace(banktypes.ModuleName)

paramsKeeper.Subspace(stakingtypes.ModuleName)

paramsKeeper.Subspace(minttypes.ModuleName)

paramsKeeper.Subspace(distrtypes.ModuleName)

paramsKeeper.Subspace(slashingtypes.ModuleName)

paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable())

paramsKeeper.Subspace(crisistypes.ModuleName)

return paramsKeeper
}

func makeEncodingConfig()

simappparams.EncodingConfig {
    encodingConfig := simappparams.MakeTestEncodingConfig()

std.RegisterLegacyAminoCodec(encodingConfig.Amino)

std.RegisterInterfaces(encodingConfig.InterfaceRegistry)

ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino)

ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry)

return encodingConfig
}
This is the same example from runtime (the package that powers app v2):
package runtime

import (
    
	"fmt"

	abci "github.com/tendermint/tendermint/abci/types"

	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
    "cosmossdk.io/core/appmodule"
    "cosmossdk.io/depinject"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/std"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/types/module"
)

// BaseAppOption is a depinject.AutoGroupType which can be used to pass
// BaseApp options into the depinject. It should be used carefully.
type BaseAppOption func(*baseapp.BaseApp)

// IsManyPerContainerType indicates that this is a depinject.ManyPerContainerType.
func (b BaseAppOption)

IsManyPerContainerType() {
}

func init() {
    appmodule.Register(&runtimev1alpha1.Module{
},
		appmodule.Provide(
			ProvideApp,
			ProvideKVStoreKey,
			ProvideTransientStoreKey,
			ProvideMemoryStoreKey,
			ProvideDeliverTx,
		),
		appmodule.Invoke(SetupAppBuilder),
	)
}

func ProvideApp() (
	codectypes.InterfaceRegistry,
	codec.Codec,
	*codec.LegacyAmino,
	*AppBuilder,
	codec.ProtoCodecMarshaler,
	*baseapp.MsgServiceRouter,
) {
    interfaceRegistry := codectypes.NewInterfaceRegistry()
    amino := codec.NewLegacyAmino()

std.RegisterInterfaces(interfaceRegistry)

std.RegisterLegacyAminoCodec(amino)
    cdc := codec.NewProtoCodec(interfaceRegistry)
    msgServiceRouter := baseapp.NewMsgServiceRouter()
    app := &AppBuilder{
		&App{
    storeKeys:         nil,
			interfaceRegistry: interfaceRegistry,
			cdc:               cdc,
			amino:             amino,
			basicManager:      module.BasicManager{
},
			msgServiceRouter:  msgServiceRouter,
},
}

return interfaceRegistry, cdc, amino, app, cdc, msgServiceRouter
}

type AppInputs struct {
    depinject.In

	AppConfig         *appv1alpha1.Config
	Config            *runtimev1alpha1.Module
	AppBuilder        *AppBuilder
	Modules           map[string]appmodule.AppModule
	BaseAppOptions    []BaseAppOption
	InterfaceRegistry codectypes.InterfaceRegistry
	LegacyAmino       *codec.LegacyAmino
}

func SetupAppBuilder(inputs AppInputs) {
    app := inputs.AppBuilder.app
	app.baseAppOptions = inputs.BaseAppOptions
	app.config = inputs.Config
	app.ModuleManager = module.NewManagerFromMap(inputs.Modules)

app.appConfig = inputs.AppConfig
    for name, mod := range inputs.Modules {
    if basicMod, ok := mod.(module.AppModuleBasic); ok {
    app.basicManager[name] = basicMod
			basicMod.RegisterInterfaces(inputs.InterfaceRegistry)

basicMod.RegisterLegacyAminoCodec(inputs.LegacyAmino)
}
	
}
}

func registerStoreKey(wrapper *AppBuilder, key storetypes.StoreKey) {
    wrapper.app.storeKeys = append(wrapper.app.storeKeys, key)
}

func storeKeyOverride(config *runtimev1alpha1.Module, moduleName string) *runtimev1alpha1.StoreKeyConfig {
    for _, cfg := range config.OverrideStoreKeys {
    if cfg.ModuleName == moduleName {
    return cfg
}
	
}

return nil
}

func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.KVStoreKey {
    override := storeKeyOverride(config, key.Name())

var storeKeyName string
    if override != nil {
    storeKeyName = override.KvStoreKey
}

else {
    storeKeyName = key.Name()
}
    storeKey := storetypes.NewKVStoreKey(storeKeyName)

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
    storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
    storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideDeliverTx(appBuilder *AppBuilder)

func(abci.RequestDeliverTx)

abci.ResponseDeliverTx {
    return func(tx abci.RequestDeliverTx)

abci.ResponseDeliverTx {
    return appBuilder.app.BaseApp.DeliverTx(tx)
}
}
package runtime

import (
    
	"fmt"

	abci "github.com/tendermint/tendermint/abci/types"

	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
    "cosmossdk.io/core/appmodule"
    "cosmossdk.io/depinject"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/std"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/types/module"
)

// BaseAppOption is a depinject.AutoGroupType which can be used to pass
// BaseApp options into the depinject. It should be used carefully.
type BaseAppOption func(*baseapp.BaseApp)

// IsManyPerContainerType indicates that this is a depinject.ManyPerContainerType.
func (b BaseAppOption)

IsManyPerContainerType() {
}

func init() {
    appmodule.Register(&runtimev1alpha1.Module{
},
		appmodule.Provide(
			ProvideApp,
			ProvideKVStoreKey,
			ProvideTransientStoreKey,
			ProvideMemoryStoreKey,
			ProvideDeliverTx,
		),
		appmodule.Invoke(SetupAppBuilder),
	)
}

func ProvideApp() (
	codectypes.InterfaceRegistry,
	codec.Codec,
	*codec.LegacyAmino,
	*AppBuilder,
	codec.ProtoCodecMarshaler,
	*baseapp.MsgServiceRouter,
) {
    interfaceRegistry := codectypes.NewInterfaceRegistry()
    amino := codec.NewLegacyAmino()

std.RegisterInterfaces(interfaceRegistry)

std.RegisterLegacyAminoCodec(amino)
    cdc := codec.NewProtoCodec(interfaceRegistry)
    msgServiceRouter := baseapp.NewMsgServiceRouter()
    app := &AppBuilder{
		&App{
    storeKeys:         nil,
			interfaceRegistry: interfaceRegistry,
			cdc:               cdc,
			amino:             amino,
			basicManager:      module.BasicManager{
},
			msgServiceRouter:  msgServiceRouter,
},
}

return interfaceRegistry, cdc, amino, app, cdc, msgServiceRouter
}

type AppInputs struct {
    depinject.In

	AppConfig         *appv1alpha1.Config
	Config            *runtimev1alpha1.Module
	AppBuilder        *AppBuilder
	Modules           map[string]appmodule.AppModule
	BaseAppOptions    []BaseAppOption
	InterfaceRegistry codectypes.InterfaceRegistry
	LegacyAmino       *codec.LegacyAmino
}

func SetupAppBuilder(inputs AppInputs) {
    app := inputs.AppBuilder.app
	app.baseAppOptions = inputs.BaseAppOptions
	app.config = inputs.Config
	app.ModuleManager = module.NewManagerFromMap(inputs.Modules)

app.appConfig = inputs.AppConfig
    for name, mod := range inputs.Modules {
    if basicMod, ok := mod.(module.AppModuleBasic); ok {
    app.basicManager[name] = basicMod
			basicMod.RegisterInterfaces(inputs.InterfaceRegistry)

basicMod.RegisterLegacyAminoCodec(inputs.LegacyAmino)
}
	
}
}

func registerStoreKey(wrapper *AppBuilder, key storetypes.StoreKey) {
    wrapper.app.storeKeys = append(wrapper.app.storeKeys, key)
}

func storeKeyOverride(config *runtimev1alpha1.Module, moduleName string) *runtimev1alpha1.StoreKeyConfig {
    for _, cfg := range config.OverrideStoreKeys {
    if cfg.ModuleName == moduleName {
    return cfg
}
	
}

return nil
}

func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.KVStoreKey {
    override := storeKeyOverride(config, key.Name())

var storeKeyName string
    if override != nil {
    storeKeyName = override.KvStoreKey
}

else {
    storeKeyName = key.Name()
}
    storeKey := storetypes.NewKVStoreKey(storeKeyName)

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
    storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
    storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))

registerStoreKey(app, storeKey)

return storeKey
}

func ProvideDeliverTx(appBuilder *AppBuilder)

func(abci.RequestDeliverTx)

abci.ResponseDeliverTx {
    return func(tx abci.RequestDeliverTx)

abci.ResponseDeliverTx {
    return appBuilder.app.BaseApp.DeliverTx(tx)
}
}