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