diff --git a/CHANGELOG.md b/CHANGELOG.md index 12b9e20663c..fe8d4b2328d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/gov,cli) [#14718](https://github.com/cosmos/cosmos-sdk/pull/14718) Added `AddGovPropFlagsToCmd` and `ReadGovPropFlags` functions. * (x/bank) [#14894](https://github.com/cosmos/cosmos-sdk/pull/14894) Return a human readable denomination for IBC vouchers when querying bank balances. Added a `ResolveDenom` parameter to `types.QueryAllBalancesRequest` and `--resolve-denom` flag to `GetBalancesCmd()`. * (x/groups) [#14879](https://github.com/cosmos/cosmos-sdk/pull/14879) Add `Query/Groups` query to get all the groups. +* (x/genutil,cli) [#15147](https://github.com/cosmos/cosmos-sdk/pull/15147) Add `--initial-height` flag to cli init cmd to provide `genesis.json` with user defined initial block height ### Improvements diff --git a/client/flags/flags.go b/client/flags/flags.go index 14240e1f0c9..148965de471 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -83,6 +83,7 @@ const ( FlagReverse = "reverse" FlagTip = "tip" FlagAux = "aux" + FlagInitHeight = "initial-height" // FlagOutput is the flag to set the output format. // This differs from FlagOutputDocument that is used to set the output file. FlagOutput = cmtcli.OutputFlag diff --git a/x/genutil/client/cli/init.go b/x/genutil/client/cli/init.go index 592a3a5546d..e09e84067e5 100644 --- a/x/genutil/client/cli/init.go +++ b/x/genutil/client/cli/init.go @@ -107,6 +107,12 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { } } + // Get initial height + initHeight, _ := cmd.Flags().GetInt64(flags.FlagInitHeight) + if initHeight < 1 { + initHeight = 1 + } + nodeID, _, err := genutil.InitializeNodeValidatorFilesFromMnemonic(config, mnemonic) if err != nil { return err @@ -151,6 +157,7 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { appGenesis.AppVersion = version.Version appGenesis.ChainID = chainID appGenesis.AppState = appState + appGenesis.InitialHeight = initHeight appGenesis.Consensus = &types.ConsensusGenesis{ Validators: nil, } @@ -171,6 +178,7 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { cmd.Flags().Bool(FlagRecover, false, "provide seed phrase to recover existing key instead of creating") cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") cmd.Flags().String(FlagDefaultBondDenom, "", "genesis file default denomination, if left blank default value is 'stake'") + cmd.Flags().Int64(flags.FlagInitHeight, 1, "specify the initial block height at genesis") return cmd } diff --git a/x/genutil/client/cli/init_test.go b/x/genutil/client/cli/init_test.go index 551ccb882a4..ae935d887ab 100644 --- a/x/genutil/client/cli/init_test.go +++ b/x/genutil/client/cli/init_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -28,6 +29,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/staking" ) @@ -285,6 +287,70 @@ func TestInitConfig(t *testing.T) { require.Contains(t, out, "\"chain_id\": \"foo\"") } +func TestInitWithHeight(t *testing.T) { + home := t.TempDir() + logger := log.NewNopLogger() + cfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(t, err) + + serverCtx := server.NewContext(viper.New(), cfg, logger) + interfaceRegistry := types.NewInterfaceRegistry() + marshaler := codec.NewProtoCodec(interfaceRegistry) + clientCtx := client.Context{}. + WithCodec(marshaler). + WithLegacyAmino(makeCodec()). + WithChainID("foo"). // add chain-id to clientCtx + WithHomeDir(home) + + ctx := context.Background() + ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) + ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) + + testInitialHeight := int64(333) + + cmd := genutilcli.InitCmd(testMbm, home) + cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)}) + + require.NoError(t, cmd.ExecuteContext(ctx)) + + appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile()) + require.NoError(t, importErr) + + require.Equal(t, testInitialHeight, appGenesis.InitialHeight) +} + +func TestInitWithNegativeHeight(t *testing.T) { + home := t.TempDir() + logger := log.NewNopLogger() + cfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(t, err) + + serverCtx := server.NewContext(viper.New(), cfg, logger) + interfaceRegistry := types.NewInterfaceRegistry() + marshaler := codec.NewProtoCodec(interfaceRegistry) + clientCtx := client.Context{}. + WithCodec(marshaler). + WithLegacyAmino(makeCodec()). + WithChainID("foo"). // add chain-id to clientCtx + WithHomeDir(home) + + ctx := context.Background() + ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) + ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) + + testInitialHeight := int64(-333) + + cmd := genutilcli.InitCmd(testMbm, home) + cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)}) + + require.NoError(t, cmd.ExecuteContext(ctx)) + + appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile()) + require.NoError(t, importErr) + + require.Equal(t, int64(1), appGenesis.InitialHeight) +} + // custom tx codec func makeCodec() *codec.LegacyAmino { cdc := codec.NewLegacyAmino()