x/upgrade: remove support for time based upgrades (#8849)
* remove time based upgrades * cleanup * cleanup evidence of time based upgrades * cleanup docs referring to time based upgrades * forgot one * added line to changelog deprecated section * Update proto/cosmos/upgrade/v1beta1/upgrade.proto Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> * update changelog line to correct section * update buf config to allow reserved fields Co-authored-by: technicallyty <48813565+tytech3@users.noreply.github.com> Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> Co-authored-by: SaReN <sahithnarahari@gmail.com> Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
parent
adf5f625c1
commit
c6af0ed87e
|
@ -47,6 +47,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
* [\#8363](https://github.com/cosmos/cosmos-sdk/pull/8363) Addresses no longer have a fixed 20-byte length. From the SDK modules' point of view, any 1-255 bytes-long byte array is a valid address.
|
||||
* [\#8346](https://github.com/cosmos/cosmos-sdk/pull/8346) All CLI `tx` commands generate ServiceMsgs by default. Graceful Amino support has been added to ServiceMsgs to support signing legacy Msgs.
|
||||
* (crypto/ed25519) [\#8690] Adopt zip1215 ed2559 verification rules.
|
||||
* [\#8849](https://github.com/cosmos/cosmos-sdk/pull/8849) Upgrade module no longer supports time based upgrades.
|
||||
|
||||
|
||||
### API Breaking Changes
|
||||
|
|
2
buf.yaml
2
buf.yaml
|
@ -26,6 +26,8 @@ lint:
|
|||
breaking:
|
||||
use:
|
||||
- FILE
|
||||
except:
|
||||
- FIELD_NO_DELETE
|
||||
ignore:
|
||||
- tendermint
|
||||
- gogoproto
|
||||
|
|
|
@ -7362,7 +7362,6 @@ Plan specifies information about a planned upgrade and when it should occur.
|
|||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `name` | [string](#string) | | Sets the name for the upgrade. This name will be used by the upgraded version of the software to apply any special "on-upgrade" commands during the first BeginBlock method after the upgrade is applied. It is also used to detect whether a software version can handle a given upgrade. If no upgrade handler with this name has been set in the software, it will be assumed that the software is out-of-date when the upgrade Time or Height is reached and the software will exit. |
|
||||
| `time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | The time after which the upgrade must be performed. Leave set to its zero value to use a pre-defined Height instead. |
|
||||
| `height` | [int64](#int64) | | The height at which the upgrade must be performed. Only used if Time is not set. |
|
||||
| `info` | [string](#string) | | Any application specific upgrade info to be included on-chain such as a git commit that validators could automatically upgrade to |
|
||||
|
||||
|
|
|
@ -22,9 +22,10 @@ message Plan {
|
|||
// reached and the software will exit.
|
||||
string name = 1;
|
||||
|
||||
// The time after which the upgrade must be performed.
|
||||
// Leave set to its zero value to use a pre-defined Height instead.
|
||||
google.protobuf.Timestamp time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||
// Time based upgrades have been deprecated. Time based upgrade logic
|
||||
// has been removed from the SDK.
|
||||
reserved 2;
|
||||
reserved "time";
|
||||
|
||||
// The height at which the upgrade must be performed.
|
||||
// Only used if Time is not set.
|
||||
|
|
|
@ -106,7 +106,6 @@ func migrateContent(oldContent v036gov.Content) *codectypes.Any {
|
|||
Title: oldContent.Title,
|
||||
Plan: v040upgrade.Plan{
|
||||
Name: oldContent.Plan.Name,
|
||||
Time: oldContent.Plan.Time,
|
||||
Height: oldContent.Plan.Height,
|
||||
Info: oldContent.Plan.Info,
|
||||
},
|
||||
|
|
|
@ -175,8 +175,7 @@ func TestMigrate(t *testing.T) {
|
|||
"plan": {
|
||||
"height": "123",
|
||||
"info": "foo_upgrade_info",
|
||||
"name": "foo_upgrade_name",
|
||||
"time": "0001-01-01T00:00:00Z"
|
||||
"name": "foo_upgrade_name"
|
||||
},
|
||||
"title": "foo_software_upgrade"
|
||||
},
|
||||
|
|
|
@ -68,13 +68,6 @@ func TestRequireName(t *testing.T) {
|
|||
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
||||
}
|
||||
|
||||
func TestRequireFutureTime(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: s.ctx.BlockHeader().Time}})
|
||||
require.NotNil(t, err)
|
||||
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
||||
}
|
||||
|
||||
func TestRequireFutureBlock(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Height: s.ctx.BlockHeight()}})
|
||||
|
@ -82,22 +75,6 @@ func TestRequireFutureBlock(t *testing.T) {
|
|||
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
||||
}
|
||||
|
||||
func TestCantSetBothTimeAndHeight(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: time.Now(), Height: s.ctx.BlockHeight() + 1}})
|
||||
require.NotNil(t, err)
|
||||
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
||||
}
|
||||
|
||||
func TestDoTimeUpgrade(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
t.Log("Verify can schedule an upgrade")
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: time.Now()}})
|
||||
require.Nil(t, err)
|
||||
|
||||
VerifyDoUpgrade(t)
|
||||
}
|
||||
|
||||
func TestDoHeightUpgrade(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
t.Log("Verify can schedule an upgrade")
|
||||
|
@ -119,7 +96,7 @@ func TestCanOverwriteScheduleUpgrade(t *testing.T) {
|
|||
}
|
||||
|
||||
func VerifyDoUpgrade(t *testing.T) {
|
||||
t.Log("Verify that a panic happens at the upgrade time/height")
|
||||
t.Log("Verify that a panic happens at the upgrade height")
|
||||
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
||||
|
||||
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
||||
|
@ -137,7 +114,7 @@ func VerifyDoUpgrade(t *testing.T) {
|
|||
}
|
||||
|
||||
func VerifyDoUpgradeWithCtx(t *testing.T, newCtx sdk.Context, proposalName string) {
|
||||
t.Log("Verify that a panic happens at the upgrade time/height")
|
||||
t.Log("Verify that a panic happens at the upgrade height")
|
||||
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
||||
require.Panics(t, func() {
|
||||
s.module.BeginBlock(newCtx, req)
|
||||
|
@ -195,7 +172,7 @@ func VerifyCleared(t *testing.T, newCtx sdk.Context) {
|
|||
func TestCanClear(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
t.Log("Verify upgrade is scheduled")
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: time.Now()}})
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Height: s.ctx.BlockHeight() + 100}})
|
||||
require.Nil(t, err)
|
||||
|
||||
err = s.handler(s.ctx, &types.CancelSoftwareUpgradeProposal{Title: "cancel"})
|
||||
|
@ -206,11 +183,12 @@ func TestCanClear(t *testing.T) {
|
|||
|
||||
func TestCantApplySameUpgradeTwice(t *testing.T) {
|
||||
s := setupTest(10, map[int64]bool{})
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: time.Now()}})
|
||||
height := s.ctx.BlockHeader().Height + 1
|
||||
err := s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Height: height}})
|
||||
require.Nil(t, err)
|
||||
VerifyDoUpgrade(t)
|
||||
t.Log("Verify an executed upgrade \"test\" can't be rescheduled")
|
||||
err = s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Time: time.Now()}})
|
||||
err = s.handler(s.ctx, &types.SoftwareUpgradeProposal{Title: "prop", Plan: types.Plan{Name: "test", Height: height}})
|
||||
require.NotNil(t, err)
|
||||
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
||||
}
|
||||
|
@ -225,20 +203,15 @@ func TestNoSpuriousUpgrades(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlanStringer(t *testing.T) {
|
||||
ti, err := time.Parse(time.RFC3339, "2020-01-01T00:00:00Z")
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, `Upgrade Plan
|
||||
Name: test
|
||||
Time: 2020-01-01T00:00:00Z
|
||||
Info: .`, types.Plan{Name: "test", Time: ti}.String())
|
||||
require.Equal(t, `Upgrade Plan
|
||||
Name: test
|
||||
Height: 100
|
||||
Info: .`, types.Plan{Name: "test", Height: 100}.String())
|
||||
Info: .`, types.Plan{Name: "test", Height: 100, Info: ""}.String())
|
||||
|
||||
require.Equal(t, fmt.Sprintf(`Upgrade Plan
|
||||
Name: test
|
||||
Height: 100
|
||||
Info: .`), types.Plan{Name: "test", Height: 100}.String())
|
||||
Info: .`), types.Plan{Name: "test", Height: 100, Info: ""}.String())
|
||||
}
|
||||
|
||||
func VerifyNotDone(t *testing.T, newCtx sdk.Context, name string) {
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
@ -16,11 +13,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// TimeFormat specifies ISO UTC format for submitting the time for a new upgrade proposal
|
||||
TimeFormat = "2006-01-02T15:04:05Z"
|
||||
|
||||
FlagUpgradeHeight = "upgrade-height"
|
||||
FlagUpgradeTime = "upgrade-time"
|
||||
FlagUpgradeInfo = "upgrade-info"
|
||||
)
|
||||
|
||||
|
@ -37,11 +30,11 @@ func GetTxCmd() *cobra.Command {
|
|||
// NewCmdSubmitUpgradeProposal implements a command handler for submitting a software upgrade proposal transaction.
|
||||
func NewCmdSubmitUpgradeProposal() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "software-upgrade [name] (--upgrade-height [height] | --upgrade-time [time]) (--upgrade-info [info]) [flags]",
|
||||
Use: "software-upgrade [name] (--upgrade-height [height]) (--upgrade-info [info]) [flags]",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Short: "Submit a software upgrade proposal",
|
||||
Long: "Submit a software upgrade along with an initial deposit.\n" +
|
||||
"Please specify a unique name and height OR time for the upgrade to take effect.\n" +
|
||||
"Please specify a unique name and height for the upgrade to take effect.\n" +
|
||||
"You may include info to reference a binary download link, in a format compatible with: https://github.com/cosmos/cosmos-sdk/tree/master/cosmovisor",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
|
@ -84,8 +77,7 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command {
|
|||
cmd.Flags().String(cli.FlagTitle, "", "title of proposal")
|
||||
cmd.Flags().String(cli.FlagDescription, "", "description of proposal")
|
||||
cmd.Flags().String(cli.FlagDeposit, "", "deposit of proposal")
|
||||
cmd.Flags().Int64(FlagUpgradeHeight, 0, "The height at which the upgrade must happen (not to be used together with --upgrade-time)")
|
||||
cmd.Flags().String(FlagUpgradeTime, "", fmt.Sprintf("The time at which the upgrade must happen (ex. %s) (not to be used together with --upgrade-height)", TimeFormat))
|
||||
cmd.Flags().Int64(FlagUpgradeHeight, 0, "The height at which the upgrade must happen")
|
||||
cmd.Flags().String(FlagUpgradeInfo, "", "Optional info for the planned upgrade such as commit hash, etc.")
|
||||
|
||||
return cmd
|
||||
|
@ -168,29 +160,12 @@ func parseArgsToContent(cmd *cobra.Command, name string) (gov.Content, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
timeStr, err := cmd.Flags().GetString(FlagUpgradeTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if height != 0 && len(timeStr) != 0 {
|
||||
return nil, fmt.Errorf("only one of --upgrade-time or --upgrade-height should be specified")
|
||||
}
|
||||
|
||||
var upgradeTime time.Time
|
||||
if len(timeStr) != 0 {
|
||||
upgradeTime, err = time.Parse(TimeFormat, timeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
info, err := cmd.Flags().GetString(FlagUpgradeInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
plan := types.Plan{Name: name, Time: upgradeTime, Height: height, Info: info}
|
||||
plan := types.Plan{Name: name, Height: height, Info: info}
|
||||
content := types.NewSoftwareUpgradeProposal(title, description, plan)
|
||||
return content, nil
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package rest
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
|
||||
|
@ -32,7 +31,6 @@ type PlanRequest struct {
|
|||
Deposit sdk.Coins `json:"deposit" yaml:"deposit"`
|
||||
UpgradeName string `json:"upgrade_name" yaml:"upgrade_name"`
|
||||
UpgradeHeight int64 `json:"upgrade_height" yaml:"upgrade_height"`
|
||||
UpgradeTime string `json:"upgrade_time" yaml:"upgrade_time"`
|
||||
UpgradeInfo string `json:"upgrade_info" yaml:"upgrade_info"`
|
||||
}
|
||||
|
||||
|
@ -76,15 +74,7 @@ func newPostPlanHandler(clientCtx client.Context) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
var t time.Time
|
||||
if req.UpgradeTime != "" {
|
||||
t, err = time.Parse(time.RFC3339, req.UpgradeTime)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
plan := types.Plan{Name: req.UpgradeName, Time: t, Height: req.UpgradeHeight, Info: req.UpgradeInfo}
|
||||
plan := types.Plan{Name: req.UpgradeName, Height: req.UpgradeHeight, Info: req.UpgradeInfo}
|
||||
content := types.NewSoftwareUpgradeProposal(req.Title, req.Description, plan)
|
||||
msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, fromAddr)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Package upgrade provides a Cosmos SDK module that can be used for smoothly upgrading a live Cosmos chain to a
|
||||
new software version. It accomplishes this by providing a BeginBlocker hook that prevents the blockchain state
|
||||
machine from proceeding once a pre-defined upgrade block time or height has been reached. The module does not prescribe
|
||||
machine from proceeding once a pre-defined upgrade block height has been reached. The module does not prescribe
|
||||
anything regarding how governance decides to do an upgrade, but just the mechanism for coordinating the upgrade safely.
|
||||
Without software support for upgrades, upgrading a live chain is risky because all of the validators need to pause
|
||||
their state machines at exactly the same point in the process. If this is not done correctly, there can be state
|
||||
|
@ -21,9 +21,9 @@ perform a migration, but also to identify if this is the old or new version (eg.
|
|||
a handler registered for the named upgrade).
|
||||
|
||||
Once the release candidate along with an appropriate upgrade handler is frozen,
|
||||
we can have a governance vote to approve this upgrade at some future block time
|
||||
or block height (e.g. 200000). This is known as an upgrade.Plan. The v0.38.0 code will not know of this
|
||||
handler, but will continue to run until block 200000, when the plan kicks in at BeginBlock. It will check
|
||||
we can have a governance vote to approve this upgrade at some future block height (e.g. 200000).
|
||||
This is known as an upgrade.Plan. The v0.38.0 code will not know of this handler, but will
|
||||
continue to run until block 200000, when the plan kicks in at BeginBlock. It will check
|
||||
for existence of the handler, and finding it missing, know that it is running the obsolete software,
|
||||
and gracefully exit.
|
||||
|
||||
|
@ -54,7 +54,7 @@ should call ScheduleUpgrade to schedule an upgrade and ClearUpgradePlan to cance
|
|||
|
||||
Performing Upgrades
|
||||
|
||||
Upgrades can be scheduled at either a predefined block height or time. Once this block height or time is reached, the
|
||||
Upgrades can be scheduled at a predefined block height. Once this block height is reached, the
|
||||
existing software will cease to process ABCI messages and a new version with code that handles the upgrade must be deployed.
|
||||
All upgrades are coordinated by a unique upgrade name that cannot be reused on the same blockchain. In order for the upgrade
|
||||
module to know that the upgrade has been safely applied, a handler with the name of the upgrade must be installed.
|
||||
|
|
|
@ -58,11 +58,7 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if plan.Time.Unix() > 0 {
|
||||
if !plan.Time.After(ctx.BlockHeader().Time) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade cannot be scheduled in the past")
|
||||
}
|
||||
} else if plan.Height <= ctx.BlockHeight() {
|
||||
if plan.Height <= ctx.BlockHeight() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade cannot be scheduled in the past")
|
||||
}
|
||||
|
||||
|
|
|
@ -63,16 +63,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() {
|
|||
setup func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
name: "successful time schedule",
|
||||
plan: types.Plan{
|
||||
Name: "all-good",
|
||||
Info: "some text here",
|
||||
Time: s.ctx.BlockTime().Add(time.Hour),
|
||||
},
|
||||
setup: func() {},
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
name: "successful height schedule",
|
||||
plan: types.Plan{
|
||||
|
@ -107,16 +97,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() {
|
|||
setup: func() {},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "unsuccessful time schedule: due date in past",
|
||||
plan: types.Plan{
|
||||
Name: "all-good",
|
||||
Info: "some text here",
|
||||
Time: s.ctx.BlockTime(),
|
||||
},
|
||||
setup: func() {},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "unsuccessful height schedule: due date in past",
|
||||
plan: types.Plan{
|
||||
|
|
|
@ -7,7 +7,7 @@ order: 1
|
|||
## Plan
|
||||
|
||||
The `x/upgrade` module defines a `Plan` type in which a live upgrade is scheduled
|
||||
to occur. A `Plan` can be scheduled at a specific block height or time, but not both.
|
||||
to occur. A `Plan` can be scheduled at a specific block height.
|
||||
A `Plan` is created once a (frozen) release candidate along with an appropriate upgrade
|
||||
`Handler` (see below) is agreed upon, where the `Name` of a `Plan` corresponds to a
|
||||
specific `Handler`. Typically, a `Plan` is created through a governance proposal
|
||||
|
@ -30,7 +30,6 @@ for more info.
|
|||
```go
|
||||
type Plan struct {
|
||||
Name string
|
||||
Time Time
|
||||
Height int64
|
||||
Info string
|
||||
}
|
||||
|
@ -52,7 +51,7 @@ type UpgradeHandler func(Context, Plan)
|
|||
```
|
||||
|
||||
During each `EndBlock` execution, the `x/upgrade` module checks if there exists a
|
||||
`Plan` that should execute (is scheduled at that time or height). If so, the corresponding
|
||||
`Plan` that should execute (is scheduled at that height). If so, the corresponding
|
||||
`Handler` is executed. If the `Plan` is expected to execute but no `Handler` is registered
|
||||
or if the binary was upgraded too early, the node will gracefully panic and exit.
|
||||
|
||||
|
@ -88,7 +87,7 @@ will ensure these `StoreUpgrades` takes place only in planned upgrade handler.
|
|||
Typically, a `Plan` is proposed and submitted through governance via a `SoftwareUpgradeProposal`.
|
||||
This proposal prescribes to the standard governance process. If the proposal passes,
|
||||
the `Plan`, which targets a specific `Handler`, is persisted and scheduled. The
|
||||
upgrade can be delayed or hastened by updating the `Plan.Time` in a new proposal.
|
||||
upgrade can be delayed or hastened by updating the `Plan.Height` in a new proposal.
|
||||
|
||||
```go
|
||||
type SoftwareUpgradeProposal struct {
|
||||
|
|
|
@ -12,7 +12,7 @@ parent:
|
|||
`x/upgrade` is an implementation of a Cosmos SDK module that facilitates smoothly
|
||||
upgrading a live Cosmos chain to a new (breaking) software version. It accomplishes this by
|
||||
providing a `BeginBlocker` hook that prevents the blockchain state machine from
|
||||
proceeding once a pre-defined upgrade block time or height has been reached.
|
||||
proceeding once a pre-defined upgrade block height has been reached.
|
||||
|
||||
The module does not prescribe anything regarding how governance decides to do an
|
||||
upgrade, but just the mechanism for coordinating the upgrade safely. Without software
|
||||
|
|
|
@ -2,8 +2,6 @@ package types
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
|
@ -11,11 +9,10 @@ import (
|
|||
|
||||
func (p Plan) String() string {
|
||||
due := p.DueAt()
|
||||
dueUp := strings.ToUpper(due[0:1]) + due[1:]
|
||||
return fmt.Sprintf(`Upgrade Plan
|
||||
Name: %s
|
||||
%s
|
||||
Info: %s.`, p.Name, dueUp, p.Info)
|
||||
Info: %s.`, p.Name, due, p.Info)
|
||||
}
|
||||
|
||||
// ValidateBasic does basic validation of a Plan
|
||||
|
@ -23,14 +20,8 @@ func (p Plan) ValidateBasic() error {
|
|||
if len(p.Name) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "name cannot be empty")
|
||||
}
|
||||
if p.Height < 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "height cannot be negative")
|
||||
}
|
||||
if p.Time.Unix() <= 0 && p.Height == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "must set either time or height")
|
||||
}
|
||||
if p.Time.Unix() > 0 && p.Height != 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "cannot set both time and height")
|
||||
if p.Height <= 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "height must be greater than 0")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -38,9 +29,6 @@ func (p Plan) ValidateBasic() error {
|
|||
|
||||
// ShouldExecute returns true if the Plan is ready to execute given the current context
|
||||
func (p Plan) ShouldExecute(ctx sdk.Context) bool {
|
||||
if p.Time.Unix() > 0 {
|
||||
return !ctx.BlockTime().Before(p.Time)
|
||||
}
|
||||
if p.Height > 0 {
|
||||
return p.Height <= ctx.BlockHeight()
|
||||
}
|
||||
|
@ -49,8 +37,5 @@ func (p Plan) ShouldExecute(ctx sdk.Context) bool {
|
|||
|
||||
// DueAt is a string representation of when this plan is due to be executed
|
||||
func (p Plan) DueAt() string {
|
||||
if p.Time.Unix() > 0 {
|
||||
return fmt.Sprintf("time: %s", p.Time.UTC().Format(time.RFC3339))
|
||||
}
|
||||
return fmt.Sprintf("height: %d", p.Height)
|
||||
return fmt.Sprintf("Height: %d", p.Height)
|
||||
}
|
||||
|
|
|
@ -27,14 +27,6 @@ func TestPlanString(t *testing.T) {
|
|||
p types.Plan
|
||||
expect string
|
||||
}{
|
||||
"with time": {
|
||||
p: types.Plan{
|
||||
Name: "due_time",
|
||||
Info: "https://foo.bar",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
},
|
||||
expect: "Upgrade Plan\n Name: due_time\n Time: 2019-07-08T11:33:55Z\n Info: https://foo.bar.",
|
||||
},
|
||||
"with height": {
|
||||
p: types.Plan{
|
||||
Name: "by height",
|
||||
|
@ -65,14 +57,6 @@ func TestPlanValid(t *testing.T) {
|
|||
p types.Plan
|
||||
valid bool
|
||||
}{
|
||||
"proper": {
|
||||
p: types.Plan{
|
||||
Name: "all-good",
|
||||
Info: "some text here",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
},
|
||||
valid: true,
|
||||
},
|
||||
"proper by height": {
|
||||
p: types.Plan{
|
||||
Name: "all-good",
|
||||
|
@ -120,34 +104,7 @@ func TestShouldExecute(t *testing.T) {
|
|||
ctxHeight int64
|
||||
expected bool
|
||||
}{
|
||||
"past time": {
|
||||
p: types.Plan{
|
||||
Name: "do-good",
|
||||
Info: "some text here",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
},
|
||||
ctxTime: mustParseTime("2019-07-08T11:32:00Z"),
|
||||
ctxHeight: 100000,
|
||||
expected: false,
|
||||
},
|
||||
"on time": {
|
||||
p: types.Plan{
|
||||
Name: "do-good",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
},
|
||||
ctxTime: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
ctxHeight: 100000,
|
||||
expected: true,
|
||||
},
|
||||
"future time": {
|
||||
p: types.Plan{
|
||||
Name: "do-good",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
},
|
||||
ctxTime: mustParseTime("2019-07-08T11:33:57Z"),
|
||||
ctxHeight: 100000,
|
||||
expected: true,
|
||||
},
|
||||
|
||||
"past height": {
|
||||
p: types.Plan{
|
||||
Name: "do-good",
|
||||
|
|
|
@ -26,9 +26,9 @@ func TestContentAccessors(t *testing.T) {
|
|||
}{
|
||||
"upgrade": {
|
||||
p: types.NewSoftwareUpgradeProposal("Title", "desc", types.Plan{
|
||||
Name: "due_time",
|
||||
Info: "https://foo.bar",
|
||||
Time: mustParseTime("2019-07-08T11:33:55Z"),
|
||||
Name: "due_height",
|
||||
Info: "https://foo.bar",
|
||||
Height: 99999999999,
|
||||
}),
|
||||
title: "Title",
|
||||
desc: "desc",
|
||||
|
|
|
@ -8,19 +8,16 @@ import (
|
|||
_ "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
|
||||
_ "google.golang.org/protobuf/types/known/timestamppb"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
var _ = time.Kitchen
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
|
@ -38,9 +35,6 @@ type Plan struct {
|
|||
// assumed that the software is out-of-date when the upgrade Time or Height is
|
||||
// reached and the software will exit.
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// The time after which the upgrade must be performed.
|
||||
// Leave set to its zero value to use a pre-defined Height instead.
|
||||
Time time.Time `protobuf:"bytes,2,opt,name=time,proto3,stdtime" json:"time"`
|
||||
// The height at which the upgrade must be performed.
|
||||
// Only used if Time is not set.
|
||||
Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
|
||||
|
@ -171,32 +165,30 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_ccf2a7d4d7b48dca = []byte{
|
||||
// 391 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x52, 0xb1, 0x6e, 0xdb, 0x30,
|
||||
0x10, 0x15, 0x6b, 0x5a, 0xb0, 0xe9, 0xa5, 0x20, 0x0c, 0x57, 0x35, 0x5a, 0x4a, 0x30, 0x3a, 0x78,
|
||||
0x68, 0x29, 0xd8, 0x05, 0x8a, 0xa2, 0xa3, 0xbb, 0x75, 0x28, 0x0c, 0xb5, 0x5d, 0x0a, 0x64, 0xa0,
|
||||
0x64, 0x5a, 0x16, 0x22, 0x89, 0x82, 0x44, 0x27, 0xf1, 0x57, 0xc4, 0x43, 0x3e, 0x20, 0x9f, 0xe3,
|
||||
0xd1, 0xa3, 0xa7, 0x24, 0xb6, 0x97, 0x7c, 0x46, 0x20, 0x52, 0x0a, 0x82, 0x20, 0x63, 0x26, 0xbd,
|
||||
0x3b, 0xbc, 0x7b, 0xf7, 0xf4, 0x78, 0xe8, 0x53, 0x20, 0x8a, 0x44, 0x14, 0xee, 0x32, 0x0b, 0x73,
|
||||
0x36, 0xe3, 0xee, 0xd9, 0xc8, 0xe7, 0x92, 0x8d, 0xea, 0x9a, 0x66, 0xb9, 0x90, 0x02, 0xf7, 0x34,
|
||||
0x8b, 0xd6, 0xdd, 0x8a, 0xd5, 0x7f, 0x1f, 0x0a, 0x11, 0xc6, 0xdc, 0x55, 0x2c, 0x7f, 0x39, 0x77,
|
||||
0x59, 0xba, 0xd2, 0x23, 0xfd, 0x6e, 0x28, 0x42, 0xa1, 0xa0, 0x5b, 0xa2, 0xaa, 0x6b, 0x3f, 0x1f,
|
||||
0x90, 0x51, 0xc2, 0x0b, 0xc9, 0x92, 0x4c, 0x13, 0x06, 0x57, 0x00, 0xc1, 0x69, 0xcc, 0x52, 0x8c,
|
||||
0x11, 0x4c, 0x59, 0xc2, 0x2d, 0xe0, 0x80, 0x61, 0xdb, 0x53, 0x18, 0x7f, 0x47, 0xb0, 0xe4, 0x5b,
|
||||
0x6f, 0x1c, 0x30, 0xec, 0x8c, 0xfb, 0x54, 0x8b, 0xd1, 0x5a, 0x8c, 0xfe, 0xad, 0xc5, 0x26, 0xad,
|
||||
0xcd, 0x8d, 0x6d, 0xac, 0x6f, 0x6d, 0xe0, 0xa9, 0x09, 0xdc, 0x43, 0xe6, 0x82, 0x47, 0xe1, 0x42,
|
||||
0x5a, 0x0d, 0x07, 0x0c, 0x1b, 0x5e, 0x55, 0x95, 0x5b, 0xa2, 0x74, 0x2e, 0x2c, 0xa8, 0xb7, 0x94,
|
||||
0xf8, 0x07, 0xbc, 0xbf, 0xb6, 0xc1, 0x2f, 0xd8, 0x6a, 0xbe, 0x35, 0x3d, 0x53, 0x64, 0x32, 0x12,
|
||||
0xe9, 0xe0, 0x12, 0xa0, 0x77, 0x7f, 0xc4, 0x5c, 0x9e, 0xb3, 0x9c, 0xff, 0xd3, 0x21, 0x4c, 0x73,
|
||||
0x91, 0x89, 0x82, 0xc5, 0xb8, 0x8b, 0x9a, 0x32, 0x92, 0x71, 0x6d, 0x55, 0x17, 0xd8, 0x41, 0x9d,
|
||||
0x19, 0x2f, 0x82, 0x3c, 0x52, 0x02, 0xca, 0x72, 0xdb, 0x7b, 0xda, 0xc2, 0xdf, 0x10, 0xcc, 0x62,
|
||||
0x96, 0x2a, 0x47, 0x9d, 0xf1, 0x07, 0xfa, 0x72, 0xc6, 0xb4, 0x4c, 0x63, 0x02, 0xcb, 0xff, 0xf1,
|
||||
0x14, 0x5f, 0xfb, 0x1b, 0x9c, 0xa0, 0x8f, 0x3f, 0x59, 0x1a, 0xf0, 0xf8, 0x95, 0x6d, 0x69, 0xf9,
|
||||
0xc9, 0xef, 0xcd, 0x9e, 0x18, 0xbb, 0x3d, 0x31, 0x36, 0x07, 0x02, 0xb6, 0x07, 0x02, 0xee, 0x0e,
|
||||
0x04, 0xac, 0x8f, 0xc4, 0xd8, 0x1e, 0x89, 0xb1, 0x3b, 0x12, 0xe3, 0xff, 0xe7, 0x30, 0x92, 0x8b,
|
||||
0xa5, 0x4f, 0x03, 0x91, 0xb8, 0xd5, 0x11, 0xe9, 0xcf, 0x97, 0x62, 0x76, 0xea, 0x5e, 0x3c, 0x5e,
|
||||
0x94, 0x5c, 0x65, 0xbc, 0xf0, 0x4d, 0xf5, 0x48, 0x5f, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9b,
|
||||
0x57, 0x9e, 0x92, 0x70, 0x02, 0x00, 0x00,
|
||||
// 364 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0xcd, 0x4e, 0xea, 0x40,
|
||||
0x14, 0xc7, 0x3b, 0x30, 0x34, 0xdc, 0x61, 0x43, 0x1a, 0xc2, 0xed, 0x25, 0xd7, 0x81, 0x10, 0x17,
|
||||
0x2c, 0xb4, 0x0d, 0x9a, 0xb8, 0x70, 0x89, 0x3b, 0x16, 0x86, 0xd4, 0xb8, 0x31, 0x71, 0x31, 0x2d,
|
||||
0xd3, 0xd2, 0xd8, 0xf6, 0x34, 0xed, 0xa0, 0xf2, 0x14, 0xfa, 0x08, 0x3e, 0x0e, 0x4b, 0x96, 0xac,
|
||||
0x8c, 0xc0, 0xc6, 0xc7, 0x30, 0x9d, 0x29, 0xc6, 0x18, 0x97, 0xae, 0xe6, 0x7f, 0xce, 0xfc, 0xce,
|
||||
0xd7, 0xcc, 0x21, 0x87, 0x1e, 0xe4, 0x31, 0xe4, 0xf6, 0x3c, 0x0d, 0x32, 0x36, 0xe5, 0xf6, 0xfd,
|
||||
0xd0, 0xe5, 0x82, 0x0d, 0xf7, 0xb6, 0x95, 0x66, 0x20, 0xc0, 0x68, 0x2b, 0xca, 0xda, 0x7b, 0x4b,
|
||||
0xaa, 0xf3, 0x2f, 0x00, 0x08, 0x22, 0x6e, 0x4b, 0xca, 0x9d, 0xfb, 0x36, 0x4b, 0x16, 0x2a, 0xa4,
|
||||
0xd3, 0x0a, 0x20, 0x00, 0x29, 0xed, 0x42, 0x95, 0xde, 0xee, 0xf7, 0x00, 0x11, 0xc6, 0x3c, 0x17,
|
||||
0x2c, 0x4e, 0x15, 0xd0, 0xf7, 0x09, 0x9e, 0x44, 0x2c, 0x31, 0x0c, 0x82, 0x13, 0x16, 0x73, 0x13,
|
||||
0xf5, 0xd0, 0xe0, 0x8f, 0x23, 0xb5, 0xd1, 0x26, 0xfa, 0x8c, 0x87, 0xc1, 0x4c, 0x98, 0xd5, 0x1e,
|
||||
0x1a, 0x54, 0x9d, 0xd2, 0x2a, 0xd8, 0x30, 0xf1, 0xc1, 0xc4, 0x8a, 0x2d, 0xf4, 0x39, 0x7e, 0x7f,
|
||||
0xe9, 0xa2, 0x31, 0xae, 0x57, 0x9a, 0xd5, 0x31, 0xae, 0xd7, 0x9a, 0xba, 0x83, 0x8b, 0x52, 0x8e,
|
||||
0x0e, 0xa9, 0x08, 0x21, 0xe9, 0x3f, 0x21, 0xf2, 0xf7, 0x0a, 0x7c, 0xf1, 0xc0, 0x32, 0x7e, 0xad,
|
||||
0xa6, 0x9a, 0x64, 0x90, 0x42, 0xce, 0x22, 0xa3, 0x45, 0x6a, 0x22, 0x14, 0xd1, 0xbe, 0xb8, 0x32,
|
||||
0x8c, 0x1e, 0x69, 0x4c, 0x79, 0xee, 0x65, 0xa1, 0x4c, 0x60, 0x56, 0xe4, 0xdd, 0x57, 0x97, 0x71,
|
||||
0x46, 0x70, 0x1a, 0xb1, 0x44, 0x76, 0xd7, 0x38, 0xf9, 0x6f, 0xfd, 0xfc, 0x68, 0x56, 0x31, 0xdf,
|
||||
0x08, 0x2f, 0x5f, 0xbb, 0x9a, 0x23, 0x79, 0xd5, 0x6b, 0xff, 0x96, 0x1c, 0x5c, 0xb0, 0xc4, 0xe3,
|
||||
0xd1, 0x2f, 0xb7, 0xa5, 0xd2, 0x8f, 0x2e, 0x97, 0x1b, 0xaa, 0xad, 0x37, 0x54, 0x5b, 0x6e, 0x29,
|
||||
0x5a, 0x6d, 0x29, 0x7a, 0xdb, 0x52, 0xf4, 0xbc, 0xa3, 0xda, 0x6a, 0x47, 0xb5, 0xf5, 0x8e, 0x6a,
|
||||
0x37, 0x47, 0x41, 0x28, 0x66, 0x73, 0xd7, 0xf2, 0x20, 0xb6, 0xcb, 0xad, 0x50, 0xc7, 0x71, 0x3e,
|
||||
0xbd, 0xb3, 0x1f, 0x3f, 0x57, 0x44, 0x2c, 0x52, 0x9e, 0xbb, 0xba, 0xfc, 0xaf, 0xd3, 0x8f, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xb1, 0x05, 0xd5, 0x12, 0x41, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (this *Plan) Equal(that interface{}) bool {
|
||||
|
@ -221,9 +213,6 @@ func (this *Plan) Equal(that interface{}) bool {
|
|||
if this.Name != that1.Name {
|
||||
return false
|
||||
}
|
||||
if !this.Time.Equal(that1.Time) {
|
||||
return false
|
||||
}
|
||||
if this.Height != that1.Height {
|
||||
return false
|
||||
}
|
||||
|
@ -321,14 +310,6 @@ func (m *Plan) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i--
|
||||
dAtA[i] = 0x18
|
||||
}
|
||||
n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
i -= n1
|
||||
i = encodeVarintUpgrade(dAtA, i, uint64(n1))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
if len(m.Name) > 0 {
|
||||
i -= len(m.Name)
|
||||
copy(dAtA[i:], m.Name)
|
||||
|
@ -444,8 +425,6 @@ func (m *Plan) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovUpgrade(uint64(l))
|
||||
}
|
||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time)
|
||||
n += 1 + l + sovUpgrade(uint64(l))
|
||||
if m.Height != 0 {
|
||||
n += 1 + sovUpgrade(uint64(m.Height))
|
||||
}
|
||||
|
@ -559,39 +538,6 @@ func (m *Plan) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
m.Name = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUpgrade
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthUpgrade
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthUpgrade
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
|
||||
|
|
Loading…
Reference in New Issue