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

R4R: Make gaiacli keys show multisig-ready #2554

Merged
merged 10 commits into from
Oct 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ FEATURES
* [stake][cli] [\#1672](https://github.com/cosmos/cosmos-sdk/issues/1672) Introduced
new commission flags for validator commands `create-validator` and `edit-validator`.
* [stake][cli] [\#1890](https://github.com/cosmos/cosmos-sdk/issues/1890) Add `--genesis-format` flag to `gaiacli tx create-validator` to produce transactions in genesis-friendly format.
* [cli][\#2554](https://github.com/cosmos/cosmos-sdk/issues/2554) Make `gaiacli keys show` multisig ready.

* Gaia
* [cli] #2170 added ability to show the node's address via `gaiad tendermint show-address`
Expand Down
65 changes: 59 additions & 6 deletions client/keys/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package keys

import (
"fmt"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/tendermint/tendermint/crypto"
"net/http"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/crypto/multisig"
"github.com/tendermint/tendermint/libs/cli"
)

Expand All @@ -18,30 +22,68 @@ const (
FlagPublicKey = "pubkey"
// FlagBechPrefix defines a desired Bech32 prefix encoding for a key.
FlagBechPrefix = "bech"

flagMultiSigThreshold = "multisig-threshold"
defaultMultiSigKeyName = "multi"
)

var _ keys.Info = (*multiSigKey)(nil)

type multiSigKey struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will multiSigKey be used elsewhere, besides just via show? If so, may I suggest to moving it to it's own file, even though it's fairly small.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's presently not used elsewhere.

name string
key crypto.PubKey
}

func (m multiSigKey) GetName() string { return m.name }
func (m multiSigKey) GetType() keys.KeyType { return keys.TypeLocal }
func (m multiSigKey) GetPubKey() crypto.PubKey { return m.key }
func (m multiSigKey) GetAddress() sdk.AccAddress { return sdk.AccAddress(m.key.Address()) }

func showKeysCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "show [name]",
Short: "Show key info for the given name",
Long: `Return public details of one local key.`,
Args: cobra.ExactArgs(1),
Args: cobra.MinimumNArgs(1),
RunE: runShowCmd,
}

cmd.Flags().String(FlagBechPrefix, "acc", "The Bech32 prefix encoding for a key (acc|val|cons)")
cmd.Flags().Bool(FlagAddress, false, "output the address only (overrides --output)")
cmd.Flags().Bool(FlagPublicKey, false, "output the public key only (overrides --output)")
cmd.Flags().Uint(flagMultiSigThreshold, 1, "K out of N required signatures")

return cmd
}

func runShowCmd(cmd *cobra.Command, args []string) error {
name := args[0]
func runShowCmd(cmd *cobra.Command, args []string) (err error) {
var info keys.Info

info, err := GetKeyInfo(name)
if err != nil {
return err
if len(args) == 1 {
info, err = GetKeyInfo(args[0])
if err != nil {
return err
}
} else {
pks := make([]crypto.PubKey, len(args))
alessio marked this conversation as resolved.
Show resolved Hide resolved
for i, keyName := range args {
info, err := GetKeyInfo(keyName)
if err != nil {
return err
}
pks[i] = info.GetPubKey()
}

multisigThreshold := viper.GetInt(flagMultiSigThreshold)
err = validateMultisigThreshold(multisigThreshold, len(args))
if err != nil {
return err
}
multikey := multisig.NewPubKeyMultisigThreshold(multisigThreshold, pks)
info = multiSigKey{
name: defaultMultiSigKeyName,
key: multikey,
}
}

isShowAddr := viper.GetBool(FlagAddress)
Expand Down Expand Up @@ -73,6 +115,17 @@ func runShowCmd(cmd *cobra.Command, args []string) error {
return nil
}

func validateMultisigThreshold(k, nKeys int) error {
if k <= 0 {
return fmt.Errorf("threshold must be a positive integer")
}
if nKeys < k {
return fmt.Errorf(
"threshold k of n multisignature: %d < %d", nKeys, k)
}
return nil
}

func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
switch bechPrefix {
case "acc":
Expand Down
10 changes: 10 additions & 0 deletions docs/sdk/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ gaiad tendermint show-validator
We strongly recommend _NOT_ using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds.
:::

#### Multisig public keys

You can generate and print a multisig public key by typing:

```bash
gaiacli show -m K key1 key2...keyK
```

`K` is the minimum weight, e.g. minimum number of private keys that must have signed the transactions that carry the generated public key.

### Account

#### Get Tokens
Expand Down