Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
323531a
x/upgrade: Refactor CLI to use protobuf query
amaury1093 Jul 7, 2020
72d0f2d
Import lint
amaury1093 Jul 7, 2020
c45824c
Use table tests
amaury1093 Jul 7, 2020
3d60e63
Small tweak in setup
amaury1093 Jul 7, 2020
25cae9c
Address bez cli refactor
amaury1093 Jul 7, 2020
8a4e906
Merge branch 'master' into am-cli-upgrade
amaury1093 Jul 7, 2020
2ee9adb
Address fede's review
amaury1093 Jul 7, 2020
025f6d4
Remove useless func args
amaury1093 Jul 7, 2020
e8eadd6
Merge branch 'am-cli-upgrade' of ssh://github.com/cosmos/cosmos-sdk i…
amaury1093 Jul 7, 2020
3c1321d
Merge branch 'master' into am-cli-upgrade
amaury1093 Jul 7, 2020
50b9c5c
Add back clientCtx to tx command
amaury1093 Jul 7, 2020
2fd0de2
Merge branch 'am-cli-upgrade' of ssh://github.com/cosmos/cosmos-sdk i…
amaury1093 Jul 7, 2020
b8421f3
Update comments
amaury1093 Jul 7, 2020
3fb0ea6
Update docs
amaury1093 Jul 8, 2020
7ab6094
Merge branch 'master' into am-cli-upgrade
fedekunze Jul 8, 2020
9c005a8
Small refactor
amaury1093 Jul 8, 2020
225cb55
Merge branch 'am-cli-upgrade' of ssh://github.com/cosmos/cosmos-sdk i…
amaury1093 Jul 8, 2020
144a2a8
Merge branch 'master' into am-cli-upgrade
fedekunze Jul 8, 2020
1ad236a
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
1610974
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
21c369a
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
820790e
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
3ecfb9b
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
bd52bea
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
3225d18
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
293dba8
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
6767917
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
6435cef
Merge branch 'master' into am-cli-upgrade
mergify[bot] Jul 8, 2020
982c573
remove Init()
amaury1093 Jul 8, 2020
2a821ce
Merge branch 'am-cli-upgrade' of ssh://github.com/cosmos/cosmos-sdk i…
amaury1093 Jul 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions x/upgrade/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -1,98 +1,102 @@
package cli

import (
"encoding/binary"
"context"
"fmt"

"github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

// GetPlanCmd returns the query upgrade plan command
func GetPlanCmd(storeName string, cdc *codec.Codec) *cobra.Command {
// GetQueryCmd returns the parent command for all x/upgrade CLi query commands
func GetQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the upgrade module",
}
cmd.AddCommand(flags.GetCommands(
GetCurrentPlanCmd(),
GetAppliedPlanCmd(),
)...)

return cmd
}

// GetCurrentPlanCmd returns the query upgrade plan command
func GetCurrentPlanCmd() *cobra.Command {
return &cobra.Command{
Use: "plan",
Short: "get upgrade plan (if one exists)",
Long: "Gets the currently scheduled upgrade plan, if one exists",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
queryClient := types.NewQueryClient(clientCtx.Init())

// ignore height for now
res, _, err := clientCtx.Query(fmt.Sprintf("custom/%s/%s", types.QuerierKey, types.QueryCurrent))
params := types.NewQueryCurrentPlanRequest()
res, err := queryClient.CurrentPlan(context.Background(), params)
if err != nil {
return err
}

if len(res) == 0 {
if len(res.Plan.Name) == 0 {
return fmt.Errorf("no upgrade scheduled")
}

var plan types.Plan
err = cdc.UnmarshalJSON(res, &plan)
if err != nil {
return err
}
return clientCtx.PrintOutput(plan)
return clientCtx.PrintOutput(res.Plan)
},
}
}

// GetAppliedHeightCmd returns the height at which a completed upgrade was applied
func GetAppliedHeightCmd(storeName string, cdc *codec.Codec) *cobra.Command {
// GetAppliedPlanCmd returns information about the block at which a completed
// upgrade was applied
func GetAppliedPlanCmd() *cobra.Command {
return &cobra.Command{
Use: "applied [upgrade-name]",
Short: "block header for height at which a completed upgrade was applied",
Long: "If upgrade-name was previously executed on the chain, this returns the header for the block at which it was applied.\n" +
"This helps a client determine which binary was valid over a given range of blocks, as well as more context to understand past migrations.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
queryClient := types.NewQueryClient(clientCtx.Init())

name := args[0]
params := types.NewQueryAppliedPlanRequest(name)
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if err != nil {
return err
}

res, _, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierKey, types.QueryApplied), bz)
res, err := queryClient.AppliedPlan(context.Background(), params)
if err != nil {
return err
}

if len(res) == 0 {
if res.Height == 0 {
return fmt.Errorf("no upgrade found")
}
if len(res) != 8 {
return fmt.Errorf("unknown format for applied-upgrade")
}
applied := int64(binary.BigEndian.Uint64(res))

// we got the height, now let's return the headers
node, err := clientCtx.GetNode()
if err != nil {
return err
}
headers, err := node.BlockchainInfo(applied, applied)
headers, err := node.BlockchainInfo(res.Height, res.Height)
if err != nil {
return err
}
if len(headers.BlockMetas) == 0 {
return fmt.Errorf("no headers returned for height %d", applied)
return fmt.Errorf("no headers returned for height %d", res.Height)
}

// always output json as Header is unreable in toml ([]byte is a long list of numbers)
bz, err = cdc.MarshalJSONIndent(headers.BlockMetas[0], "", " ")
bz, err := clientCtx.Codec.MarshalJSONIndent(headers.BlockMetas[0], "", " ")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

didn't find BlockMetas in tm's proto files, so not using protobuf here

if err != nil {
return err
}
fmt.Println(string(bz))
return nil
return clientCtx.PrintOutput(string(bz))
},
}
}
21 changes: 15 additions & 6 deletions x/upgrade/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import (
"fmt"
"time"

"github.com/cosmos/cosmos-sdk/client/tx"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/cosmos/cosmos-sdk/x/gov/client/cli"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

Expand All @@ -25,9 +24,19 @@ const (
FlagUpgradeInfo = "info"
)

// GetTxCmd returns the transaction commands for this module
func GetTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: "Upgrade transaction subcommands",
}
cmd.AddCommand(flags.PostCommands()...)

return cmd
}

// NewCmdSubmitUpgradeProposal implements a command handler for submitting a software upgrade proposal transaction.
func NewCmdSubmitUpgradeProposal(clientCtx client.Context) *cobra.Command {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This still needs to be updated: see #6639 for reference

Copy link
Copy Markdown
Contributor Author

@amaury1093 amaury1093 Jul 8, 2020

Choose a reason for hiding this comment

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

I actually went down this path, but it requires a bigger refactor:

what I propose:

  • leave this PR scoped to x/upgrade, as initially intended
  • I'll take care of one follow-up PR to refactor all x/{distribution,params,upgrade} at once once those PRs are merged


cmd := &cobra.Command{
Use: "software-upgrade [name] (--upgrade-height [height] | --upgrade-time [time]) (--upgrade-info [info]) [flags]",
Args: cobra.ExactArgs(1),
Expand Down
149 changes: 125 additions & 24 deletions x/upgrade/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,143 @@ package keeper_test

import (
gocontext "context"
"fmt"
"testing"

"github.com/stretchr/testify/suite"

abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
)

func TestGRPCQueryUpgrade(t *testing.T) {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
type UpgradeTestSuite struct {
suite.Suite

app *simapp.SimApp
ctx sdk.Context
queryClient types.QueryClient
}

func (suite *UpgradeTestSuite) SetupTest() {
suite.app = simapp.Setup(false)
suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{})

queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.app.UpgradeKeeper)
suite.queryClient = types.NewQueryClient(queryHelper)
}

func (suite *UpgradeTestSuite) TestQueryCurrentPlan() {
var (
req *types.QueryCurrentPlanRequest
expResponse types.QueryCurrentPlanResponse
)

testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"without current upgrade plan",
func() {
req = types.NewQueryCurrentPlanRequest()
expResponse = types.QueryCurrentPlanResponse{}
},
true,
},
{
"with current upgrade plan",
func() {
plan := types.Plan{Name: "test-plan", Height: 5}
suite.app.UpgradeKeeper.ScheduleUpgrade(suite.ctx, plan)

queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, app.UpgradeKeeper)
queryClient := types.NewQueryClient(queryHelper)
req = types.NewQueryCurrentPlanRequest()
expResponse = types.QueryCurrentPlanResponse{Plan: &plan}
},
true,
},
}

t.Log("Verify that the scheduled upgrade plan can be queried")
plan := types.Plan{Name: "test-plan", Height: 5}
app.UpgradeKeeper.ScheduleUpgrade(ctx, plan)
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

res, err := queryClient.CurrentPlan(gocontext.Background(), &types.QueryCurrentPlanRequest{})
require.NoError(t, err)
require.Equal(t, res.Plan, &plan)
tc.malleate()

t.Log("Verify that the upgrade plan can be successfully applied and queried")
ctx = ctx.WithBlockHeight(5)
app.UpgradeKeeper.SetUpgradeHandler("test-plan", func(ctx sdk.Context, plan types.Plan) {})
app.UpgradeKeeper.ApplyUpgrade(ctx, plan)
res, err := suite.queryClient.CurrentPlan(gocontext.Background(), req)

res, err = queryClient.CurrentPlan(gocontext.Background(), &types.QueryCurrentPlanRequest{})
require.NoError(t, err)
require.Nil(t, res.Plan)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(&expResponse, res)
} else {
suite.Require().Error(err)
}
})
}
}

func (suite *UpgradeTestSuite) TestAppliedCurrentPlan() {
var (
req *types.QueryAppliedPlanRequest
expHeight int64
)

testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"with non-existent upgrade plan",
func() {
req = types.NewQueryAppliedPlanRequest("foo")
},
true,
},
{
"with applied upgrade plan",
func() {
expHeight = 5

planName := "test-plan"
plan := types.Plan{Name: planName, Height: expHeight}
suite.app.UpgradeKeeper.ScheduleUpgrade(suite.ctx, plan)

suite.ctx = suite.ctx.WithBlockHeight(expHeight)
suite.app.UpgradeKeeper.SetUpgradeHandler(planName, func(ctx sdk.Context, plan types.Plan) {})
suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx, plan)

req = types.NewQueryAppliedPlanRequest(planName)
},
true,
},
}

for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

tc.malleate()

res, err := suite.queryClient.AppliedPlan(gocontext.Background(), req)

if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expHeight, res.Height)
} else {
suite.Require().Error(err)
}
})
}
}

appliedRes, appliedErr := queryClient.AppliedPlan(gocontext.Background(), &types.QueryAppliedPlanRequest{Name: "test-plan"})
require.NoError(t, appliedErr)
require.Equal(t, int64(5), appliedRes.Height)
func TestUpgradeTestSuite(t *testing.T) {
suite.Run(t, new(UpgradeTestSuite))
}
21 changes: 3 additions & 18 deletions x/upgrade/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -54,27 +53,13 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, r *mux.Router
}

// GetQueryCmd returns the cli query commands for this module
func (AppModuleBasic) GetQueryCmd(clientCtx client.Context) *cobra.Command {
queryCmd := &cobra.Command{
Use: "upgrade",
Short: "Querying commands for the upgrade module",
}
queryCmd.AddCommand(flags.GetCommands(
cli.GetPlanCmd(types.StoreKey, clientCtx.Codec),
cli.GetAppliedHeightCmd(types.StoreKey, clientCtx.Codec),
)...)

return queryCmd
func (AppModuleBasic) GetQueryCmd(_ client.Context) *cobra.Command {
return cli.GetQueryCmd()
}

// GetTxCmd returns the transaction commands for this module
func (AppModuleBasic) GetTxCmd(_ client.Context) *cobra.Command {
txCmd := &cobra.Command{
Use: "upgrade",
Short: "Upgrade transaction subcommands",
}
txCmd.AddCommand(flags.PostCommands()...)
return txCmd
return cli.GetTxCmd()
}

func (b AppModuleBasic) RegisterInterfaceTypes(registry codectypes.InterfaceRegistry) {
Expand Down