github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/module/module.go (about)

     1  /*
     2  Package module contains application module patterns and associated "manager" functionality.
     3  The module pattern has been broken down by:
     4    - independent module functionality (AppModuleBasic)
     5    - inter-dependent module genesis functionality (AppModuleGenesis)
     6    - inter-dependent module simulation functionality (AppModuleSimulation)
     7    - inter-dependent module full functionality (AppModule)
     8  
     9  inter-dependent module functionality is module functionality which somehow
    10  depends on other modules, typically through the module keeper.  Many of the
    11  module keepers are dependent on each other, thus in order to access the full
    12  set of module functionality we need to define all the keepers/params-store/keys
    13  etc. This full set of advanced functionality is defined by the AppModule interface.
    14  
    15  Independent module functions are separated to allow for the construction of the
    16  basic application structures required early on in the application definition
    17  and used to enable the definition of full module functionality later in the
    18  process. This separation is necessary, however we still want to allow for a
    19  high level pattern for modules to follow - for instance, such that we don't
    20  have to manually register all of the codecs for all the modules. This basic
    21  procedure as well as other basic patterns are handled through the use of
    22  BasicManager.
    23  
    24  Lastly the interface for genesis functionality (AppModuleGenesis) has been
    25  separated out from full module functionality (AppModule) so that modules which
    26  are only used for genesis can take advantage of the Module patterns without
    27  needlessly defining many placeholder functions
    28  */
    29  package module
    30  
    31  import (
    32  	"encoding/json"
    33  
    34  	interfacetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
    35  
    36  	"github.com/gorilla/mux"
    37  	"github.com/spf13/cobra"
    38  
    39  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    40  
    41  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    42  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    43  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    44  )
    45  
    46  //__________________________________________________________________________________________
    47  
    48  // AppModuleBasic is the standard form for basic non-dependant elements of an application module.
    49  type AppModuleBasic interface {
    50  	Name() string
    51  	RegisterCodec(*codec.Codec)
    52  
    53  	// genesis
    54  	DefaultGenesis() json.RawMessage
    55  	ValidateGenesis(json.RawMessage) error
    56  
    57  	// client functionality
    58  	RegisterRESTRoutes(context.CLIContext, *mux.Router)
    59  	GetTxCmd(*codec.Codec) *cobra.Command
    60  	GetQueryCmd(*codec.Codec) *cobra.Command
    61  }
    62  
    63  // BasicManager is a collection of AppModuleBasic
    64  type BasicManager map[string]AppModuleBasic
    65  
    66  // NewBasicManager creates a new BasicManager object
    67  func NewBasicManager(modules ...AppModuleBasic) BasicManager {
    68  	moduleMap := make(map[string]AppModuleBasic)
    69  	for _, module := range modules {
    70  		moduleMap[module.Name()] = module
    71  	}
    72  	return moduleMap
    73  }
    74  
    75  // RegisterCodec registers all module codecs
    76  func (bm BasicManager) RegisterCodec(cdc *codec.Codec) {
    77  	for _, b := range bm {
    78  		b.RegisterCodec(cdc)
    79  	}
    80  }
    81  
    82  // DefaultGenesis provides default genesis information for all modules
    83  func (bm BasicManager) DefaultGenesis() map[string]json.RawMessage {
    84  	genesis := make(map[string]json.RawMessage)
    85  	for _, b := range bm {
    86  		genesis[b.Name()] = b.DefaultGenesis()
    87  	}
    88  	return genesis
    89  }
    90  
    91  // ValidateGenesis performs genesis state validation for all modules
    92  func (bm BasicManager) ValidateGenesis(genesis map[string]json.RawMessage) error {
    93  	for _, b := range bm {
    94  		if err := b.ValidateGenesis(genesis[b.Name()]); err != nil {
    95  			return err
    96  		}
    97  	}
    98  	return nil
    99  }
   100  
   101  // RegisterRESTRoutes registers all module rest routes
   102  func (bm BasicManager) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
   103  	for _, b := range bm {
   104  		b.RegisterRESTRoutes(ctx, rtr)
   105  	}
   106  }
   107  
   108  // AddTxCommands adds all tx commands to the rootTxCmd
   109  func (bm BasicManager) AddTxCommands(rootTxCmd *cobra.Command, cdc *codec.Codec) {
   110  	for _, b := range bm {
   111  		if cmd := b.GetTxCmd(cdc); cmd != nil {
   112  			rootTxCmd.AddCommand(cmd)
   113  		}
   114  	}
   115  }
   116  
   117  func (bm BasicManager) AddTxCommandsV2(rootTxCmd *cobra.Command, proxy *codec.CodecProxy, reg interfacetypes.InterfaceRegistry) {
   118  	for _, b := range bm {
   119  		if ada, ok := b.(AppModuleBasicAdapter); ok {
   120  			if cmd := ada.GetTxCmdV2(proxy, reg); cmd != nil {
   121  				rootTxCmd.AddCommand(cmd)
   122  			}
   123  		}
   124  	}
   125  }
   126  
   127  // AddQueryCommands adds all query commands to the rootQueryCmd
   128  func (bm BasicManager) AddQueryCommands(rootQueryCmd *cobra.Command, cdc *codec.Codec) {
   129  	for _, b := range bm {
   130  		if cmd := b.GetQueryCmd(cdc); cmd != nil {
   131  			rootQueryCmd.AddCommand(cmd)
   132  		}
   133  	}
   134  }
   135  
   136  func (bm BasicManager) AddQueryCommandsV2(rootQueryCmd *cobra.Command, proxy *codec.CodecProxy, reg interfacetypes.InterfaceRegistry) {
   137  	for _, b := range bm {
   138  		if ada, ok := b.(AppModuleBasicAdapter); ok {
   139  			if cmd := ada.GetQueryCmdV2(proxy, reg); cmd != nil {
   140  				rootQueryCmd.AddCommand(cmd)
   141  			}
   142  		}
   143  	}
   144  }
   145  
   146  //_________________________________________________________
   147  
   148  // AppModuleGenesis is the standard form for an application module genesis functions
   149  type AppModuleGenesis interface {
   150  	AppModuleBasic
   151  	InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate
   152  	ExportGenesis(sdk.Context) json.RawMessage
   153  }
   154  
   155  // AppModule is the standard form for an application module
   156  type AppModule interface {
   157  	AppModuleGenesis
   158  
   159  	// registers
   160  	RegisterInvariants(sdk.InvariantRegistry)
   161  
   162  	// routes
   163  	Route() string
   164  	NewHandler() sdk.Handler
   165  	QuerierRoute() string
   166  	NewQuerierHandler() sdk.Querier
   167  
   168  	// ABCI
   169  	BeginBlock(sdk.Context, abci.RequestBeginBlock)
   170  	EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
   171  }
   172  
   173  //___________________________
   174  
   175  // GenesisOnlyAppModule is an AppModule that only has import/export functionality
   176  type GenesisOnlyAppModule struct {
   177  	AppModuleGenesis
   178  }
   179  
   180  // NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
   181  func NewGenesisOnlyAppModule(amg AppModuleGenesis) AppModule {
   182  	return GenesisOnlyAppModule{
   183  		AppModuleGenesis: amg,
   184  	}
   185  }
   186  
   187  // RegisterInvariants is a placeholder function register no invariants
   188  func (GenesisOnlyAppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
   189  
   190  // Route empty module message route
   191  func (GenesisOnlyAppModule) Route() string { return "" }
   192  
   193  // NewHandler returns an empty module handler
   194  func (GenesisOnlyAppModule) NewHandler() sdk.Handler { return nil }
   195  
   196  // QuerierRoute returns an empty module querier route
   197  func (GenesisOnlyAppModule) QuerierRoute() string { return "" }
   198  
   199  // NewQuerierHandler returns an empty module querier
   200  func (gam GenesisOnlyAppModule) NewQuerierHandler() sdk.Querier { return nil }
   201  
   202  // BeginBlock returns an empty module begin-block
   203  func (gam GenesisOnlyAppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {}
   204  
   205  // EndBlock returns an empty module end-block
   206  func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
   207  	return []abci.ValidatorUpdate{}
   208  }
   209  
   210  //____________________________________________________________________________
   211  
   212  // Manager defines a module manager that provides the high level utility for managing and executing
   213  // operations for a group of modules
   214  type Manager struct {
   215  	Modules            map[string]AppModule
   216  	OrderInitGenesis   []string
   217  	OrderExportGenesis []string
   218  	OrderBeginBlockers []string
   219  	OrderEndBlockers   []string
   220  }
   221  
   222  // NewManager creates a new Manager object
   223  func NewManager(modules ...AppModule) *Manager {
   224  
   225  	moduleMap := make(map[string]AppModule)
   226  	modulesStr := make([]string, 0, len(modules))
   227  	for _, module := range modules {
   228  		moduleMap[module.Name()] = module
   229  		modulesStr = append(modulesStr, module.Name())
   230  	}
   231  
   232  	return &Manager{
   233  		Modules:            moduleMap,
   234  		OrderInitGenesis:   modulesStr,
   235  		OrderExportGenesis: modulesStr,
   236  		OrderBeginBlockers: modulesStr,
   237  		OrderEndBlockers:   modulesStr,
   238  	}
   239  }
   240  
   241  // SetOrderInitGenesis sets the order of init genesis calls
   242  func (m *Manager) SetOrderInitGenesis(moduleNames ...string) {
   243  	m.OrderInitGenesis = moduleNames
   244  }
   245  
   246  // SetOrderExportGenesis sets the order of export genesis calls
   247  func (m *Manager) SetOrderExportGenesis(moduleNames ...string) {
   248  	m.OrderExportGenesis = moduleNames
   249  }
   250  
   251  // SetOrderBeginBlockers sets the order of set begin-blocker calls
   252  func (m *Manager) SetOrderBeginBlockers(moduleNames ...string) {
   253  	m.OrderBeginBlockers = moduleNames
   254  }
   255  
   256  // SetOrderEndBlockers sets the order of set end-blocker calls
   257  func (m *Manager) SetOrderEndBlockers(moduleNames ...string) {
   258  	m.OrderEndBlockers = moduleNames
   259  }
   260  
   261  // RegisterInvariants registers all module routes and module querier routes
   262  func (m *Manager) RegisterInvariants(ir sdk.InvariantRegistry) {
   263  	for _, module := range m.Modules {
   264  		module.RegisterInvariants(ir)
   265  	}
   266  }
   267  
   268  // RegisterRoutes registers all module routes and module querier routes
   269  func (m *Manager) RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter) {
   270  	for _, module := range m.Modules {
   271  		if module.Route() != "" {
   272  			router.AddRoute(module.Route(), module.NewHandler())
   273  		}
   274  		if module.QuerierRoute() != "" {
   275  			queryRouter.AddRoute(module.QuerierRoute(), module.NewQuerierHandler())
   276  		}
   277  	}
   278  }
   279  
   280  // InitGenesis performs init genesis functionality for modules
   281  func (m *Manager) InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMessage) abci.ResponseInitChain {
   282  	var validatorUpdates []abci.ValidatorUpdate
   283  	for _, moduleName := range m.OrderInitGenesis {
   284  		if genesisData[moduleName] == nil {
   285  			continue
   286  		}
   287  		moduleValUpdates := m.Modules[moduleName].InitGenesis(ctx, genesisData[moduleName])
   288  
   289  		// use these validator updates if provided, the module manager assumes
   290  		// only one module will update the validator set
   291  		if len(moduleValUpdates) > 0 {
   292  			if len(validatorUpdates) > 0 {
   293  				panic("validator InitGenesis updates already set by a previous module")
   294  			}
   295  			validatorUpdates = moduleValUpdates
   296  		}
   297  	}
   298  	return abci.ResponseInitChain{
   299  		Validators: validatorUpdates,
   300  	}
   301  }
   302  
   303  // ExportGenesis performs export genesis functionality for modules
   304  func (m *Manager) ExportGenesis(ctx sdk.Context) map[string]json.RawMessage {
   305  	genesisData := make(map[string]json.RawMessage)
   306  	for _, moduleName := range m.OrderExportGenesis {
   307  		data := m.Modules[moduleName].ExportGenesis(ctx)
   308  		if nil == data {
   309  			continue
   310  		}
   311  		genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx)
   312  	}
   313  	return genesisData
   314  }
   315  
   316  // BeginBlock performs begin block functionality for all modules. It creates a
   317  // child context with an event manager to aggregate events emitted from all
   318  // modules.
   319  func (m *Manager) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
   320  	ctx.SetEventManager(sdk.NewEventManager())
   321  
   322  	for _, moduleName := range m.OrderBeginBlockers {
   323  		m.Modules[moduleName].BeginBlock(ctx, req)
   324  	}
   325  
   326  	return abci.ResponseBeginBlock{
   327  		Events: ctx.EventManager().ABCIEvents(),
   328  	}
   329  }
   330  
   331  // EndBlock performs end block functionality for all modules. It creates a
   332  // child context with an event manager to aggregate events emitted from all
   333  // modules.
   334  func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
   335  	ctx.SetEventManager(sdk.NewEventManager())
   336  	validatorUpdates := []abci.ValidatorUpdate{}
   337  
   338  	for _, moduleName := range m.OrderEndBlockers {
   339  		moduleValUpdates := m.Modules[moduleName].EndBlock(ctx, req)
   340  
   341  		// use these validator updates if provided, the module manager assumes
   342  		// only one module will update the validator set
   343  		if len(moduleValUpdates) > 0 {
   344  			if len(validatorUpdates) > 0 {
   345  				panic("validator EndBlock updates already set by a previous module")
   346  			}
   347  
   348  			validatorUpdates = moduleValUpdates
   349  		}
   350  	}
   351  
   352  	return abci.ResponseEndBlock{
   353  		ValidatorUpdates: validatorUpdates,
   354  		Events:           ctx.EventManager().ABCIEvents(),
   355  	}
   356  }
   357  
   358  // RegisterServices registers all module services
   359  func (m *Manager) RegisterServices(cfg Configurator) {
   360  	for _, module := range m.Modules {
   361  		if ada, ok := module.(AppModuleAdapter); ok {
   362  			ada.RegisterServices(cfg)
   363  		}
   364  	}
   365  }
   366  
   367  type MigrationHandler func(sdk.Context) error