Add msg on CLI for migrating GenesisDoc (#8164)

* Add msg on CLI for migrating GenesisDoc

* Fix build

* Better indentation

* Add table tests

* typo

* Rename variables

* Fix validate tests

* Add warning println

Co-authored-by: Cory <cjlevinson@gmail.com>
This commit is contained in:
Amaury 2020-12-14 23:51:23 +01:00 committed by GitHub
parent a3ae6e3704
commit cf86c567c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 40 deletions

View File

@ -73,7 +73,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome), genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
genutilcli.MigrateGenesisCmd(), genutilcli.MigrateGenesisCmd(),
genutilcli.GenTxCmd(simapp.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome), genutilcli.GenTxCmd(simapp.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
genutilcli.ValidateGenesisCmd(simapp.ModuleBasics, encodingConfig.TxConfig), genutilcli.ValidateGenesisCmd(simapp.ModuleBasics),
AddGenesisAccountCmd(simapp.DefaultNodeHome), AddGenesisAccountCmd(simapp.DefaultNodeHome),
tmcli.NewCompletionCmd(rootCmd, true), tmcli.NewCompletionCmd(rootCmd, true),
testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}), testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}),

View File

@ -9,7 +9,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmjson "github.com/tendermint/tendermint/libs/json" tmjson "github.com/tendermint/tendermint/libs/json"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
@ -74,9 +73,17 @@ $ %s migrate v0.36 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2
target := args[0] target := args[0]
importGenesis := args[1] importGenesis := args[1]
genDoc, err := tmtypes.GenesisDocFromFile(importGenesis) genDoc, err := validateGenDoc(importGenesis)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to read genesis document from file %s", importGenesis) return err
}
// Since some default values are valid values, we just print to
// make sure the user didn't forget to update these values.
if genDoc.ConsensusParams.Evidence.MaxBytes == 0 {
fmt.Printf("Warning: consensus_params.evidence.max_bytes is set to 0. If this is"+
" deliberate, feel free to ignore this warning. If not, please have a look at the chain"+
" upgrade guide at %s.\n", chainUpgradeGuide)
} }
var initialState types.AppMap var initialState types.AppMap

View File

@ -1,15 +1,12 @@
package cli_test package cli_test
import ( import (
"context"
"io/ioutil"
"path"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
) )
@ -19,29 +16,45 @@ func TestGetMigrationCallback(t *testing.T) {
} }
} }
func TestMigrateGenesis(t *testing.T) { func (s *IntegrationTestSuite) TestMigrateGenesis() {
home := t.TempDir() val0 := s.network.Validators[0]
cdc := makeCodec() testCases := []struct {
name string
genesisPath := path.Join(home, "genesis.json") genesis string
target := "v0.36" target string
expErr bool
cmd := cli.MigrateGenesisCmd() expErrMsg string
_ = testutil.ApplyMockIODiscardOutErr(cmd) }{
{
clientCtx := client.Context{}.WithLegacyAmino(cdc) "migrate to 0.36",
ctx := context.Background() `{"chain_id":"test","app_state":{}}`,
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) "v0.36",
false, "",
// Reject if we dont' have the right parameters or genesis does not exists },
cmd.SetArgs([]string{target, genesisPath}) {
require.Error(t, cmd.ExecuteContext(ctx)) "exported 0.37 genesis file",
v037Exported,
// Noop migration with minimal genesis "v0.40",
emptyGenesis := []byte(`{"chain_id":"test","app_state":{}}`) true, "Make sure that you have correctly migrated all Tendermint consensus params",
require.NoError(t, ioutil.WriteFile(genesisPath, emptyGenesis, 0644)) },
{
cmd.SetArgs([]string{target, genesisPath}) "valid 0.40 genesis file",
require.NoError(t, cmd.ExecuteContext(ctx)) v040Valid,
"v0.40",
false, "",
},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis)
_, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()})
if tc.expErr {
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
} }

View File

@ -3,7 +3,6 @@ package cli
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -13,8 +12,10 @@ import (
"github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/types/module"
) )
// Validate genesis command takes const chainUpgradeGuide = "https://docs.cosmos.network/master/migrations/chain-upgrade-guide-040.html"
func ValidateGenesisCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig) *cobra.Command {
// ValidateGenesisCmd takes a genesis file, and makes sure that it is valid.
func ValidateGenesisCmd(mbm module.BasicManager) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "validate-genesis [file]", Use: "validate-genesis [file]",
Args: cobra.RangeArgs(0, 1), Args: cobra.RangeArgs(0, 1),
@ -33,11 +34,9 @@ func ValidateGenesisCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfi
genesis = args[0] genesis = args[0]
} }
fmt.Fprintf(os.Stderr, "validating genesis file at %s\n", genesis) genDoc, err := validateGenDoc(genesis)
if err != nil {
var genDoc *tmtypes.GenesisDoc return err
if genDoc, err = tmtypes.GenesisDocFromFile(genesis); err != nil {
return fmt.Errorf("error loading genesis doc from %s: %s", genesis, err.Error())
} }
var genState map[string]json.RawMessage var genState map[string]json.RawMessage
@ -45,7 +44,7 @@ func ValidateGenesisCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfi
return fmt.Errorf("error unmarshalling genesis doc %s: %s", genesis, err.Error()) return fmt.Errorf("error unmarshalling genesis doc %s: %s", genesis, err.Error())
} }
if err = mbm.ValidateGenesis(cdc, txEncCfg, genState); err != nil { if err = mbm.ValidateGenesis(cdc, clientCtx.TxConfig, genState); err != nil {
return fmt.Errorf("error validating genesis file %s: %s", genesis, err.Error()) return fmt.Errorf("error validating genesis file %s: %s", genesis, err.Error())
} }
@ -54,3 +53,19 @@ func ValidateGenesisCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfi
}, },
} }
} }
// validateGenDoc reads a genesis file and validates that it is a correct
// Tendermint GenesisDoc. This function does not do any cosmos-related
// validation.
func validateGenDoc(importGenesisFile string) (*tmtypes.GenesisDoc, error) {
genDoc, err := tmtypes.GenesisDocFromFile(importGenesisFile)
if err != nil {
return nil, fmt.Errorf("%s. Make sure that"+
" you have correctly migrated all Tendermint consensus params, please see the"+
" chain migration guide at %s for more info",
err.Error(), chainUpgradeGuide,
)
}
return genDoc, nil
}

View File

@ -0,0 +1,82 @@
package cli_test
import (
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
)
// An example exported genesis file from a 0.37 chain. Note that evidence
// parameters only contains `max_age`.
var v037Exported = `{
"app_hash": "",
"app_state": {},
"chain_id": "test",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "1000"
},
"evidence": { "max_age": "100000" },
"validator": { "pub_key_types": ["ed25519"] }
},
"genesis_time": "2020-09-29T20:16:29.172362037Z",
"validators": []
}`
// An example exported genesis file that's 0.40 compatible.
var v040Valid = `{
"app_hash": "",
"app_state": {},
"chain_id": "test",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "1000"
},
"evidence": {
"max_age_num_blocks": "100000",
"max_age_duration": "172800000000000",
"max_bytes": "0"
},
"validator": { "pub_key_types": ["ed25519"] }
},
"genesis_time": "2020-09-29T20:16:29.172362037Z",
"validators": []
}`
func (s *IntegrationTestSuite) TestValidateGenesis() {
val0 := s.network.Validators[0]
testCases := []struct {
name string
genesis string
expErr bool
}{
{
"exported 0.37 genesis file",
v037Exported,
true,
},
{
"valid 0.40 genesis file",
v040Valid,
false,
},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis)
_, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.ValidateGenesisCmd(nil), []string{genesisFile.Name()})
if tc.expErr {
s.Require().Contains(err.Error(), "Make sure that you have correctly migrated all Tendermint consensus params")
} else {
s.Require().NoError(err)
}
})
}
}