Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow custom authority and inflation function when using app-wiring #12660

Merged
merged 10 commits into from
Jul 21, 2022
16 changes: 14 additions & 2 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,20 @@ func NewSimApp(
app = &SimApp{}
appBuilder *runtime.AppBuilder

// merge the app.yaml and the appOpts in one config
appConfig = depinject.Configs(AppConfig, depinject.Supply(appOpts))
// merge the AppConfig and other configuration in one config
appConfig = depinject.Configs(
AppConfig,
depinject.Supply(
// supply the application options
appOpts,

// for providing a custom inflaction function for x/mint
// add here your custom function that implements the minttypes.InflationCalculationFn interface.

// for providing a custom authority to a module simply add it below. By default the governance module is the default authority.
// e.g minttypes.MintAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
),
)
)

if err := depinject.Inject(appConfig,
Expand Down
17 changes: 12 additions & 5 deletions x/crisis/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,11 @@ func init() {
type crisisInputs struct {
depinject.In

Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
AppOpts servertypes.AppOptions `optional:"true"`
Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
AppOpts servertypes.AppOptions `optional:"true"`
Authority types.CrisisAuthority `optional:"true"`

BankKeeper types.SupplyKeeper

Expand All @@ -227,13 +228,19 @@ func provideModule(in crisisInputs) crisisOutputs {
feeCollectorName = authtypes.FeeCollectorName
}

authority := in.Authority
if authority == nil || len(authority) == 0 {
// default to governance authority if not provided
authority = types.CrisisAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
}

k := keeper.NewKeeper(
in.Cdc,
in.Key,
invalidCheckPeriod,
in.BankKeeper,
feeCollectorName,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
authority.String(),
)

skipGenesisInvariants := cast.ToBool(in.AppOpts.Get(FlagSkipGenesisInvariants))
Expand Down
11 changes: 11 additions & 0 deletions x/crisis/types/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type CrisisAuthority sdk.AccAddress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a need for a dedicated type (alias)?

Copy link
Member Author

@julienrbrt julienrbrt Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we named them all Authority, there would be a name collision.

Let me try another implementation to see which one you prefer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've simplified it in d623377. What do you think?


func (a CrisisAuthority) String() string {
return sdk.AccAddress(a).String()
}
15 changes: 11 additions & 4 deletions x/distribution/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,10 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper {
type distrInputs struct {
depinject.In

Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
Authority types.DistrAuthority `optional:"true"`

AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
Expand All @@ -264,14 +265,20 @@ func provideModule(in distrInputs) distrOutputs {
feeCollectorName = authtypes.FeeCollectorName
}

authority := in.Authority
if authority == nil || len(authority) == 0 {
// default to governance authority if not provided
authority = types.DistrAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
}

k := keeper.NewKeeper(
in.Cdc,
in.Key,
in.AccountKeeper,
in.BankKeeper,
in.StakingKeeper,
feeCollectorName,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
authority.String(),
)

m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, in.LegacySubspace)
Expand Down
11 changes: 11 additions & 0 deletions x/distribution/types/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type DistrAuthority sdk.AccAddress

func (a DistrAuthority) String() string {
return sdk.AccAddress(a).String()
}
20 changes: 14 additions & 6 deletions x/mint/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,11 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper {
type mintInputs struct {
depinject.In

Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
Config *modulev1.Module
Key *store.KVStoreKey
Cdc codec.Codec
Authority types.MintAuthority `optional:"true"`
Copy link
Member

@tac0turtle tac0turtle Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slightly lost where this gets set? I thought you would need to modify protobuf config of each module? (https://github.com/cosmos/cosmos-sdk/blob/main/proto/cosmos/mint/module/v1/module.proto#L13)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We set it in the app.go in depinject.Supply (see comments). This is because it could be just an address or we want to get a module address, so I don't think it can be in the app_config / app.yaml.

Copy link
Member

@tac0turtle tac0turtle Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. still trying to wrap my head around some of DI

InflationCalculationFn types.InflationCalculationFn `optional:"true"`

// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace
Expand All @@ -261,18 +263,24 @@ func provideModule(in mintInputs) mintOutputs {
feeCollectorName = authtypes.FeeCollectorName
}

authority := in.Authority
if authority == nil || len(authority) == 0 {
// default to governance authority if not provided
authority = types.MintAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
}

k := keeper.NewKeeper(
in.Cdc,
in.Key,
in.StakingKeeper,
in.AccountKeeper,
in.BankKeeper,
feeCollectorName,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
authority.String(),
)

// TODO: allow to set inflation calculation function
m := NewAppModule(in.Cdc, k, in.AccountKeeper, nil, in.LegacySubspace)
// when no inflation calculation function is provided it will use the default types.DefaultInflationCalculationFn
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.InflationCalculationFn, in.LegacySubspace)

return mintOutputs{MintKeeper: k, Module: runtime.WrapAppModule(m)}
}
11 changes: 11 additions & 0 deletions x/mint/types/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type MintAuthority sdk.AccAddress

func (a MintAuthority) String() string {
return sdk.AccAddress(a).String()
}
88 changes: 48 additions & 40 deletions x/slashing/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,39 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
BeginBlocker(ctx, req, am.keeper)
}

// _____________________________________________________________________________________
// AppModuleSimulation functions

// GenerateGenesisState creates a randomized GenState of the slashing module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}

// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return nil
}

// RandomizedParams creates randomized slashing param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
return []simtypes.ParamChange{}
}

// RegisterStoreDecoder registers a decoder for slashing module's types
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
}

// WeightedOperations returns the all the slashing module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
return simulation.WeightedOperations(
simState.AppParams, simState.Cdc,
am.accountKeeper, am.bankKeeper, am.keeper, am.stakingKeeper,
)
}

// ============================================================================
// New App Wiring Setup
// ============================================================================

func init() {
appmodule.Register(
Expand All @@ -203,12 +235,14 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper {
type slashingInputs struct {
depinject.In

Key *store.KVStoreKey
Cdc codec.Codec
LegacyAmino *codec.LegacyAmino
AccountKeeper types.AccountKeeper `key:"cosmos.auth.v1.AccountKeeper"`
BankKeeper types.BankKeeper `key:"cosmos.bank.v1.Keeper"`
StakingKeeper types.StakingKeeper `key:"cosmos.staking.v1.Keeper"`
Key *store.KVStoreKey
Cdc codec.Codec
LegacyAmino *codec.LegacyAmino
Authority types.SlashingAuthority `optional:"true"`

AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
StakingKeeper types.StakingKeeper

// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace
Expand All @@ -223,43 +257,17 @@ type slashingOutputs struct {
}

func provideModule(in slashingInputs) slashingOutputs {
k := keeper.NewKeeper(in.Cdc, in.LegacyAmino, in.Key, in.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String())
authority := in.Authority
if authority == nil || len(authority) == 0 {
// default to governance authority if not provided
authority = types.SlashingAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
}

k := keeper.NewKeeper(in.Cdc, in.LegacyAmino, in.Key, in.StakingKeeper, authority.String())
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, in.LegacySubspace)
return slashingOutputs{
Keeper: k,
Module: runtime.WrapAppModule(m),
Hooks: staking.StakingHooksWrapper{StakingHooks: k.Hooks()},
}
}

// _____________________________________________________________________________________

// AppModuleSimulation functions

// GenerateGenesisState creates a randomized GenState of the slashing module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}

// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return nil
}

// RandomizedParams creates randomized slashing param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
return []simtypes.ParamChange{}
}

// RegisterStoreDecoder registers a decoder for slashing module's types
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
}

// WeightedOperations returns the all the slashing module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
return simulation.WeightedOperations(
simState.AppParams, simState.Cdc,
am.accountKeeper, am.bankKeeper, am.keeper, am.stakingKeeper,
)
}
11 changes: 11 additions & 0 deletions x/slashing/types/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type SlashingAuthority sdk.AccAddress

func (a SlashingAuthority) String() string {
return sdk.AccAddress(a).String()
}
11 changes: 9 additions & 2 deletions x/upgrade/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ type upgradeInputs struct {
Key *store.KVStoreKey
Cdc codec.Codec

AppOpts servertypes.AppOptions `optional:"true"`
AppOpts servertypes.AppOptions `optional:"true"`
Authority types.UpgradeAuthority `optional:"true"`
}

type upgradeOutputs struct {
Expand All @@ -197,8 +198,14 @@ func provideModule(in upgradeInputs) upgradeOutputs {
homePath = cast.ToString(in.AppOpts.Get(flags.FlagHome))
}

authority := in.Authority
if authority == nil || len(authority) == 0 {
// default to governance authority if not provided
authority = types.UpgradeAuthority(authtypes.NewModuleAddress(govtypes.ModuleName))
}

// set the governance module account as the authority for conducting upgrades
k := keeper.NewKeeper(skipUpgradeHeights, in.Key, in.Cdc, homePath, nil, authtypes.NewModuleAddress(govtypes.ModuleName).String())
k := keeper.NewKeeper(skipUpgradeHeights, in.Key, in.Cdc, homePath, nil, authority.String())
m := NewAppModule(k)
gh := govv1beta1.HandlerRoute{RouteKey: types.RouterKey, Handler: NewSoftwareUpgradeProposalHandler(k)}

Expand Down
11 changes: 11 additions & 0 deletions x/upgrade/types/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type UpgradeAuthority sdk.AccAddress

func (a UpgradeAuthority) String() string {
return sdk.AccAddress(a).String()
}