Skip to content

Commit

Permalink
fix: added key when dry-run is true (#9480)
Browse files Browse the repository at this point in the history
<!--
The default pull request template is for types feat, fix, or refactor.
For other templates, add one of the following parameters to the url:
- template=docs.md
- template=other.md
-->

## Description

Closes: #9475 

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

This pull request ensures a key is not added after running `keys add` with `--dry-run`. This pull request also adds consistent output information for each key (previously multisig and pubkey did not print info).

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] added `!` to the type prefix if API or client breaking change - **n/a**
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - **n/a**
- [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - **n/a**
- [x] updated the relevant documentation or specification - **n/a**
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
ryanchristo authored Jun 25, 2021
1 parent 3fd376b commit 7679820
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

* [\#9480](https://github.com/cosmos/cosmos-sdk/pull/9480) Fix added keys when using `--dry-run`.
* [\#9540](https://github.com/cosmos/cosmos-sdk/pull/9540) Add output flag for query txs command.
* [\#9460](https://github.com/cosmos/cosmos-sdk/pull/9460) Fix lint error in `MigratePrefixAddress`.
* [\#9231](https://github.com/cosmos/cosmos-sdk/pull/9231) Remove redundant staking errors.
Expand Down
30 changes: 19 additions & 11 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func runAddCmdPrepare(cmd *cobra.Command, args []string) error {
return err
}

return RunAddCmd(clientCtx, cmd, args, buf)
return runAddCmd(clientCtx, cmd, args, buf)
}

/*
Expand All @@ -100,7 +100,7 @@ input
output
- armor encrypted private key (saved to file)
*/
func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
var err error

name := args[0]
Expand All @@ -117,7 +117,10 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
return err
}

if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); !dryRun {
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
// use in memory keybase
kb = keyring.NewInMemory()
} else {
_, err = kb.Key(name)
if err == nil {
// account exists, ask for user confirmation
Expand All @@ -138,19 +141,19 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf

multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
if len(multisigKeys) != 0 {
var pks []cryptotypes.PubKey
pks := make([]cryptotypes.PubKey, len(multisigKeys))
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
if err := validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
return err
}

for _, keyname := range multisigKeys {
for i, keyname := range multisigKeys {
k, err := kb.Key(keyname)
if err != nil {
return err
}

pks = append(pks, k.GetPubKey())
pks[i] = k.GetPubKey()
}

if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
Expand All @@ -160,12 +163,12 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
}

pk := multisig.NewLegacyAminoPubKey(multisigThreshold, pks)
if _, err := kb.SaveMultisig(name, pk); err != nil {
info, err := kb.SaveMultisig(name, pk)
if err != nil {
return err
}

cmd.PrintErrf("Key %q saved to disk.\n", name)
return nil
return printCreate(cmd, info, false, "", outputFormat)
}
}

Expand All @@ -176,8 +179,13 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
if err != nil {
return err
}
_, err := kb.SavePubKey(name, pk, algo.Name())
return err

info, err := kb.SavePubKey(name, pk, algo.Name())
if err != nil {
return err
}

return printCreate(cmd, info, false, "", outputFormat)
}

coinType, _ := cmd.Flags().GetUint32(flagCoinType)
Expand Down
65 changes: 65 additions & 0 deletions client/keys/add_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
package keys

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -124,3 +126,66 @@ func Test_runAddCmdLedger(t *testing.T) {
"PubKeySecp256k1{034FEF9CD7C4C63588D3B03FEB5281B9D232CBA34D6F3D71AEE59211FFBFE1FE87}",
key1.GetPubKey().String())
}

func Test_runAddCmdLedgerDryRun(t *testing.T) {
testData := []struct {
name string
args []string
added bool
}{
{
name: "ledger account is added",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
fmt.Sprintf("--%s=%s", flags.FlagUseLedger, "true"),
},
added: true,
},
{
name: "ledger account is not added with dry run",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
fmt.Sprintf("--%s=%s", flags.FlagUseLedger, "true"),
},
added: false,
},
}
for _, tt := range testData {
tt := tt
t.Run(tt.name, func(t *testing.T) {
cmd := AddKeyCommand()
cmd.Flags().AddFlagSet(Commands("home").PersistentFlags())

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

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

b := bytes.NewBufferString("")
cmd.SetOut(b)

cmd.SetArgs(tt.args)
require.NoError(t, cmd.ExecuteContext(ctx))

if tt.added {
_, err = kb.Key("testkey")
require.NoError(t, err)

out, err := ioutil.ReadAll(b)
require.NoError(t, err)
require.Contains(t, string(out), "name: testkey")
} else {
_, err = kb.Key("testkey")
require.Error(t, err)
require.Equal(t, "testkey.info: key not found", err.Error())
}
})
}
}
113 changes: 113 additions & 0 deletions client/keys/add_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package keys

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -13,6 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -114,3 +117,113 @@ func Test_runAddCmdBasic(t *testing.T) {
mockIn.Reset("\n" + password + "\n" + "fail" + "\n")
require.Error(t, cmd.ExecuteContext(ctx))
}

func Test_runAddCmdDryRun(t *testing.T) {
pubkey1 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtObiFVE4s+9+RX5SP8TN9r2mxpoaT4eGj9CJfK7VRzN"}`
pubkey2 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/se1vkqgdQ7VJQCM4mxN+L+ciGhnnJ4XYsQCRBMrdRi"}`

testData := []struct {
name string
args []string
added bool
}{
{
name: "account is added",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
},
added: true,
},
{
name: "account is not added with dry run",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
},
added: false,
},
{
name: "multisig account is added",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
fmt.Sprintf("--%s=%s", flagMultisig, "subkey"),
},
added: true,
},
{
name: "multisig account is not added with dry run",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
fmt.Sprintf("--%s=%s", flagMultisig, "subkey"),
},
added: false,
},
{
name: "pubkey account is added",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey1),
},
added: true,
},
{
name: "pubkey account is not added with dry run",
args: []string{
"testkey",
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey2),
},
added: false,
},
}
for _, tt := range testData {
tt := tt
t.Run(tt.name, func(t *testing.T) {
cmd := AddKeyCommand()
cmd.Flags().AddFlagSet(Commands("home").PersistentFlags())

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

appCodec := simapp.MakeTestEncodingConfig().Marshaler
clientCtx := client.Context{}.
WithJSONCodec(appCodec).
WithKeyringDir(kbHome).
WithKeyring(kb)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)

path := sdk.GetConfig().GetFullBIP44Path()
_, err = kb.NewAccount("subkey", testutil.TestMnemonic, "", path, hd.Secp256k1)
require.NoError(t, err)

t.Cleanup(func() {
_ = kb.Delete("subkey")
})

b := bytes.NewBufferString("")
cmd.SetOut(b)

cmd.SetArgs(tt.args)
require.NoError(t, cmd.ExecuteContext(ctx))

if tt.added {
_, err = kb.Key("testkey")
require.NoError(t, err)

out, err := ioutil.ReadAll(b)
require.NoError(t, err)
require.Contains(t, string(out), "name: testkey")
} else {
_, err = kb.Key("testkey")
require.Error(t, err)
require.Equal(t, "testkey.info: key not found", err.Error())
}
})
}
}
2 changes: 1 addition & 1 deletion crypto/keyring/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ func (ks keystore) writeInfo(info Info) error {
return err
}
if exists {
return errors.New("public key already exist in keybase")
return errors.New("public key already exists in keybase")
}

err = ks.db.Set(keyring.Item{
Expand Down

0 comments on commit 7679820

Please sign in to comment.