diff --git a/x/upgrade/keeper.go b/x/upgrade/keeper.go index 2de0140fd4ee..50d2ee1bdb6a 100644 --- a/x/upgrade/keeper.go +++ b/x/upgrade/keeper.go @@ -1,16 +1,11 @@ package upgrade import ( - "encoding/json" "fmt" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/viper" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/cli" - "os" - "os/exec" - "path/filepath" ) // Keeper of the upgrade module @@ -30,17 +25,6 @@ type Keeper interface { // upgrade or false if there is none GetUpgradePlan(ctx sdk.Context) (plan Plan, havePlan bool) - // SetWillUpgrader sets a custom function to be run whenever an upgrade is scheduled. This - // can be used to notify the node that an upgrade will be happen in the future so that it - // can download any software ahead of time in the background. - // It does not indicate that an upgrade is happening now and should just be used for preparation, - // not the actual upgrade. - SetWillUpgrader(willUpgrader func(ctx sdk.Context, plan Plan)) - - // SetOnUpgrader sets a custom function to be called right before the chain halts and the - // upgrade needs to be applied. This can be used to initiate an automatic upgrade process. - SetOnUpgrader(onUpgrader func(ctx sdk.Context, plan Plan)) - // BeginBlocker should be called inside the BeginBlocker method of any app using the upgrade module. Scheduled upgrade // plans are cached in memory so the overhead of this method is trivial. BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) @@ -53,8 +37,6 @@ type keeper struct { haveCache bool //haveCachedPlan bool //plan Plan - willUpgrader func(ctx sdk.Context, plan Plan) - onUpgrader func(ctx sdk.Context, plan Plan) } const ( @@ -75,14 +57,6 @@ func (keeper *keeper) SetUpgradeHandler(name string, upgradeHandler Handler) { keeper.upgradeHandlers[name] = upgradeHandler } -func (keeper *keeper) SetWillUpgrader(willUpgrader func(ctx sdk.Context, plan Plan)) { - keeper.willUpgrader = willUpgrader -} - -func (keeper *keeper) SetOnUpgrader(onUpgrader func(ctx sdk.Context, plan Plan)) { - keeper.onUpgrader = onUpgrader -} - func (keeper *keeper) ScheduleUpgrade(ctx sdk.Context, plan Plan) sdk.Error { err := plan.ValidateBasic() if err != nil { @@ -166,75 +140,9 @@ func (keeper *keeper) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) } else { // We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown ctx.Logger().Error(fmt.Sprintf("UPGRADE \"%s\" NEEDED at height %d: %s", plan.Name, blockHeight, plan.Info)) - if keeper.onUpgrader != nil { - keeper.onUpgrader(ctx, plan) - } else { - DefaultOnUpgrader(ctx, plan) - } panic("UPGRADE REQUIRED!") } } - // TODO will upgraded is disabled for now because of inconsistent behavior - //else if justRetrievedFromCache { - // // In this case we are notifying the system that an upgrade is planned but not scheduled to happen yet - // if keeper.willUpgrader != nil { - // keeper.willUpgrader(ctx, keeper.plan) - // } else { - // DefaultWillUpgrader(ctx, keeper.plan) - // } - //} -} - - -// DefaultWillUpgrader asynchronously runs a script called prepare-upgrade from $COSMOS_HOME/config if such a script exists, -// with plan serialized to JSON as the first argument and the current block height as the second argument. -// The environment variable $COSMOS_HOME will be set to the home directory of the daemon. -func DefaultWillUpgrader(ctx sdk.Context, plan Plan) { - CallUpgradeScript(ctx, plan, "prepare-upgrade", true) -} - -// DefaultOnUpgrader synchronously runs a script called do-upgrade from $COSMOS_HOME/config if such a script exists, -// with plan serialized to JSON as the first argument and the current block height as the second argument. -// The environment variable $COSMOS_HOME will be set to the home directory of the daemon. -func DefaultOnUpgrader(ctx sdk.Context, plan Plan) { - CallUpgradeScript(ctx, plan, "do-upgrade", false) -} - -// CallUpgradeScript runs a script called script from $COSMOS_HOME/config if such a script exists, -// with plan serialized to JSON as the first argument and the current block height as the second argument. -// The environment variable $COSMOS_HOME will be set to the home directory of the daemon. -// If async is true, the command will be run in a separate go-routine. -func CallUpgradeScript(ctx sdk.Context, plan Plan, script string, async bool) { - f := func() { - home := viper.GetString(cli.HomeFlag) - file := filepath.Join(home, "config", script) - ctx.Logger().Info(fmt.Sprintf("Looking for upgrade script %s", file)) - if _, err := os.Stat(file); err == nil { - ctx.Logger().Info(fmt.Sprintf("Applying upgrade script %s", file)) - err = os.Setenv("COSMOS_HOME", home) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error setting env var COSMOS_HOME: %v", err)) - } - - - planJson, err := json.Marshal(plan) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error marshaling upgrade plan to JSON: %v", err)) - } - cmd := exec.Command(file, string(planJson), fmt.Sprintf("%d", ctx.BlockHeight())) - cmd.Stdout = logWriter{ctx, script, false} - cmd.Stderr = logWriter{ctx, script, false} - err = cmd.Run() - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error running script %s: %v", file, err)) - } - } - } - if async { - go f() - } else { - f() - } } type logWriter struct { diff --git a/x/upgrade/keeper_test.go b/x/upgrade/keeper_test.go index 40eafa9108d6..978de13111f8 100644 --- a/x/upgrade/keeper_test.go +++ b/x/upgrade/keeper_test.go @@ -1,6 +1,9 @@ package upgrade import ( + "testing" + "time" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -8,8 +11,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" - "testing" - "time" ) type TestSuite struct { @@ -112,41 +113,6 @@ func (s *TestSuite) TestCantApplySameUpgradeTwice() { s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) } -func (s *TestSuite) TestCustomCallbacks() { - s.T().Log("Set custom WillUpgrader and OnUpgrader") - willUpgraderCalled := false - onUpgraderCalled := false - s.keeper.SetWillUpgrader(func(ctx sdk.Context, plan Plan) { - willUpgraderCalled = true - }) - s.keeper.SetOnUpgrader(func(ctx sdk.Context, plan Plan) { - onUpgraderCalled = true - }) - - s.T().Log("Run an upgrade and verify that the custom WillUpgrader and OnUpgrader's are called") - err := s.keeper.ScheduleUpgrade(s.ctx, Plan{Name: "test", Height: s.ctx.BlockHeight() + 2}) - s.Require().Nil(err) - - header := abci.Header{Height: s.ctx.BlockHeight() + 1} - newCtx := sdk.NewContext(s.cms, header, false, log.NewNopLogger()) - req := abci.RequestBeginBlock{Header: header} - s.Require().NotPanics(func() { - s.keeper.BeginBlocker(newCtx, req) - }) - //s.Require().True(willUpgraderCalled) - s.Require().False(onUpgraderCalled) - - willUpgraderCalled = false - header = abci.Header{Height: s.ctx.BlockHeight() + 2} - newCtx = sdk.NewContext(s.cms, header, false, log.NewNopLogger()) - req = abci.RequestBeginBlock{Header: header} - s.Require().Panics(func() { - s.keeper.BeginBlocker(newCtx, req) - }) - s.Require().True(onUpgraderCalled) - s.Require().False(willUpgraderCalled) -} - func (s *TestSuite) TestNoSpuriousUpgrades() { s.T().Log("Verify that no upgrade panic is triggered in the BeginBlocker when we haven't scheduled an upgrade") req := abci.RequestBeginBlock{Header: s.ctx.BlockHeader()}