Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keyring-dir flag #7485

Merged
merged 11 commits into from
Oct 8, 2020
Merged
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]

### Client Breaking

* (modules) [\#7243](https://github.com/cosmos/cosmos-sdk/pull/7243) Rename `RegisterCodec` to `RegisterLegacyAminoCodec` and `codec.New()` is now renamed to `codec.NewLegacyAmino()`
* (cli) [\#6651](https://github.com/cosmos/cosmos-sdk/pull/6651) The `gentx` command has been improved. No longer are `--from` and `--name` flags required. Instead, a single argument, `name`, is required which refers to the key pair in the Keyring. In addition, an optional
`--moniker` flag can be provided to override the moniker found in `config.toml`.
Expand Down Expand Up @@ -163,6 +164,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa

### Features

* [\#7485](https://github.com/cosmos/cosmos-sdk/pull/7485) Introduce a new optional `--keyring-dir` flag that allows clients to specify a Keyring directory if it does not reside in the directory specified by `--home`.
* [\#6755](https://github.com/cosmos/cosmos-sdk/pull/6755) Add custom regex validation for `Coin` denom by overwriting `CoinDenomRegex` when using `/types/coin.go`.
* [\#7265](https://github.com/cosmos/cosmos-sdk/pull/7265) Support Tendermint block pruning through a new `min-retain-blocks` configuration that can be set in either `app.toml` or via the CLI. This parameter is used in conjunction with other criteria to determine the height at which Tendermint should prune blocks.
* (vesting) [\#7209](https://github.com/cosmos/cosmos-sdk/pull/7209) Create new `MsgCreateVestingAccount` message type along with CLI handler that allows for the creation of delayed and continuous vesting types.
Expand Down
12 changes: 12 additions & 0 deletions client/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ func ReadPersistentCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Cont
clientCtx = clientCtx.WithHomeDir(homeDir)
}

if clientCtx.KeyringDir == "" || flagSet.Changed(flags.FlagKeyringDir) {
keyringDir, _ := flagSet.GetString(flags.FlagKeyringDir)

// The keyring directory is optional and falls back to the home directory
// if omitted.
if keyringDir == "" {
keyringDir = clientCtx.HomeDir
}

clientCtx = clientCtx.WithKeyringDir(keyringDir)
}

if clientCtx.ChainID == "" || flagSet.Changed(flags.FlagChainID) {
chainID, _ := flagSet.GetString(flags.FlagChainID)
clientCtx = clientCtx.WithChainID(chainID)
Expand Down
2 changes: 1 addition & 1 deletion client/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestValidateCmd(t *testing.T) {
}

func TestSetCmdClientContextHandler(t *testing.T) {
initClientCtx := client.Context{}.WithHomeDir("/foo/bar").WithChainID("test-chain")
initClientCtx := client.Context{}.WithHomeDir("/foo/bar").WithChainID("test-chain").WithKeyringDir("/foo/bar")

newCmd := func() *cobra.Command {
c := &cobra.Command{
Expand Down
11 changes: 9 additions & 2 deletions client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Context struct {
OutputFormat string
Height int64
HomeDir string
KeyringDir string
From string
BroadcastMode string
FromName string
Expand Down Expand Up @@ -134,6 +135,12 @@ func (ctx Context) WithHomeDir(dir string) Context {
return ctx
}

// WithKeyringDir returns a copy of the Context with KeyringDir set.
func (ctx Context) WithKeyringDir(dir string) Context {
ctx.KeyringDir = dir
return ctx
}

// WithGenerateOnly returns a copy of the context with updated GenerateOnly value
func (ctx Context) WithGenerateOnly(generateOnly bool) Context {
ctx.GenerateOnly = generateOnly
Expand Down Expand Up @@ -302,8 +309,8 @@ func GetFromFields(kr keyring.Keyring, from string, genOnly bool) (sdk.AccAddres

func newKeyringFromFlags(ctx Context, backend string) (keyring.Keyring, error) {
if ctx.GenerateOnly {
return keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, ctx.HomeDir, ctx.Input)
return keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, ctx.KeyringDir, ctx.Input)
}

return keyring.New(sdk.KeyringServiceName(), backend, ctx.HomeDir, ctx.Input)
return keyring.New(sdk.KeyringServiceName(), backend, ctx.KeyringDir, ctx.Input)
}
2 changes: 2 additions & 0 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
// List of CLI flags
const (
FlagHome = tmcli.HomeFlag
FlagKeyringDir = "keyring-dir"
FlagUseLedger = "ledger"
FlagChainID = "chain-id"
FlagNode = "node"
Expand Down Expand Up @@ -84,6 +85,7 @@ func AddQueryFlagsToCmd(cmd *cobra.Command) {

// AddTxFlagsToCmd adds common flags to a module tx command.
func AddTxFlagsToCmd(cmd *cobra.Command) {
cmd.Flags().String(FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")
cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign")
cmd.Flags().Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)")
cmd.Flags().Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)")
Expand Down
10 changes: 5 additions & 5 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/hd"
Expand Down Expand Up @@ -84,20 +85,19 @@ the flag --nosort is set.

func runAddCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())

homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
dryRun, _ := cmd.Flags().GetBool(flags.FlagHome)
clientCtx := client.GetClientContextFromCmd(cmd)

var (
kr keyring.Keyring
err error
)

dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, homeDir, buf)
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf)
} else {
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
kr, err = keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
kr, err = keyring.New(sdk.KeyringServiceName(), backend, clientCtx.KeyringDir, buf)
}

if err != nil {
Expand Down
15 changes: 11 additions & 4 deletions client/keys/add_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
package keys

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -39,9 +41,11 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
// Prepare a keybase
kbHome := t.TempDir()

clientCtx := client.Context{}.WithKeyringDir(kbHome)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)

cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=0", flagAccount),
fmt.Sprintf("--%s=0", flagIndex),
Expand All @@ -53,7 +57,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {

mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
mockIn.Reset("test1234\ntest1234\n")
require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
Expand Down Expand Up @@ -83,12 +87,15 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
func Test_runAddCmdLedger(t *testing.T) {
cmd := AddKeyCommand()
cmd.Flags().AddFlagSet(Commands("home").PersistentFlags())

mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
kbHome := t.TempDir()

clientCtx := client.Context{}.WithKeyringDir(kbHome)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)

cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
Expand All @@ -97,7 +104,7 @@ func Test_runAddCmdLedger(t *testing.T) {
})
mockIn.Reset("test1234\ntest1234\n")

require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
Expand Down
32 changes: 19 additions & 13 deletions client/keys/add_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package keys

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand All @@ -21,9 +23,13 @@ func Test_runAddCmdBasic(t *testing.T) {

mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
kbHome := t.TempDir()
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)

kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)

clientCtx := client.Context{}.WithKeyringDir(kbHome)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)

t.Cleanup(func() {
_ = kb.Delete("keyname1")
_ = kb.Delete("keyname2")
Expand All @@ -37,10 +43,10 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn.Reset("y\n")
require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

mockIn.Reset("N\n")
require.Error(t, cmd.Execute())
require.Error(t, cmd.ExecuteContext(ctx))

cmd.SetArgs([]string{
"keyname2",
Expand All @@ -50,11 +56,11 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})

require.NoError(t, cmd.Execute())
require.Error(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))
require.Error(t, cmd.ExecuteContext(ctx))

mockIn.Reset("y\n")
require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

cmd.SetArgs([]string{
"keyname4",
Expand All @@ -64,8 +70,8 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})

require.NoError(t, cmd.Execute())
require.Error(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))
require.Error(t, cmd.ExecuteContext(ctx))

cmd.SetArgs([]string{
"keyname5",
Expand All @@ -75,7 +81,7 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
})

require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

// In recovery mode
cmd.SetArgs([]string{
Expand All @@ -85,11 +91,11 @@ func Test_runAddCmdBasic(t *testing.T) {

// use valid mnemonic and complete recovery key generation successfully
mockIn.Reset("decide praise business actor peasant farm drastic weather extend front hurt later song give verb rhythm worry fun pond reform school tumble august one\n")
require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

// use invalid mnemonic and fail recovery key generation
mockIn.Reset("invalid mnemonic\n")
require.Error(t, cmd.Execute())
require.Error(t, cmd.ExecuteContext(ctx))

// In interactive mode
cmd.SetArgs([]string{
Expand All @@ -102,9 +108,9 @@ func Test_runAddCmdBasic(t *testing.T) {

// set password and complete interactive key generation successfully
mockIn.Reset("\n" + password + "\n" + password + "\n")
require.NoError(t, cmd.Execute())
require.NoError(t, cmd.ExecuteContext(ctx))

// passwords don't match and fail interactive key generation
mockIn.Reset("\n" + password + "\n" + "fail" + "\n")
require.Error(t, cmd.Execute())
require.Error(t, cmd.ExecuteContext(ctx))
}
15 changes: 4 additions & 11 deletions client/keys/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package keys
import (
"bufio"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/spf13/cobra"
)
Expand All @@ -30,16 +29,10 @@ private keys stored in a ledger device cannot be deleted with the CLI.
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())

backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
if err != nil {
return err
}
clientCtx := client.GetClientContextFromCmd(cmd)

for _, name := range args {
info, err := kb.Key(name)
info, err := clientCtx.Keyring.Key(name)
if err != nil {
return err
}
Expand All @@ -53,7 +46,7 @@ private keys stored in a ledger device cannot be deleted with the CLI.
}
}

if err := kb.Delete(name); err != nil {
if err := clientCtx.Keyring.Delete(name); err != nil {
return err
}

Expand Down
8 changes: 7 additions & 1 deletion client/keys/delete_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package keys

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -41,7 +43,11 @@ func Test_runDeleteCmd(t *testing.T) {
require.NoError(t, err)

cmd.SetArgs([]string{"blah", fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome)})
err = cmd.Execute()

clientCtx := client.Context{}.WithKeyring(kb)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)

err = cmd.ExecuteContext(ctx)
require.Error(t, err)
require.Equal(t, "The specified item could not be found in the keyring", err.Error())

Expand Down
14 changes: 3 additions & 11 deletions client/keys/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// ExportKeyCommand exports private keys from the key store.
Expand All @@ -20,20 +18,14 @@ func ExportKeyCommand() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())

backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
if err != nil {
return err
}
clientCtx := client.GetClientContextFromCmd(cmd)

encryptPassword, err := input.GetPassword("Enter passphrase to encrypt the exported key:", buf)
if err != nil {
return err
}

armored, err := kb.ExportPrivKeyArmor(args[0], encryptPassword)
armored, err := clientCtx.Keyring.ExportPrivKeyArmor(args[0], encryptPassword)
if err != nil {
return err
}
Expand Down
Loading