cosmos-sdk/x/gov/depinject.go

136 lines
3.6 KiB
Go

package gov
import (
"fmt"
"maps"
"slices"
"strings"
modulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
govclient "cosmossdk.io/x/gov/client"
"cosmossdk.io/x/gov/keeper"
govtypes "cosmossdk.io/x/gov/types"
"cosmossdk.io/x/gov/types/v1beta1"
"github.com/cosmos/cosmos-sdk/codec"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var _ depinject.OnePerModuleType = AppModule{}
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule) IsOnePerModuleType() {}
func init() {
appconfig.RegisterModule(
&modulev1.Module{},
appconfig.Invoke(InvokeAddRoutes, InvokeSetHooks),
appconfig.Provide(ProvideModule))
}
type ModuleInputs struct {
depinject.In
Config *modulev1.Module
Cdc codec.Codec
Environment appmodule.Environment
ModuleKey depinject.OwnModuleKey
LegacyProposalHandler []govclient.ProposalHandler `optional:"true"`
AccountKeeper govtypes.AccountKeeper
BankKeeper govtypes.BankKeeper
StakingKeeper govtypes.StakingKeeper
PoolKeeper govtypes.PoolKeeper
}
type ModuleOutputs struct {
depinject.Out
Module appmodule.AppModule
Keeper *keeper.Keeper
HandlerRoute v1beta1.HandlerRoute
}
func ProvideModule(in ModuleInputs) ModuleOutputs {
defaultConfig := keeper.DefaultConfig()
if in.Config.MaxTitleLen != 0 {
defaultConfig.MaxTitleLen = in.Config.MaxTitleLen
}
if in.Config.MaxMetadataLen != 0 {
defaultConfig.MaxMetadataLen = in.Config.MaxMetadataLen
}
if in.Config.MaxSummaryLen != 0 {
defaultConfig.MaxSummaryLen = in.Config.MaxSummaryLen
}
if in.LegacyProposalHandler == nil {
in.LegacyProposalHandler = []govclient.ProposalHandler{}
}
// default to governance authority if not provided
authority := authtypes.NewModuleAddress(govtypes.ModuleName)
if in.Config.Authority != "" {
authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
}
authorityAddr, err := in.AccountKeeper.AddressCodec().BytesToString(authority)
if err != nil {
panic(err)
}
k := keeper.NewKeeper(
in.Cdc,
in.Environment,
in.AccountKeeper,
in.BankKeeper,
in.StakingKeeper,
in.PoolKeeper,
defaultConfig,
authorityAddr,
)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.PoolKeeper, in.LegacyProposalHandler...)
hr := v1beta1.HandlerRoute{Handler: v1beta1.ProposalHandler, RouteKey: govtypes.RouterKey}
return ModuleOutputs{Module: m, Keeper: k, HandlerRoute: hr}
}
func InvokeAddRoutes(keeper *keeper.Keeper, routes []v1beta1.HandlerRoute) {
if keeper == nil || routes == nil {
return
}
// Default route order is a lexical sort by RouteKey.
// Explicit ordering can be added to the module config if required.
slices.SortFunc(routes, func(x, y v1beta1.HandlerRoute) int {
return strings.Compare(x.RouteKey, y.RouteKey)
})
router := v1beta1.NewRouter()
for _, r := range routes {
router.AddRoute(r.RouteKey, r.Handler)
}
keeper.SetLegacyRouter(router)
}
func InvokeSetHooks(keeper *keeper.Keeper, govHooks map[string]govtypes.GovHooksWrapper) error {
if keeper == nil || govHooks == nil {
return nil
}
// Default ordering is lexical by module name.
// Explicit ordering can be added to the module config if required.
modNames := slices.Sorted(maps.Keys(govHooks))
var multiHooks govtypes.MultiGovHooks
for _, modName := range modNames {
hook, ok := govHooks[modName]
if !ok {
return fmt.Errorf("can't find staking hooks for module %s", modName)
}
multiHooks = append(multiHooks, hook)
}
keeper.SetHooks(multiHooks)
return nil
}