Skip to content

Commit

Permalink
Merge PR cosmos#4228: gaiakeyutil -> gaiacli keys parse
Browse files Browse the repository at this point in the history
  • Loading branch information
alessio authored and alexanderbez committed May 2, 2019
1 parent f4a96fd commit 4e70a37
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 65 deletions.
2 changes: 2 additions & 0 deletions .pending/breaking/gaiacli/4228-merge-gaiakeyutil-into-gaiacli
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#4228 Merge gaiakeyutil functionality into gaiacli keys.
Drop `gaiakeyutil` in favor of new `gaiacli keys parse` command. Syntax and semantic are preserved.
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ else
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiad ./cmd/gaia/cmd/gaiad
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaia/cmd/gaiacli
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiareplay ./cmd/gaia/cmd/gaiareplay
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiakeyutil ./cmd/gaia/cmd/gaiakeyutil
endif

build-linux: go.sum
Expand All @@ -94,7 +93,6 @@ install: go.sum check-ledger update_gaia_lite_docs
go install -mod=readonly $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiad
go install -mod=readonly $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiacli
go install -mod=readonly $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiareplay
go install -mod=readonly $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiakeyutil

install_debug: go.sum
go install -mod=readonly $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiadebug
Expand Down
133 changes: 133 additions & 0 deletions client/keys/parse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package keys

import (
"encoding/hex"
"errors"
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/bech32"
"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
)

var bech32Prefixes = []string{
sdk.Bech32PrefixAccAddr,
sdk.Bech32PrefixAccPub,
sdk.Bech32PrefixValAddr,
sdk.Bech32PrefixValPub,
sdk.Bech32PrefixConsAddr,
sdk.Bech32PrefixConsPub,
}

type hexOutput struct {
Human string `json:"human"`
Bytes string `json:"bytes"`
}

func (ho hexOutput) String() string {
return fmt.Sprintf("Human readable part: %v\nBytes (hex): %s", ho.Human, ho.Bytes)
}

func newHexOutput(human string, bs []byte) hexOutput {
return hexOutput{Human: human, Bytes: fmt.Sprintf("%X", bs)}
}

type bech32Output struct {
Formats []string `json:"formats"`
}

func newBech32Output(bs []byte) bech32Output {
out := bech32Output{Formats: make([]string, len(bech32Prefixes))}
for i, prefix := range bech32Prefixes {
bech32Addr, err := bech32.ConvertAndEncode(prefix, bs)
if err != nil {
panic(err)
}
out.Formats[i] = bech32Addr
}

return out
}

func (bo bech32Output) String() string {
out := make([]string, len(bo.Formats))

for i, format := range bo.Formats {
out[i] = fmt.Sprintf(" - %s", format)
}

return fmt.Sprintf("Bech32 Formats:\n%s", strings.Join(out, "\n"))
}

func parseKeyStringCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "parse <hex-or-bech32-address>",
Short: "Parse address from hex to bech32 and vice versa",
Long: `Convert and print to stdout key addresses and fingerprints from
hexadecimal into bech32 cosmos prefixed format and vice versa.
`,
Args: cobra.ExactArgs(1),
RunE: parseKey,
}
cmd.Flags().Bool(client.FlagIndentResponse, false, "Indent JSON output")

return cmd
}

func parseKey(_ *cobra.Command, args []string) error {
addr := strings.TrimSpace(args[0])
if len(addr) == 0 {
return errors.New("couldn't parse empty input")
}
if !(runFromBech32(addr) || runFromHex(addr)) {
return errors.New("couldn't find valid bech32 nor hex data")
}
return nil
}

// print info from bech32
func runFromBech32(bech32str string) bool {
hrp, bz, err := bech32.DecodeAndConvert(bech32str)
if err != nil {
return false
}
displayParseKeyInfo(newHexOutput(hrp, bz))
return true
}

// print info from hex
func runFromHex(hexstr string) bool {
bz, err := hex.DecodeString(hexstr)
if err != nil {
return false
}
displayParseKeyInfo(newBech32Output(bz))
return true
}

func displayParseKeyInfo(stringer fmt.Stringer) {
switch viper.Get(cli.OutputFlag) {
case OutputFormatText:
fmt.Printf("%s\n", stringer)

case OutputFormatJSON:
var out []byte
var err error

if viper.GetBool(client.FlagIndentResponse) {
out, err = cdc.MarshalJSONIndent(stringer, "", " ")
if err != nil {
panic(err)
}
} else {
out = cdc.MustMarshalJSON(stringer)
}

fmt.Println(string(out))
}
}
28 changes: 28 additions & 0 deletions client/keys/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package keys

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestParseKey(t *testing.T) {
bech32str := "cosmos104ytdpvrx9284zd50v9ep8c6j7pua7dkk0x3ek"
hexstr := "EB5AE9872103497EC092EF901027049E4F39200C60040D3562CD7F104A39F62E6E5A39A818F4"

tests := []struct {
name string
args []string
wantErr bool
}{
{"empty input", []string{""}, true},
{"invalid input", []string{"invalid"}, true},
{"bech32", []string{bech32str}, false},
{"hex", []string{hexstr}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.wantErr, parseKey(nil, tt.args) != nil)
})
}
}
1 change: 1 addition & 0 deletions client/keys/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func Commands() *cobra.Command {
client.LineBreak,
deleteKeyCommand(),
updateKeyCommand(),
parseKeyStringCommand(),
)
return cmd
}
2 changes: 1 addition & 1 deletion client/keys/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ func TestCommands(t *testing.T) {
assert.NotNil(t, rootCommands)

// Commands are registered
assert.Equal(t, 7, len(rootCommands.Commands()))
assert.Equal(t, 8, len(rootCommands.Commands()))
}
2 changes: 0 additions & 2 deletions cmd/gaia/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ else
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiad ../../cmd/gaia/cmd/gaiad
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiacli ../../cmd/gaia/cmd/gaiacli
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiareplay ../../cmd/gaia/cmd/gaiareplay
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiakeyutil ../../cmd/gaia/cmd/gaiakeyutil
endif

build-linux: ../../go.sum
Expand All @@ -82,7 +81,6 @@ install: ../../go.sum check-ledger
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiad
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiacli
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiareplay
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiakeyutil

install-debug: ../../go.sum
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiadebug
Expand Down
60 changes: 0 additions & 60 deletions cmd/gaia/cmd/gaiakeyutil/main.go

This file was deleted.

0 comments on commit 4e70a37

Please sign in to comment.