Skip to content

Commit

Permalink
Merge PR #2040: Refactor Validator Account Types/Bech32 Prefixing
Browse files Browse the repository at this point in the history
* Add new account bech32 prefixes with godocs

* Restructure spacing of existing account code

* Update account godocs

* More account godoc updates + new tm pub/addr helpers

* Update validator type to use new account types/bech32 prefixes

* Fix account documentation errors

* Update Bech32 prefix for consensus nodes

* Update Bech32 spec doc

* Fix account type tests

* Add missing account consensus functions, clear up godocs, and fix tests

* Add to TestRandBech32PubkeyConsistency check

* Update initialization of validator public keys

* Update query signing info command

* Implement new ConsAddress type with associated unit tests

* [WIP] Update stake and slashing parameters

* Update all calls to MustBech32ifyValPub

* [WIP] Validator operator API updates

* [WIP] Fix and update unit tests

* Fix gov logs (helping to debug failing tests)

* Fix gov tally

* Fix all broken x/ unit tests

* Update gaia app genesis address logic

* Fix linting errors

* Fix broken LCD tests

* Fix broken CLI tests

* Implement command to get validator address and pubkey from key name

* Add support for getting validator key information via REST endpoint

* Update PENDING log

* Update docs

* Revert GaiaGenTx.PubKey bech32 prefix

* Fix broken docs and cli tests

* Update genesis to use correct Bech32 (cons) prefix for pubkeys

* Update docs and unit tests to reflect new cosmos account bech32 prefix

* minor formatting
  • Loading branch information
alexanderbez authored and rigelrozanski committed Aug 31, 2018
1 parent dc0f132 commit 2d92803
Show file tree
Hide file tree
Showing 66 changed files with 1,312 additions and 832 deletions.
8 changes: 8 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ BREAKING CHANGES
* [cli] \#2014 `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively
* [makefile] `get_vendor_deps` no longer updates lock file it just updates vendor directory. Use `update_vendor_deps` to update the lock file. [#2152](https://github.com/cosmos/cosmos-sdk/pull/2152)
* [cli] \#2190 `gaiacli init --gen-txs` is now `gaiacli init --with-txs` to reduce confusion
* \#2040 All commands that utilize a validator's address must now use the new
bech32 prefix, `cosmosval`. A validator's Tendermint signing key and address
now use a new bech32 prefix, `cosmoscons`.

* Gaia
* Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013)
* [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface.
* [docs] [#2001](https://github.com/cosmos/cosmos-sdk/pull/2001) Update slashing spec for slashing period
* [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed"
* [x/stake] \#2040 Validator operator type has now changed to `sdk.ValAddress`
* A new bech32 prefix has been introduced for Tendermint signing keys and
addresses, `cosmosconspub` and `cosmoscons` respectively.

* SDK
* [core] \#1807 Switch from use of rational to decimal
Expand All @@ -38,6 +44,8 @@ FEATURES
* Gaia CLI (`gaiacli`)
* [cli] Cmds to query staking pool and params
* [gov][cli] #2062 added `--proposal` flag to `submit-proposal` that allows a JSON file containing a proposal to be passed in
* \#2040 Add `--bech` to `gaiacli keys show` and respective REST endpoint to
provide desired Bech32 prefix encoding
* [cli] \#2047 Setting the --gas flag value to 0 triggers a simulation of the tx before the actual execution. The gas estimate obtained via the simulation will be used as gas limit in the actual execution.
* [cli] \#2047 The --gas-adjustment flag can be used to adjust the estimate obtained via the simulation triggered by --gas=0.

Expand Down
3 changes: 2 additions & 1 deletion client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ func printCreate(info keys.Info, seed string) {
output := viper.Get(cli.OutputFlag)
switch output {
case "text":
printInfo(info)
printKeyInfo(info, Bech32KeyOutput)

// print seed unless requested not to.
if !viper.GetBool(client.FlagUseLedger) && !viper.GetBool(flagNoBackup) {
fmt.Println("**Important** write this seed phrase in a safe place.")
Expand Down
2 changes: 1 addition & 1 deletion client/keys/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Commands() *cobra.Command {
cmd.AddCommand(
addKeyCommand(),
listKeysCmd,
showKeysCmd,
showKeysCmd(),
client.LineBreak,
deleteKeyCommand(),
updateKeyCommand(),
Expand Down
110 changes: 74 additions & 36 deletions client/keys/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keys

import (
"encoding/json"
"fmt"
"net/http"

"github.com/cosmos/cosmos-sdk/crypto/keys"
Expand All @@ -18,46 +19,69 @@ const (
FlagAddress = "address"
// FlagPublicKey represents the user's public key on the command line.
FlagPublicKey = "pubkey"
// FlagBechPrefix defines a desired Bech32 prefix encoding for a key
FlagBechPrefix = "bech"
)

var showKeysCmd = &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),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]
info, err := getKey(name)
if err != nil {
return err
}

showAddress := viper.GetBool(FlagAddress)
showPublicKey := viper.GetBool(FlagPublicKey)
outputSet := cmd.Flag(cli.OutputFlag).Changed
if showAddress && showPublicKey {
return errors.New("cannot use both --address and --pubkey at once")
}
if outputSet && (showAddress || showPublicKey) {
return errors.New("cannot use --output with --address or --pubkey")
}
if showAddress {
printKeyAddress(info)
return nil
}
if showPublicKey {
printPubKey(info)
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),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]
info, err := getKey(name)
if err != nil {
return err
}

showAddress := viper.GetBool(FlagAddress)
showPublicKey := viper.GetBool(FlagPublicKey)
outputSet := cmd.Flag(cli.OutputFlag).Changed

if showAddress && showPublicKey {
return errors.New("cannot use both --address and --pubkey at once")
}
if outputSet && (showAddress || showPublicKey) {
return errors.New("cannot use --output with --address or --pubkey")
}

bechKeyOut, err := getBechKeyOut(viper.GetString(FlagBechPrefix))
if err != nil {
return err
}

switch {
case showAddress:
printKeyAddress(info, bechKeyOut)
case showPublicKey:
printPubKey(info, bechKeyOut)
default:
printKeyInfo(info, bechKeyOut)
}
return nil
}
},
}

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)")

printInfo(info)
return nil
},
return cmd
}

func init() {
showKeysCmd.Flags().Bool(FlagAddress, false, "output the address only (overrides --output)")
showKeysCmd.Flags().Bool(FlagPublicKey, false, "output the public key only (overrides --output)")
func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
switch bechPrefix {
case "acc":
return Bech32KeyOutput, nil
case "val":
return Bech32ValKeyOutput, nil
case "cons":
return Bech32ConsKeyOutput, nil
}

return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix)
}

func getKey(name string) (keys.Info, error) {
Expand All @@ -76,21 +100,35 @@ func getKey(name string) (keys.Info, error) {
func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
bechPrefix := r.URL.Query().Get(FlagBechPrefix)

if bechPrefix == "" {
bechPrefix = "acc"
}

bechKeyOut, err := getBechKeyOut(bechPrefix)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
return
}

info, err := getKey(name)
// TODO check for the error if key actually does not exist, instead of assuming this as the reason
// TODO: check for the error if key actually does not exist, instead of
// assuming this as the reason
if err != nil {
w.WriteHeader(404)
w.Write([]byte(err.Error()))
return
}

keyOutput, err := Bech32KeyOutput(info)
keyOutput, err := bechKeyOut(info)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}

output, err := json.MarshalIndent(keyOutput, "", " ")
if err != nil {
w.WriteHeader(500)
Expand Down
70 changes: 56 additions & 14 deletions client/keys/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const KeyDBName = "keys"
// keybase is used to make GetKeyBase a singleton
var keybase keys.Keybase

type bechKeyOutFn func(keyInfo keys.Info) (KeyOutput, error)

// TODO make keybase take a database not load from the directory

// initialize a keybase based on the configuration
Expand Down Expand Up @@ -97,11 +99,11 @@ func SetKeyBase(kb keys.Keybase) {

// used for outputting keys.Info over REST
type KeyOutput struct {
Name string `json:"name"`
Type string `json:"type"`
Address sdk.AccAddress `json:"address"`
PubKey string `json:"pub_key"`
Seed string `json:"seed,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
Address string `json:"address"`
PubKey string `json:"pub_key"`
Seed string `json:"seed,omitempty"`
}

// create a list of KeyOutput in bech32 format
Expand All @@ -119,24 +121,61 @@ func Bech32KeysOutput(infos []keys.Info) ([]KeyOutput, error) {

// create a KeyOutput in bech32 format
func Bech32KeyOutput(info keys.Info) (KeyOutput, error) {
account := sdk.AccAddress(info.GetPubKey().Address().Bytes())
accAddr := sdk.AccAddress(info.GetPubKey().Address().Bytes())
bechPubKey, err := sdk.Bech32ifyAccPub(info.GetPubKey())
if err != nil {
return KeyOutput{}, err
}

return KeyOutput{
Name: info.GetName(),
Type: info.GetType().String(),
Address: account,
Address: accAddr.String(),
PubKey: bechPubKey,
}, nil
}

// Bech32ConsKeyOutput returns key output for a consensus node's key
// information.
func Bech32ConsKeyOutput(keyInfo keys.Info) (KeyOutput, error) {
consAddr := sdk.ConsAddress(keyInfo.GetPubKey().Address().Bytes())

bechPubKey, err := sdk.Bech32ifyConsPub(keyInfo.GetPubKey())
if err != nil {
return KeyOutput{}, err
}

return KeyOutput{
Name: keyInfo.GetName(),
Type: keyInfo.GetType().String(),
Address: consAddr.String(),
PubKey: bechPubKey,
}, nil
}

// Bech32ValKeyOutput returns key output for a validator's key information.
func Bech32ValKeyOutput(keyInfo keys.Info) (KeyOutput, error) {
valAddr := sdk.ValAddress(keyInfo.GetPubKey().Address().Bytes())

bechPubKey, err := sdk.Bech32ifyValPub(keyInfo.GetPubKey())
if err != nil {
return KeyOutput{}, err
}

return KeyOutput{
Name: keyInfo.GetName(),
Type: keyInfo.GetType().String(),
Address: valAddr.String(),
PubKey: bechPubKey,
}, nil
}

func printInfo(info keys.Info) {
ko, err := Bech32KeyOutput(info)
func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
ko, err := bechKeyOut(keyInfo)
if err != nil {
panic(err)
}

switch viper.Get(cli.OutputFlag) {
case "text":
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
Expand All @@ -146,6 +185,7 @@ func printInfo(info keys.Info) {
if err != nil {
panic(err)
}

fmt.Println(string(out))
}
}
Expand Down Expand Up @@ -174,18 +214,20 @@ func printKeyOutput(ko KeyOutput) {
fmt.Printf("%s\t%s\t%s\t%s\n", ko.Name, ko.Type, ko.Address, ko.PubKey)
}

func printKeyAddress(info keys.Info) {
ko, err := Bech32KeyOutput(info)
func printKeyAddress(info keys.Info, bechKeyOut bechKeyOutFn) {
ko, err := bechKeyOut(info)
if err != nil {
panic(err)
}
fmt.Println(ko.Address.String())

fmt.Println(ko.Address)
}

func printPubKey(info keys.Info) {
ko, err := Bech32KeyOutput(info)
func printPubKey(info keys.Info, bechKeyOut bechKeyOutFn) {
ko, err := bechKeyOut(info)
if err != nil {
panic(err)
}

fmt.Println(ko.PubKey)
}
Loading

0 comments on commit 2d92803

Please sign in to comment.