Add upgrade module to simapp (#5328)
* upgrade: add x/upgrade to simapp * upgrade: clean up tests
This commit is contained in:
parent
c16c32aefa
commit
43f011865d
|
@ -29,18 +29,20 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
"github.com/cosmos/cosmos-sdk/x/upgrade"
|
||||
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
|
||||
)
|
||||
|
||||
const appName = "SimApp"
|
||||
|
||||
var (
|
||||
// default home directories for the application CLI
|
||||
// DefaultCLIHome default home directories for the application CLI
|
||||
DefaultCLIHome = os.ExpandEnv("$HOME/.simapp")
|
||||
|
||||
// default home directories for the application daemon
|
||||
// DefaultNodeHome default home directories for the application daemon
|
||||
DefaultNodeHome = os.ExpandEnv("$HOME/.simapp")
|
||||
|
||||
// The module BasicManager is in charge of setting up basic,
|
||||
// ModuleBasics defines the module BasicManager is in charge of setting up basic,
|
||||
// non-dependant module elements, such as codec registration
|
||||
// and genesis verification.
|
||||
ModuleBasics = module.NewBasicManager(
|
||||
|
@ -51,10 +53,13 @@ var (
|
|||
staking.AppModuleBasic{},
|
||||
mint.AppModuleBasic{},
|
||||
distr.AppModuleBasic{},
|
||||
gov.NewAppModuleBasic(paramsclient.ProposalHandler, distr.ProposalHandler),
|
||||
gov.NewAppModuleBasic(
|
||||
paramsclient.ProposalHandler, distr.ProposalHandler, upgradeclient.ProposalHandler,
|
||||
),
|
||||
params.AppModuleBasic{},
|
||||
crisis.AppModuleBasic{},
|
||||
slashing.AppModuleBasic{},
|
||||
upgrade.AppModuleBasic{},
|
||||
evidence.AppModuleBasic{},
|
||||
)
|
||||
|
||||
|
@ -69,7 +74,7 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// custom tx codec
|
||||
// MakeCodec - custom tx codec
|
||||
func MakeCodec() *codec.Codec {
|
||||
var cdc = codec.New()
|
||||
ModuleBasics.RegisterCodec(cdc)
|
||||
|
@ -105,6 +110,7 @@ type SimApp struct {
|
|||
DistrKeeper distr.Keeper
|
||||
GovKeeper gov.Keeper
|
||||
CrisisKeeper crisis.Keeper
|
||||
UpgradeKeeper upgrade.Keeper
|
||||
ParamsKeeper params.Keeper
|
||||
EvidenceKeeper evidence.Keeper
|
||||
|
||||
|
@ -128,8 +134,9 @@ func NewSimApp(
|
|||
bApp.SetAppVersion(version.Version)
|
||||
|
||||
keys := sdk.NewKVStoreKeys(
|
||||
bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey,
|
||||
distr.StoreKey, slashing.StoreKey, gov.StoreKey, params.StoreKey, evidence.StoreKey,
|
||||
bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
|
||||
supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
|
||||
gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey,
|
||||
)
|
||||
tkeys := sdk.NewTransientStoreKeys(params.TStoreKey)
|
||||
|
||||
|
@ -182,6 +189,7 @@ func NewSimApp(
|
|||
app.CrisisKeeper = crisis.NewKeeper(
|
||||
app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName,
|
||||
)
|
||||
app.UpgradeKeeper = upgrade.NewKeeper(keys[upgrade.StoreKey], app.cdc)
|
||||
|
||||
// create evidence keeper with router
|
||||
evidenceKeeper := evidence.NewKeeper(
|
||||
|
@ -196,7 +204,8 @@ func NewSimApp(
|
|||
govRouter := gov.NewRouter()
|
||||
govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler).
|
||||
AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
|
||||
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper))
|
||||
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
|
||||
AddRoute(upgrade.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
|
||||
app.GovKeeper = gov.NewKeeper(
|
||||
app.cdc, keys[gov.StoreKey], app.subspaces[gov.ModuleName], app.SupplyKeeper,
|
||||
&stakingKeeper, gov.DefaultCodespace, govRouter,
|
||||
|
@ -221,13 +230,14 @@ func NewSimApp(
|
|||
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
|
||||
slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper),
|
||||
staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
|
||||
upgrade.NewAppModule(app.UpgradeKeeper),
|
||||
evidence.NewAppModule(app.EvidenceKeeper),
|
||||
)
|
||||
|
||||
// During begin block slashing happens after distr.BeginBlocker so that
|
||||
// there is nothing left over in the validator fee pool, so as to keep the
|
||||
// CanWithdrawInvariant invariant.
|
||||
app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName)
|
||||
app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName)
|
||||
app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName)
|
||||
|
||||
// NOTE: The genutils moodule must occur after staking so that pools are
|
||||
|
@ -278,24 +288,24 @@ func NewSimApp(
|
|||
return app
|
||||
}
|
||||
|
||||
// application updates every begin block
|
||||
// BeginBlocker application updates every begin block
|
||||
func (app *SimApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
|
||||
return app.mm.BeginBlock(ctx, req)
|
||||
}
|
||||
|
||||
// application updates every end block
|
||||
// EndBlocker application updates every end block
|
||||
func (app *SimApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
return app.mm.EndBlock(ctx, req)
|
||||
}
|
||||
|
||||
// application update at chain initialization
|
||||
// InitChainer application update at chain initialization
|
||||
func (app *SimApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
var genesisState GenesisState
|
||||
app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
|
||||
return app.mm.InitGenesis(ctx, genesisState)
|
||||
}
|
||||
|
||||
// load a particular height
|
||||
// LoadHeight loads a particular height
|
||||
func (app *SimApp) LoadHeight(height int64) error {
|
||||
return app.LoadVersion(height, app.keys[bam.MainStoreKey])
|
||||
}
|
||||
|
|
|
@ -1,72 +1,66 @@
|
|||
package upgrade
|
||||
package upgrade_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/upgrade"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
)
|
||||
|
||||
type TestSuite struct {
|
||||
suite.Suite
|
||||
keeper Keeper
|
||||
|
||||
module module.AppModule
|
||||
keeper upgrade.Keeper
|
||||
querier sdk.Querier
|
||||
handler gov.Handler
|
||||
module module.AppModule
|
||||
ctx sdk.Context
|
||||
cms store.CommitMultiStore
|
||||
}
|
||||
|
||||
func (s *TestSuite) SetupTest() {
|
||||
db := dbm.NewMemDB()
|
||||
s.cms = store.NewCommitMultiStore(db)
|
||||
key := sdk.NewKVStoreKey("upgrade")
|
||||
cdc := codec.New()
|
||||
RegisterCodec(cdc)
|
||||
s.keeper = NewKeeper(key, cdc)
|
||||
s.handler = NewSoftwareUpgradeProposalHandler(s.keeper)
|
||||
s.querier = NewQuerier(s.keeper)
|
||||
s.module = NewAppModule(s.keeper)
|
||||
s.cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
|
||||
_ = s.cms.LoadLatestVersion()
|
||||
s.ctx = sdk.NewContext(s.cms, abci.Header{Height: 10, Time: time.Now()}, false, log.NewNopLogger())
|
||||
checkTx := false
|
||||
app := simapp.Setup(checkTx)
|
||||
|
||||
s.keeper = app.UpgradeKeeper
|
||||
s.handler = upgrade.NewSoftwareUpgradeProposalHandler(s.keeper)
|
||||
s.querier = upgrade.NewQuerier(s.keeper)
|
||||
s.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 10, Time: time.Now()})
|
||||
s.module = upgrade.NewAppModule(s.keeper)
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestRequireName() {
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{}})
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal(sdk.CodeUnknownRequest, err.Code())
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestRequireFutureTime() {
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Time: s.ctx.BlockHeader().Time}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: s.ctx.BlockHeader().Time}})
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal(sdk.CodeUnknownRequest, err.Code())
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestRequireFutureBlock() {
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Height: s.ctx.BlockHeight()}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight()}})
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal(sdk.CodeUnknownRequest, err.Code())
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestCantSetBothTimeAndHeight() {
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Time: time.Now(), Height: s.ctx.BlockHeight() + 1}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now(), Height: s.ctx.BlockHeight() + 1}})
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal(sdk.CodeUnknownRequest, err.Code())
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestDoTimeUpgrade() {
|
||||
s.T().Log("Verify can schedule an upgrade")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Time: time.Now()}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
||||
s.Require().Nil(err)
|
||||
|
||||
s.VerifyDoUpgrade()
|
||||
|
@ -74,7 +68,7 @@ func (s *TestSuite) TestDoTimeUpgrade() {
|
|||
|
||||
func (s *TestSuite) TestDoHeightUpgrade() {
|
||||
s.T().Log("Verify can schedule an upgrade")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
||||
s.Require().Nil(err)
|
||||
|
||||
s.VerifyDoUpgrade()
|
||||
|
@ -82,9 +76,9 @@ func (s *TestSuite) TestDoHeightUpgrade() {
|
|||
|
||||
func (s *TestSuite) TestCanOverwriteScheduleUpgrade() {
|
||||
s.T().Log("Can overwrite plan")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "bad_test", Height: s.ctx.BlockHeight() + 10}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "bad_test", Height: s.ctx.BlockHeight() + 10}})
|
||||
s.Require().Nil(err)
|
||||
err = s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
||||
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
||||
s.Require().Nil(err)
|
||||
|
||||
s.VerifyDoUpgrade()
|
||||
|
@ -92,14 +86,15 @@ func (s *TestSuite) TestCanOverwriteScheduleUpgrade() {
|
|||
|
||||
func (s *TestSuite) VerifyDoUpgrade() {
|
||||
s.T().Log("Verify that a panic happens at the upgrade time/height")
|
||||
newCtx := sdk.NewContext(s.cms, abci.Header{Height: s.ctx.BlockHeight() + 1, Time: time.Now()}, false, log.NewNopLogger())
|
||||
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
||||
|
||||
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
||||
s.Require().Panics(func() {
|
||||
s.module.BeginBlock(newCtx, req)
|
||||
})
|
||||
|
||||
s.T().Log("Verify that the upgrade can be successfully applied with a handler")
|
||||
s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan Plan) {})
|
||||
s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan upgrade.Plan) {})
|
||||
s.Require().NotPanics(func() {
|
||||
s.module.BeginBlock(newCtx, req)
|
||||
})
|
||||
|
@ -110,9 +105,9 @@ func (s *TestSuite) VerifyDoUpgrade() {
|
|||
func (s *TestSuite) TestHaltIfTooNew() {
|
||||
s.T().Log("Verify that we don't panic with registered plan not in database at all")
|
||||
var called int
|
||||
s.keeper.SetUpgradeHandler("future", func(ctx sdk.Context, plan Plan) { called++ })
|
||||
s.keeper.SetUpgradeHandler("future", func(ctx sdk.Context, plan upgrade.Plan) { called++ })
|
||||
|
||||
newCtx := sdk.NewContext(s.cms, abci.Header{Height: s.ctx.BlockHeight() + 1, Time: time.Now()}, false, log.NewNopLogger())
|
||||
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
||||
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
||||
s.Require().NotPanics(func() {
|
||||
s.module.BeginBlock(newCtx, req)
|
||||
|
@ -120,7 +115,7 @@ func (s *TestSuite) TestHaltIfTooNew() {
|
|||
s.Require().Equal(0, called)
|
||||
|
||||
s.T().Log("Verify we panic if we have a registered handler ahead of time")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "future", Height: s.ctx.BlockHeight() + 3}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "future", Height: s.ctx.BlockHeight() + 3}})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Panics(func() {
|
||||
s.module.BeginBlock(newCtx, req)
|
||||
|
@ -129,7 +124,7 @@ func (s *TestSuite) TestHaltIfTooNew() {
|
|||
|
||||
s.T().Log("Verify we no longer panic if the plan is on time")
|
||||
|
||||
futCtx := sdk.NewContext(s.cms, abci.Header{Height: s.ctx.BlockHeight() + 3, Time: time.Now()}, false, log.NewNopLogger())
|
||||
futCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 3).WithBlockTime(time.Now())
|
||||
req = abci.RequestBeginBlock{Header: futCtx.BlockHeader()}
|
||||
s.Require().NotPanics(func() {
|
||||
s.module.BeginBlock(futCtx, req)
|
||||
|
@ -141,17 +136,17 @@ func (s *TestSuite) TestHaltIfTooNew() {
|
|||
|
||||
func (s *TestSuite) VerifyCleared(newCtx sdk.Context) {
|
||||
s.T().Log("Verify that the upgrade plan has been cleared")
|
||||
bz, err := s.querier(newCtx, []string{QueryCurrent}, abci.RequestQuery{})
|
||||
bz, err := s.querier(newCtx, []string{upgrade.QueryCurrent}, abci.RequestQuery{})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Nil(bz)
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestCanClear() {
|
||||
s.T().Log("Verify upgrade is scheduled")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Time: time.Now()}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
||||
s.Require().Nil(err)
|
||||
|
||||
s.handler(s.ctx, CancelSoftwareUpgradeProposal{Title: "cancel"})
|
||||
s.handler(s.ctx, upgrade.CancelSoftwareUpgradeProposal{Title: "cancel"})
|
||||
|
||||
s.VerifyCleared(s.ctx)
|
||||
}
|
||||
|
@ -159,7 +154,7 @@ func (s *TestSuite) TestCanClear() {
|
|||
func (s *TestSuite) TestCantApplySameUpgradeTwice() {
|
||||
s.TestDoTimeUpgrade()
|
||||
s.T().Log("Verify an upgrade named \"test\" can't be scheduled twice")
|
||||
err := s.handler(s.ctx, SoftwareUpgradeProposal{Title: "prop", Plan: Plan{Name: "test", Time: time.Now()}})
|
||||
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal(sdk.CodeUnknownRequest, err.Code())
|
||||
}
|
||||
|
@ -178,11 +173,11 @@ func (s *TestSuite) TestPlanStringer() {
|
|||
s.Require().Equal(`Upgrade Plan
|
||||
Name: test
|
||||
Time: 2020-01-01T00:00:00Z
|
||||
Info: `, Plan{Name: "test", Time: t}.String())
|
||||
Info: `, upgrade.Plan{Name: "test", Time: t}.String())
|
||||
s.Require().Equal(`Upgrade Plan
|
||||
Name: test
|
||||
Height: 100
|
||||
Info: `, Plan{Name: "test", Height: 100}.String())
|
||||
Info: `, upgrade.Plan{Name: "test", Height: 100}.String())
|
||||
}
|
||||
|
||||
func TestTestSuite(t *testing.T) {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package exported
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/upgrade/internal/types"
|
||||
)
|
||||
|
||||
// Keeper of the upgrade module
|
||||
type Keeper interface {
|
||||
// ScheduleUpgrade schedules an upgrade based on the specified plan
|
||||
ScheduleUpgrade(ctx sdk.Context, plan types.Plan) sdk.Error
|
||||
|
||||
// SetUpgradeHandler sets an UpgradeHandler for the upgrade specified by name. This handler will be called when the upgrade
|
||||
// with this name is applied. In order for an upgrade with the given name to proceed, a handler for this upgrade
|
||||
// must be set even if it is a no-op function.
|
||||
SetUpgradeHandler(name string, upgradeHandler types.UpgradeHandler)
|
||||
|
||||
// ClearUpgradePlan clears any schedule upgrade
|
||||
ClearUpgradePlan(ctx sdk.Context)
|
||||
|
||||
// GetUpgradePlan returns the currently scheduled Plan if any, setting havePlan to true if there is a scheduled
|
||||
// upgrade or false if there is none
|
||||
GetUpgradePlan(ctx sdk.Context) (plan types.Plan, havePlan bool)
|
||||
|
||||
// HasHandler returns true iff there is a handler registered for this name
|
||||
HasHandler(name string) bool
|
||||
|
||||
// ApplyUpgrade will execute the handler associated with the Plan and mark the plan as done.
|
||||
ApplyUpgrade(ctx sdk.Context, plan types.Plan)
|
||||
}
|
Loading…
Reference in New Issue