github.com/cosmos/cosmos-sdk@v0.50.10/runtime/module.go (about) 1 package runtime 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/cosmos/gogoproto/proto" 8 "google.golang.org/protobuf/reflect/protodesc" 9 "google.golang.org/protobuf/reflect/protoregistry" 10 11 runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" 12 appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" 13 authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1" 14 stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1" 15 "cosmossdk.io/core/address" 16 "cosmossdk.io/core/appmodule" 17 "cosmossdk.io/core/comet" 18 "cosmossdk.io/core/event" 19 "cosmossdk.io/core/genesis" 20 "cosmossdk.io/core/header" 21 "cosmossdk.io/core/store" 22 "cosmossdk.io/depinject" 23 "cosmossdk.io/log" 24 storetypes "cosmossdk.io/store/types" 25 "cosmossdk.io/x/tx/signing" 26 27 "github.com/cosmos/cosmos-sdk/baseapp" 28 "github.com/cosmos/cosmos-sdk/codec" 29 addresscodec "github.com/cosmos/cosmos-sdk/codec/address" 30 codectypes "github.com/cosmos/cosmos-sdk/codec/types" 31 "github.com/cosmos/cosmos-sdk/std" 32 "github.com/cosmos/cosmos-sdk/types/module" 33 "github.com/cosmos/cosmos-sdk/types/msgservice" 34 ) 35 36 type appModule struct { 37 app *App 38 } 39 40 func (m appModule) RegisterServices(configurator module.Configurator) { 41 err := m.app.registerRuntimeServices(configurator) 42 if err != nil { 43 panic(err) 44 } 45 } 46 47 func (m appModule) IsOnePerModuleType() {} 48 func (m appModule) IsAppModule() {} 49 50 var ( 51 _ appmodule.AppModule = appModule{} 52 _ module.HasServices = appModule{} 53 ) 54 55 // BaseAppOption is a depinject.AutoGroupType which can be used to pass 56 // BaseApp options into the depinject. It should be used carefully. 57 type BaseAppOption func(*baseapp.BaseApp) 58 59 // IsManyPerContainerType indicates that this is a depinject.ManyPerContainerType. 60 func (b BaseAppOption) IsManyPerContainerType() {} 61 62 func init() { 63 appmodule.Register(&runtimev1alpha1.Module{}, 64 appmodule.Provide( 65 ProvideApp, 66 ProvideInterfaceRegistry, 67 ProvideKVStoreKey, 68 ProvideTransientStoreKey, 69 ProvideMemoryStoreKey, 70 ProvideGenesisTxHandler, 71 ProvideKVStoreService, 72 ProvideMemoryStoreService, 73 ProvideTransientStoreService, 74 ProvideEventService, 75 ProvideHeaderInfoService, 76 ProvideCometInfoService, 77 ProvideBasicManager, 78 ProvideAddressCodec, 79 ), 80 appmodule.Invoke(SetupAppBuilder), 81 ) 82 } 83 84 func ProvideApp(interfaceRegistry codectypes.InterfaceRegistry) ( 85 codec.Codec, 86 *codec.LegacyAmino, 87 *AppBuilder, 88 *baseapp.MsgServiceRouter, 89 *baseapp.GRPCQueryRouter, 90 appmodule.AppModule, 91 protodesc.Resolver, 92 protoregistry.MessageTypeResolver, 93 error, 94 ) { 95 protoFiles := proto.HybridResolver 96 protoTypes := protoregistry.GlobalTypes 97 98 // At startup, check that all proto annotations are correct. 99 if err := msgservice.ValidateProtoAnnotations(protoFiles); err != nil { 100 // Once we switch to using protoreflect-based ante handlers, we might 101 // want to panic here instead of logging a warning. 102 _, _ = fmt.Fprintln(os.Stderr, err.Error()) 103 } 104 105 amino := codec.NewLegacyAmino() 106 107 std.RegisterInterfaces(interfaceRegistry) 108 std.RegisterLegacyAminoCodec(amino) 109 110 cdc := codec.NewProtoCodec(interfaceRegistry) 111 msgServiceRouter := baseapp.NewMsgServiceRouter() 112 grpcQueryRouter := baseapp.NewGRPCQueryRouter() 113 app := &App{ 114 storeKeys: nil, 115 interfaceRegistry: interfaceRegistry, 116 cdc: cdc, 117 amino: amino, 118 basicManager: module.BasicManager{}, 119 msgServiceRouter: msgServiceRouter, 120 grpcQueryRouter: grpcQueryRouter, 121 } 122 appBuilder := &AppBuilder{app} 123 124 return cdc, amino, appBuilder, msgServiceRouter, grpcQueryRouter, appModule{app}, protoFiles, protoTypes, nil 125 } 126 127 type AppInputs struct { 128 depinject.In 129 130 AppConfig *appv1alpha1.Config `optional:"true"` 131 Config *runtimev1alpha1.Module 132 AppBuilder *AppBuilder 133 Modules map[string]appmodule.AppModule 134 CustomModuleBasics map[string]module.AppModuleBasic `optional:"true"` 135 BaseAppOptions []BaseAppOption 136 InterfaceRegistry codectypes.InterfaceRegistry 137 LegacyAmino *codec.LegacyAmino 138 Logger log.Logger 139 } 140 141 func SetupAppBuilder(inputs AppInputs) { 142 app := inputs.AppBuilder.app 143 app.baseAppOptions = inputs.BaseAppOptions 144 app.config = inputs.Config 145 app.appConfig = inputs.AppConfig 146 app.logger = inputs.Logger 147 app.ModuleManager = module.NewManagerFromMap(inputs.Modules) 148 149 for name, mod := range inputs.Modules { 150 if customBasicMod, ok := inputs.CustomModuleBasics[name]; ok { 151 app.basicManager[name] = customBasicMod 152 customBasicMod.RegisterInterfaces(inputs.InterfaceRegistry) 153 customBasicMod.RegisterLegacyAminoCodec(inputs.LegacyAmino) 154 continue 155 } 156 157 coreAppModuleBasic := module.CoreAppModuleBasicAdaptor(name, mod) 158 app.basicManager[name] = coreAppModuleBasic 159 coreAppModuleBasic.RegisterInterfaces(inputs.InterfaceRegistry) 160 coreAppModuleBasic.RegisterLegacyAminoCodec(inputs.LegacyAmino) 161 } 162 } 163 164 func ProvideInterfaceRegistry(addressCodec address.Codec, validatorAddressCodec ValidatorAddressCodec, customGetSigners []signing.CustomGetSigner) (codectypes.InterfaceRegistry, error) { 165 signingOptions := signing.Options{ 166 AddressCodec: addressCodec, 167 ValidatorAddressCodec: validatorAddressCodec, 168 } 169 for _, signer := range customGetSigners { 170 signingOptions.DefineCustomGetSigners(signer.MsgType, signer.Fn) 171 } 172 173 interfaceRegistry, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{ 174 ProtoFiles: proto.HybridResolver, 175 SigningOptions: signingOptions, 176 }) 177 if err != nil { 178 return nil, err 179 } 180 181 if err := interfaceRegistry.SigningContext().Validate(); err != nil { 182 return nil, err 183 } 184 185 return interfaceRegistry, nil 186 } 187 188 func registerStoreKey(wrapper *AppBuilder, key storetypes.StoreKey) { 189 wrapper.app.storeKeys = append(wrapper.app.storeKeys, key) 190 } 191 192 func storeKeyOverride(config *runtimev1alpha1.Module, moduleName string) *runtimev1alpha1.StoreKeyConfig { 193 for _, cfg := range config.OverrideStoreKeys { 194 if cfg.ModuleName == moduleName { 195 return cfg 196 } 197 } 198 return nil 199 } 200 201 func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.KVStoreKey { 202 override := storeKeyOverride(config, key.Name()) 203 204 var storeKeyName string 205 if override != nil { 206 storeKeyName = override.KvStoreKey 207 } else { 208 storeKeyName = key.Name() 209 } 210 211 storeKey := storetypes.NewKVStoreKey(storeKeyName) 212 registerStoreKey(app, storeKey) 213 return storeKey 214 } 215 216 func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey { 217 storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name())) 218 registerStoreKey(app, storeKey) 219 return storeKey 220 } 221 222 func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey { 223 storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name())) 224 registerStoreKey(app, storeKey) 225 return storeKey 226 } 227 228 func ProvideGenesisTxHandler(appBuilder *AppBuilder) genesis.TxHandler { 229 return appBuilder.app 230 } 231 232 func ProvideKVStoreService(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) store.KVStoreService { 233 storeKey := ProvideKVStoreKey(config, key, app) 234 return kvStoreService{key: storeKey} 235 } 236 237 func ProvideMemoryStoreService(key depinject.ModuleKey, app *AppBuilder) store.MemoryStoreService { 238 storeKey := ProvideMemoryStoreKey(key, app) 239 return memStoreService{key: storeKey} 240 } 241 242 func ProvideTransientStoreService(key depinject.ModuleKey, app *AppBuilder) store.TransientStoreService { 243 storeKey := ProvideTransientStoreKey(key, app) 244 return transientStoreService{key: storeKey} 245 } 246 247 func ProvideEventService() event.Service { 248 return EventService{} 249 } 250 251 func ProvideCometInfoService() comet.BlockInfoService { 252 return cometInfoService{} 253 } 254 255 func ProvideHeaderInfoService(app *AppBuilder) header.Service { 256 return headerInfoService{} 257 } 258 259 func ProvideBasicManager(app *AppBuilder) module.BasicManager { 260 return app.app.basicManager 261 } 262 263 type ( 264 // ValidatorAddressCodec is an alias for address.Codec for validator addresses. 265 ValidatorAddressCodec address.Codec 266 267 // ConsensusAddressCodec is an alias for address.Codec for validator consensus addresses. 268 ConsensusAddressCodec address.Codec 269 ) 270 271 type AddressCodecInputs struct { 272 depinject.In 273 274 AuthConfig *authmodulev1.Module `optional:"true"` 275 StakingConfig *stakingmodulev1.Module `optional:"true"` 276 277 AddressCodecFactory func() address.Codec `optional:"true"` 278 ValidatorAddressCodecFactory func() ValidatorAddressCodec `optional:"true"` 279 ConsensusAddressCodecFactory func() ConsensusAddressCodec `optional:"true"` 280 } 281 282 // ProvideAddressCodec provides an address.Codec to the container for any 283 // modules that want to do address string <> bytes conversion. 284 func ProvideAddressCodec(in AddressCodecInputs) (address.Codec, ValidatorAddressCodec, ConsensusAddressCodec) { 285 if in.AddressCodecFactory != nil && in.ValidatorAddressCodecFactory != nil && in.ConsensusAddressCodecFactory != nil { 286 return in.AddressCodecFactory(), in.ValidatorAddressCodecFactory(), in.ConsensusAddressCodecFactory() 287 } 288 289 if in.AuthConfig == nil || in.AuthConfig.Bech32Prefix == "" { 290 panic("auth config bech32 prefix cannot be empty if no custom address codec is provided") 291 } 292 293 if in.StakingConfig == nil { 294 in.StakingConfig = &stakingmodulev1.Module{} 295 } 296 297 if in.StakingConfig.Bech32PrefixValidator == "" { 298 in.StakingConfig.Bech32PrefixValidator = fmt.Sprintf("%svaloper", in.AuthConfig.Bech32Prefix) 299 } 300 301 if in.StakingConfig.Bech32PrefixConsensus == "" { 302 in.StakingConfig.Bech32PrefixConsensus = fmt.Sprintf("%svalcons", in.AuthConfig.Bech32Prefix) 303 } 304 305 return addresscodec.NewBech32Codec(in.AuthConfig.Bech32Prefix), 306 addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixValidator), 307 addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixConsensus) 308 }