Merge PR #4854: Crisis Module Manager Fixes
This commit is contained in:
parent
1f8cdeed55
commit
c8ee82b40a
|
@ -163,14 +163,17 @@ func NewSimApp(
|
||||||
// register the staking hooks
|
// register the staking hooks
|
||||||
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
|
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
|
||||||
app.stakingKeeper = *stakingKeeper.SetHooks(
|
app.stakingKeeper = *stakingKeeper.SetHooks(
|
||||||
staking.NewMultiStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()))
|
staking.NewMultiStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()),
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: Any module instantiated in the module manager that is later modified
|
||||||
|
// must be passed by reference here.
|
||||||
app.mm = module.NewManager(
|
app.mm = module.NewManager(
|
||||||
genaccounts.NewAppModule(app.accountKeeper),
|
genaccounts.NewAppModule(app.accountKeeper),
|
||||||
genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx),
|
genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx),
|
||||||
auth.NewAppModule(app.accountKeeper),
|
auth.NewAppModule(app.accountKeeper),
|
||||||
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
|
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
|
||||||
crisis.NewAppModule(app.crisisKeeper),
|
crisis.NewAppModule(&app.crisisKeeper),
|
||||||
supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
|
supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
|
||||||
distr.NewAppModule(app.distrKeeper, app.supplyKeeper),
|
distr.NewAppModule(app.distrKeeper, app.supplyKeeper),
|
||||||
gov.NewAppModule(app.govKeeper, app.supplyKeeper),
|
gov.NewAppModule(app.govKeeper, app.supplyKeeper),
|
||||||
|
@ -184,13 +187,15 @@ func NewSimApp(
|
||||||
// CanWithdrawInvariant invariant.
|
// CanWithdrawInvariant invariant.
|
||||||
app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName)
|
app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName)
|
||||||
|
|
||||||
app.mm.SetOrderEndBlockers(gov.ModuleName, staking.ModuleName)
|
app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName)
|
||||||
|
|
||||||
// genutils must occur after staking so that pools are properly
|
// NOTE: The genutils moodule must occur after staking so that pools are
|
||||||
// initialized with tokens from genesis accounts.
|
// properly initialized with tokens from genesis accounts.
|
||||||
app.mm.SetOrderInitGenesis(genaccounts.ModuleName, distr.ModuleName,
|
app.mm.SetOrderInitGenesis(
|
||||||
staking.ModuleName, auth.ModuleName, bank.ModuleName, slashing.ModuleName,
|
genaccounts.ModuleName, distr.ModuleName, staking.ModuleName,
|
||||||
gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName)
|
auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName,
|
||||||
|
mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName,
|
||||||
|
)
|
||||||
|
|
||||||
app.mm.RegisterInvariants(&app.crisisKeeper)
|
app.mm.RegisterInvariants(&app.crisisKeeper)
|
||||||
app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
|
app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
|
||||||
|
|
|
@ -554,7 +554,7 @@ func TestAppImportExport(t *testing.T) {
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
newDB.Close()
|
newDB.Close()
|
||||||
os.RemoveAll(newDir)
|
_ = os.RemoveAll(newDir)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
||||||
|
@ -566,11 +566,11 @@ func TestAppImportExport(t *testing.T) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxB := newApp.NewContext(true, abci.Header{})
|
ctxB := newApp.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
|
||||||
newApp.mm.InitGenesis(ctxB, genesisState)
|
newApp.mm.InitGenesis(ctxB, genesisState)
|
||||||
|
|
||||||
fmt.Printf("Comparing stores...\n")
|
fmt.Printf("Comparing stores...\n")
|
||||||
ctxA := app.NewContext(true, abci.Header{})
|
ctxA := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
|
||||||
|
|
||||||
type StoreKeysPrefixes struct {
|
type StoreKeysPrefixes struct {
|
||||||
A sdk.StoreKey
|
A sdk.StoreKey
|
||||||
|
|
|
@ -23,11 +23,13 @@ type Keeper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeeper creates a new Keeper object
|
// NewKeeper creates a new Keeper object
|
||||||
func NewKeeper(paramSpace params.Subspace, invCheckPeriod uint,
|
func NewKeeper(
|
||||||
supplyKeeper types.SupplyKeeper, feeCollectorName string) Keeper {
|
paramSpace params.Subspace, invCheckPeriod uint, supplyKeeper types.SupplyKeeper,
|
||||||
|
feeCollectorName string,
|
||||||
|
) Keeper {
|
||||||
|
|
||||||
return Keeper{
|
return Keeper{
|
||||||
routes: []types.InvarRoute{},
|
routes: make([]types.InvarRoute, 0),
|
||||||
paramSpace: paramSpace.WithKeyTable(types.ParamKeyTable()),
|
paramSpace: paramSpace.WithKeyTable(types.ParamKeyTable()),
|
||||||
invCheckPeriod: invCheckPeriod,
|
invCheckPeriod: invCheckPeriod,
|
||||||
supplyKeeper: supplyKeeper,
|
supplyKeeper: supplyKeeper,
|
||||||
|
@ -53,22 +55,23 @@ func (k Keeper) Routes() []types.InvarRoute {
|
||||||
|
|
||||||
// Invariants returns all the registered Crisis keeper invariants.
|
// Invariants returns all the registered Crisis keeper invariants.
|
||||||
func (k Keeper) Invariants() []sdk.Invariant {
|
func (k Keeper) Invariants() []sdk.Invariant {
|
||||||
var invars []sdk.Invariant
|
invars := make([]sdk.Invariant, len(k.routes))
|
||||||
for _, route := range k.routes {
|
for i, route := range k.routes {
|
||||||
invars = append(invars, route.Invar)
|
invars[i] = route.Invar
|
||||||
}
|
}
|
||||||
return invars
|
return invars
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert all invariants
|
// AssertInvariants asserts all registered invariants. If any invariant fails,
|
||||||
|
// the method panics.
|
||||||
func (k Keeper) AssertInvariants(ctx sdk.Context) {
|
func (k Keeper) AssertInvariants(ctx sdk.Context) {
|
||||||
logger := k.Logger(ctx)
|
logger := k.Logger(ctx)
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
invarRoutes := k.Routes()
|
invarRoutes := k.Routes()
|
||||||
|
|
||||||
for _, ir := range invarRoutes {
|
for _, ir := range invarRoutes {
|
||||||
if res, stop := ir.Invar(ctx); stop {
|
if res, stop := ir.Invar(ctx); stop {
|
||||||
|
|
||||||
// TODO: Include app name as part of context to allow for this to be
|
// TODO: Include app name as part of context to allow for this to be
|
||||||
// variable.
|
// variable.
|
||||||
panic(fmt.Errorf("invariant broken: %s\n"+
|
panic(fmt.Errorf("invariant broken: %s\n"+
|
||||||
|
@ -90,5 +93,3 @@ func (k Keeper) InvCheckPeriod() uint { return k.invCheckPeriod }
|
||||||
func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||||
return k.supplyKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, k.feeCollectorName, amt)
|
return k.supplyKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, k.feeCollectorName, amt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DONTCOVER
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/crisis/internal/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testPassingInvariant(_ sdk.Context) (string, bool) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFailingInvariant(_ sdk.Context) (string, bool) {
|
||||||
|
return "", true
|
||||||
|
}
|
||||||
|
|
||||||
|
func testKeeper(checkPeriod uint) Keeper {
|
||||||
|
cdc := codec.New()
|
||||||
|
paramsKeeper := params.NewKeeper(
|
||||||
|
cdc, sdk.NewKVStoreKey(params.StoreKey), sdk.NewTransientStoreKey(params.TStoreKey), params.DefaultCodespace,
|
||||||
|
)
|
||||||
|
|
||||||
|
return NewKeeper(paramsKeeper.Subspace(types.DefaultParamspace), checkPeriod, nil, "test")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogger(t *testing.T) {
|
||||||
|
k := testKeeper(5)
|
||||||
|
|
||||||
|
ctx := sdk.Context{}.WithLogger(log.NewNopLogger())
|
||||||
|
require.Equal(t, ctx.Logger(), k.Logger(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvariants(t *testing.T) {
|
||||||
|
k := testKeeper(5)
|
||||||
|
require.Equal(t, k.InvCheckPeriod(), uint(5))
|
||||||
|
|
||||||
|
k.RegisterRoute("testModule", "testRoute", testPassingInvariant)
|
||||||
|
require.Len(t, k.Routes(), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssertInvariants(t *testing.T) {
|
||||||
|
k := testKeeper(5)
|
||||||
|
ctx := sdk.Context{}.WithLogger(log.NewNopLogger())
|
||||||
|
|
||||||
|
k.RegisterRoute("testModule", "testRoute1", testPassingInvariant)
|
||||||
|
require.NotPanics(t, func() { k.AssertInvariants(ctx) })
|
||||||
|
|
||||||
|
k.RegisterRoute("testModule", "testRoute2", testFailingInvariant)
|
||||||
|
require.Panics(t, func() { k.AssertInvariants(ctx) })
|
||||||
|
}
|
|
@ -22,27 +22,26 @@ var (
|
||||||
_ module.AppModuleBasic = AppModuleBasic{}
|
_ module.AppModuleBasic = AppModuleBasic{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// app module basics object
|
// AppModuleBasic defines the basic application module used by the crisis module.
|
||||||
type AppModuleBasic struct{}
|
type AppModuleBasic struct{}
|
||||||
|
|
||||||
var _ module.AppModuleBasic = AppModuleBasic{}
|
// Name returns the crisis module's name.
|
||||||
|
|
||||||
// module name
|
|
||||||
func (AppModuleBasic) Name() string {
|
func (AppModuleBasic) Name() string {
|
||||||
return ModuleName
|
return ModuleName
|
||||||
}
|
}
|
||||||
|
|
||||||
// register module codec
|
// RegisterCodec registers the crisis module's types for the given codec.
|
||||||
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
||||||
RegisterCodec(cdc)
|
RegisterCodec(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// default genesis state
|
// DefaultGenesis returns default genesis state as raw bytes for the crisis
|
||||||
|
// module.
|
||||||
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
||||||
return types.ModuleCdc.MustMarshalJSON(DefaultGenesisState())
|
return types.ModuleCdc.MustMarshalJSON(DefaultGenesisState())
|
||||||
}
|
}
|
||||||
|
|
||||||
// module validate genesis
|
// ValidateGenesis performs genesis state validation for the crisis module.
|
||||||
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
||||||
var data types.GenesisState
|
var data types.GenesisState
|
||||||
if err := types.ModuleCdc.UnmarshalJSON(bz, &data); err != nil {
|
if err := types.ModuleCdc.UnmarshalJSON(bz, &data); err != nil {
|
||||||
|
@ -51,77 +50,83 @@ func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
||||||
return types.ValidateGenesis(data)
|
return types.ValidateGenesis(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// register rest routes
|
// RegisterRESTRoutes registers no REST routes for the crisis module.
|
||||||
func (AppModuleBasic) RegisterRESTRoutes(_ context.CLIContext, _ *mux.Router) {}
|
func (AppModuleBasic) RegisterRESTRoutes(_ context.CLIContext, _ *mux.Router) {}
|
||||||
|
|
||||||
// get the root tx command of this module
|
// GetTxCmd returns the root tx command for the crisis module.
|
||||||
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
||||||
return cli.GetTxCmd(cdc)
|
return cli.GetTxCmd(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the root query command of this module
|
// GetQueryCmd returns no root query command for the crisis module.
|
||||||
func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
|
func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
|
||||||
|
|
||||||
//___________________________
|
// AppModule implements an application module for the crisis module.
|
||||||
// app module for bank
|
|
||||||
type AppModule struct {
|
type AppModule struct {
|
||||||
AppModuleBasic
|
AppModuleBasic
|
||||||
keeper keeper.Keeper
|
|
||||||
|
// NOTE: We store a reference to the keeper here so that after a module
|
||||||
|
// manager is created, the invariants can be properly registered and
|
||||||
|
// executed.
|
||||||
|
keeper *keeper.Keeper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAppModule creates a new AppModule object
|
// NewAppModule creates a new AppModule object
|
||||||
func NewAppModule(keeper keeper.Keeper) AppModule {
|
func NewAppModule(keeper *keeper.Keeper) AppModule {
|
||||||
return AppModule{
|
return AppModule{
|
||||||
AppModuleBasic: AppModuleBasic{},
|
AppModuleBasic: AppModuleBasic{},
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// module name
|
// Name returns the crisis module's name.
|
||||||
func (AppModule) Name() string {
|
func (AppModule) Name() string {
|
||||||
return ModuleName
|
return ModuleName
|
||||||
}
|
}
|
||||||
|
|
||||||
// register invariants
|
// RegisterInvariants performs a no-op.
|
||||||
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
||||||
|
|
||||||
// module querier route name
|
// Route returns the message routing key for the crisis module.
|
||||||
func (AppModule) Route() string {
|
func (AppModule) Route() string {
|
||||||
return RouterKey
|
return RouterKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// module handler
|
// NewHandler returns an sdk.Handler for the crisis module.
|
||||||
func (am AppModule) NewHandler() sdk.Handler {
|
func (am AppModule) NewHandler() sdk.Handler {
|
||||||
return NewHandler(am.keeper)
|
return NewHandler(*am.keeper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// module querier route name
|
// QuerierRoute returns no querier route.
|
||||||
func (AppModule) QuerierRoute() string { return "" }
|
func (AppModule) QuerierRoute() string { return "" }
|
||||||
|
|
||||||
// module querier
|
// NewQuerierHandler returns no sdk.Querier.
|
||||||
func (AppModule) NewQuerierHandler() sdk.Querier { return nil }
|
func (AppModule) NewQuerierHandler() sdk.Querier { return nil }
|
||||||
|
|
||||||
// module init-genesis
|
// InitGenesis performs genesis initialization for the crisis module. It returns
|
||||||
|
// no validator updates.
|
||||||
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
||||||
var genesisState GenesisState
|
var genesisState GenesisState
|
||||||
types.ModuleCdc.MustUnmarshalJSON(data, &genesisState)
|
types.ModuleCdc.MustUnmarshalJSON(data, &genesisState)
|
||||||
InitGenesis(ctx, am.keeper, genesisState)
|
InitGenesis(ctx, *am.keeper, genesisState)
|
||||||
|
|
||||||
am.keeper.AssertInvariants(ctx)
|
am.keeper.AssertInvariants(ctx)
|
||||||
return []abci.ValidatorUpdate{}
|
return []abci.ValidatorUpdate{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// module export genesis
|
// ExportGenesis returns the exported genesis state as raw bytes for the crisis
|
||||||
|
// module.
|
||||||
func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||||
gs := ExportGenesis(ctx, am.keeper)
|
gs := ExportGenesis(ctx, *am.keeper)
|
||||||
return types.ModuleCdc.MustMarshalJSON(gs)
|
return types.ModuleCdc.MustMarshalJSON(gs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// module begin-block
|
// BeginBlock returns the begin blocker for the crisis module.
|
||||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||||
|
|
||||||
// module end-block
|
// EndBlock returns the end blocker for the crisis module. It returns no validator
|
||||||
|
// updates.
|
||||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||||
EndBlocker(ctx, am.keeper)
|
EndBlocker(ctx, *am.keeper)
|
||||||
return []abci.ValidatorUpdate{}
|
return []abci.ValidatorUpdate{}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue