From 8528ac76654766f17d446663feea1b729feb6650 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Mon, 25 Mar 2019 11:27:24 -0400 Subject: [PATCH] Merge PR #3960: Disable Keybase for Generate Only in CLI --- ...ed-the-Keybase-is-not-used-and-as-a-result | 2 ++ client/context/context.go | 19 +++++++++--- cmd/gaia/cli_test/cli_test.go | 26 ++++++++-------- cmd/gaia/cli_test/test_helpers.go | 14 +++++---- cmd/gaia/init/gentx.go | 30 ++++++++++++------- 5 files changed, 59 insertions(+), 32 deletions(-) create mode 100644 .pending/bugfixes/gaia/3889-When---generate-only-is-provided-the-Keybase-is-not-used-and-as-a-result diff --git a/.pending/bugfixes/gaia/3889-When---generate-only-is-provided-the-Keybase-is-not-used-and-as-a-result b/.pending/bugfixes/gaia/3889-When---generate-only-is-provided-the-Keybase-is-not-used-and-as-a-result new file mode 100644 index 0000000000..cdeff1d63f --- /dev/null +++ b/.pending/bugfixes/gaia/3889-When---generate-only-is-provided-the-Keybase-is-not-used-and-as-a-result @@ -0,0 +1,2 @@ +#3889 When `--generate-only` is provided, the Keybase is not used and as a result +the `--from` value must be a valid Bech32 cosmos address. diff --git a/client/context/context.go b/client/context/context.go index fd2e1ac1a5..f85f9ba4cd 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -67,7 +67,8 @@ func NewCLIContext() CLIContext { } from := viper.GetString(client.FlagFrom) - fromAddress, fromName, err := GetFromFields(from) + genOnly := viper.GetBool(client.FlagGenerateOnly) + fromAddress, fromName, err := GetFromFields(from, genOnly) if err != nil { fmt.Printf("failed to get from fields: %v", err) os.Exit(1) @@ -93,7 +94,7 @@ func NewCLIContext() CLIContext { PrintResponse: viper.GetBool(client.FlagPrintResponse), Verifier: verifier, Simulate: viper.GetBool(client.FlagDryRun), - GenerateOnly: viper.GetBool(client.FlagGenerateOnly), + GenerateOnly: genOnly, FromAddress: fromAddress, FromName: fromName, Indent: viper.GetBool(client.FlagIndentResponse), @@ -274,12 +275,22 @@ func (ctx CLIContext) PrintOutput(toPrint fmt.Stringer) (err error) { } // GetFromFields returns a from account address and Keybase name given either -// an address or key name. -func GetFromFields(from string) (sdk.AccAddress, string, error) { +// an address or key name. If genOnly is true, only a valid Bech32 cosmos +// address is returned. +func GetFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) { if from == "" { return nil, "", nil } + if genOnly { + addr, err := sdk.AccAddressFromBech32(from) + if err != nil { + return nil, "", err + } + + return addr, "", nil + } + keybase, err := keys.NewKeyBaseFromHomeFlag() if err != nil { return nil, "", err diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 5bdb325f4a..f346f0f14b 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -361,7 +361,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) // Generate a create validator transaction and ensure correctness - success, stdout, stderr := f.TxStakingCreateValidator(keyBar, consPubKey, sdk.NewInt64Coin(denom, 2), "--generate-only") + success, stdout, stderr := f.TxStakingCreateValidator(barAddr.String(), consPubKey, sdk.NewInt64Coin(denom, 2), "--generate-only") require.True(f.T, success) require.Empty(f.T, stderr) @@ -437,7 +437,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { // Test submit generate only for submit proposal proposalTokens := sdk.TokensFromTendermintPower(5) success, stdout, stderr := f.TxGovSubmitProposal( - keyFoo, "Text", "Test", "test", sdk.NewCoin(denom, proposalTokens), "--generate-only", "-y") + fooAddr.String(), "Text", "Test", "test", sdk.NewCoin(denom, proposalTokens), "--generate-only", "-y") require.True(t, success) require.Empty(t, stderr) msg := unmarshalStdTx(t, stdout) @@ -476,7 +476,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { // Test deposit generate only depositTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr = f.TxGovDeposit(1, keyFoo, sdk.NewCoin(denom, depositTokens), "--generate-only") + success, stdout, stderr = f.TxGovDeposit(1, fooAddr.String(), sdk.NewCoin(denom, depositTokens), "--generate-only") require.True(t, success) require.Empty(t, stderr) msg = unmarshalStdTx(t, stdout) @@ -511,7 +511,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, gov.StatusVotingPeriod, proposal1.Status) // Test vote generate only - success, stdout, stderr = f.TxGovVote(1, gov.OptionYes, keyFoo, "--generate-only") + success, stdout, stderr = f.TxGovVote(1, gov.OptionYes, fooAddr.String(), "--generate-only") require.True(t, success) require.Empty(t, stderr) msg = unmarshalStdTx(t, stdout) @@ -618,7 +618,7 @@ func TestGaiaCLIValidateSignatures(t *testing.T) { barAddr := f.KeyAddress(keyBar) // generate sendTx with default gas - success, stdout, stderr := f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") + success, stdout, stderr := f.TxSend(fooAddr.String(), barAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") require.True(t, success) require.Empty(t, stderr) @@ -669,7 +669,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { // Test generate sendTx with default gas sendTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only") + success, stdout, stderr := f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only") require.True(t, success) require.Empty(t, stderr) msg := unmarshalStdTx(t, stdout) @@ -678,7 +678,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { require.Equal(t, 0, len(msg.GetSignatures())) // Test generate sendTx with --gas=$amount - success, stdout, stderr = f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=100", "--generate-only") + success, stdout, stderr = f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--gas=100", "--generate-only") require.True(t, success) require.Empty(t, stderr) msg = unmarshalStdTx(t, stdout) @@ -687,7 +687,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { require.Equal(t, 0, len(msg.GetSignatures())) // Test generate sendTx, estimate gas - success, stdout, stderr = f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=auto", "--generate-only") + success, stdout, stderr = f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--gas=auto", "--generate-only") require.True(t, success) require.NotEmpty(t, stderr) msg = unmarshalStdTx(t, stdout) @@ -764,7 +764,7 @@ func TestGaiaCLIMultisignInsufficientCosigners(t *testing.T) { tests.WaitForNextNBlocksTM(1, f.Port) // Test generate sendTx with multisig - success, stdout, _ := f.TxSend(keyFooBarBaz, barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") + success, stdout, _ := f.TxSend(fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") require.True(t, success) // Write the output to disk @@ -808,8 +808,10 @@ func TestGaiaCLIEncode(t *testing.T) { // Build a testing transaction and write it to disk barAddr := f.KeyAddress(keyBar) + keyAddr := f.KeyAddress(keyFoo) + sendTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only", "--memo", "deadbeef") + success, stdout, stderr := f.TxSend(keyAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only", "--memo", "deadbeef") require.True(t, success) require.Empty(t, stderr) @@ -853,7 +855,7 @@ func TestGaiaCLIMultisignSortSignatures(t *testing.T) { require.Equal(t, int64(10), fooBarBazAcc.GetCoins().AmountOf(denom).Int64()) // Test generate sendTx with multisig - success, stdout, _ := f.TxSend(keyFooBarBaz, barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") + success, stdout, _ := f.TxSend(fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") require.True(t, success) // Write the output to disk @@ -915,7 +917,7 @@ func TestGaiaCLIMultisign(t *testing.T) { require.Equal(t, int64(10), fooBarBazAcc.GetCoins().AmountOf(denom).Int64()) // Test generate sendTx with multisig - success, stdout, stderr := f.TxSend(keyFooBarBaz, bazAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") + success, stdout, stderr := f.TxSend(fooBarBazAddr.String(), bazAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") require.True(t, success) require.Empty(t, stderr) diff --git a/cmd/gaia/cli_test/test_helpers.go b/cmd/gaia/cli_test/test_helpers.go index 16227acfba..04bfb2666d 100644 --- a/cmd/gaia/cli_test/test_helpers.go +++ b/cmd/gaia/cli_test/test_helpers.go @@ -104,15 +104,15 @@ func (f Fixtures) GenesisState() app.GenesisState { return appState } -// InitFixtures is called at the beginning of a test -// and initializes a chain with 1 validator +// InitFixtures is called at the beginning of a test and initializes a chain +// with 1 validator. func InitFixtures(t *testing.T) (f *Fixtures) { f = NewFixtures(t) - // Reset test state + // reset test state f.UnsafeResetAll() - // Ensure keystore has foo and bar keys + // ensure keystore has foo and bar keys f.KeysDelete(keyFoo) f.KeysDelete(keyBar) f.KeysDelete(keyBar) @@ -124,14 +124,14 @@ func InitFixtures(t *testing.T) (f *Fixtures) { f.KeysAdd(keyFooBarBaz, "--multisig-threshold=2", fmt.Sprintf( "--multisig=%s,%s,%s", keyFoo, keyBar, keyBaz)) - // Ensure that CLI output is in JSON format + // ensure that CLI output is in JSON format f.CLIConfig("output", "json") // NOTE: GDInit sets the ChainID f.GDInit(keyFoo) f.CLIConfig("chain-id", f.ChainID) - // Start an account with tokens + // start an account with tokens f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) f.AddGenesisAccount( f.KeyAddress(keyVesting), startCoins, @@ -139,8 +139,10 @@ func InitFixtures(t *testing.T) (f *Fixtures) { fmt.Sprintf("--vesting-start-time=%d", time.Now().UTC().UnixNano()), fmt.Sprintf("--vesting-end-time=%d", time.Now().Add(60*time.Second).UTC().UnixNano()), ) + f.GenTx(keyFoo) f.CollectGenTxs() + return } diff --git a/cmd/gaia/init/gentx.go b/cmd/gaia/init/gentx.go index 67ebfb87a9..166c5a6b27 100644 --- a/cmd/gaia/init/gentx.go +++ b/cmd/gaia/init/gentx.go @@ -126,9 +126,17 @@ following delegation and commission default parameters: return err } - // Run gaiad tx create-validator txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) + + // XXX: Set the generate-only flag here after the CLI context has + // been created. This allows the from name/key to be correctly populated. + // + // TODO: Consider removing the manual setting of generate-only in + // favor of a 'gentx' flag in the create-validator command. + viper.Set(client.FlagGenerateOnly, true) + + // create a 'create-validator' message txBldr, msg, err := cli.BuildCreateValidatorMsg(cliCtx, txBldr) if err != nil { return err @@ -228,16 +236,18 @@ func accountInGenesis(genesisState app.GenesisState, key sdk.AccAddress, coins s return fmt.Errorf("account %s in not in the app_state.accounts array of genesis.json", key) } -func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip, chainID string, - valPubKey crypto.PubKey) { - viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home +func prepareFlagsForTxCreateValidator( + config *cfg.Config, nodeID, ip, chainID string, valPubKey crypto.PubKey, +) { + + viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) viper.Set(client.FlagChainID, chainID) - viper.Set(client.FlagFrom, viper.GetString(client.FlagName)) // --from - viper.Set(cli.FlagNodeID, nodeID) // --node-id - viper.Set(cli.FlagIP, ip) // --ip - viper.Set(cli.FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey)) // --pubkey - viper.Set(client.FlagGenerateOnly, true) // --genesis-format - viper.Set(cli.FlagMoniker, config.Moniker) // --moniker + viper.Set(client.FlagFrom, viper.GetString(client.FlagName)) + viper.Set(cli.FlagNodeID, nodeID) + viper.Set(cli.FlagIP, ip) + viper.Set(cli.FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey)) + viper.Set(cli.FlagMoniker, config.Moniker) + if config.Moniker == "" { viper.Set(cli.FlagMoniker, viper.GetString(client.FlagName)) }