cosmos-sdk/runtime/module.go
Facundo Medica 2b7aca73d2
feat: add MsgServiceRouter to Baseapp (and runtime's provideCodecs) (#12168)
## Description

This PR adds a way to provide through depinject BaseApp's MsgServiceRouter, required for `x/auth`. Ref: #12125



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
2022-06-06 20:58:28 +00:00

134 lines
3.7 KiB
Go

package runtime
import (
"fmt"
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
"cosmossdk.io/core/appmodule"
"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/depinject"
"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() {}
// appWrapper is used to pass around an instance of *App internally between
// runtime dependency inject providers that is partially constructed (no
// baseapp yet).
type appWrapper *App
func init() {
appmodule.Register(&runtimev1alpha1.Module{},
appmodule.Provide(
provideCodecs,
provideAppBuilder,
provideKVStoreKey,
provideTransientStoreKey,
provideMemoryStoreKey,
),
)
}
func provideCodecs(moduleBasics map[string]AppModuleBasicWrapper) (
codectypes.InterfaceRegistry,
codec.Codec,
*codec.LegacyAmino,
appWrapper,
codec.ProtoCodecMarshaler,
*baseapp.MsgServiceRouter,
) {
interfaceRegistry := codectypes.NewInterfaceRegistry()
amino := codec.NewLegacyAmino()
// build codecs
basicManager := module.BasicManager{}
for name, wrapper := range moduleBasics {
basicManager[name] = wrapper
wrapper.RegisterInterfaces(interfaceRegistry)
wrapper.RegisterLegacyAminoCodec(amino)
}
std.RegisterInterfaces(interfaceRegistry)
std.RegisterLegacyAminoCodec(amino)
cdc := codec.NewProtoCodec(interfaceRegistry)
app := &App{
storeKeys: nil,
interfaceRegistry: interfaceRegistry,
cdc: cdc,
amino: amino,
basicManager: basicManager,
}
return interfaceRegistry, cdc, amino, app, cdc, baseapp.NewMsgServiceRouter()
}
type appInputs struct {
depinject.In
Config *runtimev1alpha1.Module
App appWrapper
Modules map[string]AppModuleWrapper
BaseAppOptions []BaseAppOption
}
func provideAppBuilder(inputs appInputs) *AppBuilder {
mm := &module.Manager{Modules: map[string]module.AppModule{}}
for name, wrapper := range inputs.Modules {
mm.Modules[name] = wrapper.AppModule
}
app := inputs.App
app.baseAppOptions = inputs.BaseAppOptions
app.config = inputs.Config
app.ModuleManager = mm
return &AppBuilder{app: app}
}
func registerStoreKey(wrapper appWrapper, key storetypes.StoreKey) {
wrapper.storeKeys = append(wrapper.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 appWrapper) *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 appWrapper) *storetypes.TransientStoreKey {
storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}
func provideMemoryStoreKey(key depinject.ModuleKey, app appWrapper) *storetypes.MemoryStoreKey {
storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}