Skip to content

Commit

Permalink
Move PubKey bech32 to legacy package and migrate the usage where poss…
Browse files Browse the repository at this point in the history
…ible
  • Loading branch information
robert-zaremba committed Nov 3, 2020
1 parent 4420fe2 commit faa822a
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 209 deletions.
43 changes: 21 additions & 22 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ the flag --nosort is set.
Args: cobra.ExactArgs(1),
RunE: runAddCmd,
}

cmd.Flags().StringSlice(flagMultisig, nil, "Construct and store a multisig public key (implies --pubkey)")
cmd.Flags().Int(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
cmd.Flags().Bool(flagNoSort, false, "Keys passed to --multisig are taken in the order they're supplied")
cmd.Flags().String(FlagPublicKey, "", "Parse a public key in bech32 format and save it to disk")
cmd.Flags().BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic")
cmd.Flags().Bool(flags.FlagUseLedger, false, "Store a local reference to a private key on a Ledger device")
cmd.Flags().Bool(flagRecover, false, "Provide seed phrase to recover existing key instead of creating")
cmd.Flags().Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)")
cmd.Flags().Bool(flags.FlagDryRun, false, "Perform action, but don't add key to local keystore")
cmd.Flags().String(flagHDPath, "", "Manual HD Path derivation (overrides BIP44 config)")
cmd.Flags().Uint32(flagCoinType, sdk.GetConfig().GetCoinType(), "coin type number for HD derivation")
cmd.Flags().Uint32(flagAccount, 0, "Account number for HD derivation")
cmd.Flags().Uint32(flagIndex, 0, "Address index number for HD derivation")
cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
flags := cmd.Flags()
flags.StringSlice(flagMultisig, nil, "Construct and store a multisig public key (implies --pubkey)")
flags.Int(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
flags.Bool(flagNoSort, false, "Keys passed to --multisig are taken in the order they're supplied")
flags.String(FlagPublicKey, "", "Parse a public key in bech32 format and save it to disk")
flags.BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic")
flags.Bool(flags.FlagUseLedger, false, "Store a local reference to a private key on a Ledger device")
flags.Bool(flagRecover, false, "Provide seed phrase to recover existing key instead of creating")
flags.Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)")
flags.Bool(flags.FlagDryRun, false, "Perform action, but don't add key to local keystore")
flags.String(flagHDPath, "", "Manual HD Path derivation (overrides BIP44 config)")
flags.Uint32(flagCoinType, sdk.GetConfig().GetCoinType(), "coin type number for HD derivation")
flags.Uint32(flagAccount, 0, "Account number for HD derivation")
flags.Uint32(flagIndex, 0, "Address index number for HD derivation")
flags.String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")

cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.ErrOrStderr())
Expand Down Expand Up @@ -186,16 +186,15 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf

pubKey, _ := cmd.Flags().GetString(FlagPublicKey)
if pubKey != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, pubKey)
if err != nil {
return err
}

if _, err := kb.SavePubKey(name, pk, algo.Name()); err != nil {
var pk crypto.PubKey
// TODO: shall we use KeysCdc here (global from this module, = codec.NewLegacyAmino)?
marshaller := client.GetClientContextFromCmd(cmd).JSONMarshaler
if err := marshaller.UnmarshalJSON([]byte(pubKey), &pk); err != nil {
return err
}

return nil
_, err := kb.SavePubKey(name, pk, algo.Name())
return err
}

coinType, _ := cmd.Flags().GetUint32(flagCoinType)
Expand Down
12 changes: 6 additions & 6 deletions client/keys/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ consisting of all the keys provided by name and multisig threshold.`,
Args: cobra.MinimumNArgs(1),
RunE: runShowCmd,
}

cmd.Flags().String(FlagBechPrefix, sdk.PrefixAccount, "The Bech32 prefix encoding for a key (acc|val|cons)")
cmd.Flags().BoolP(FlagAddress, "a", false, "Output the address only (overrides --output)")
cmd.Flags().BoolP(FlagPublicKey, "p", false, "Output the public key only (overrides --output)")
cmd.Flags().BoolP(FlagDevice, "d", false, "Output the address in a ledger device")
cmd.Flags().Int(flagMultiSigThreshold, 1, "K out of N required signatures")
flags := cmd.Flags()
flags.String(FlagBechPrefix, sdk.PrefixAccount, "The Bech32 prefix encoding for a key (acc|val|cons)")
flags.BoolP(FlagAddress, "a", false, "Output the address only (overrides --output)")
flags.BoolP(FlagPublicKey, "p", false, "Output the public key only (overrides --output)")
flags.BoolP(FlagDevice, "d", false, "Output the address in a ledger device")
flags.Int(flagMultiSigThreshold, 1, "K out of N required signatures")

return cmd
}
Expand Down
3 changes: 3 additions & 0 deletions server/tm_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/privval"
tversion "github.com/tendermint/tendermint/version"
"google.golang.org/protobuf/proto"
yaml "gopkg.in/yaml.v2"

"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -59,6 +60,8 @@ func ShowValidatorCmd() *cobra.Command {
return printlnJSON(valPubKey)
}

pk, ok := valPubKey.(proto.Message)

pubkey, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey)
if err != nil {
return err
Expand Down
119 changes: 2 additions & 117 deletions types/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ import (
"strings"

"github.com/tendermint/tendermint/crypto"
tmed25519 "github.com/tendermint/tendermint/crypto/ed25519"
yaml "gopkg.in/yaml.v2"

"github.com/cosmos/cosmos-sdk/codec/legacy"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/types/bech32"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

const (
Expand Down Expand Up @@ -604,121 +598,12 @@ func (ca ConsAddress) Format(s fmt.State, verb rune) {
// auxiliary
// ----------------------------------------------------------------------------

// Bech32PubKeyType defines a string type alias for a Bech32 public key type.
type Bech32PubKeyType string

// Bech32 conversion constants
const (
Bech32PubKeyTypeAccPub Bech32PubKeyType = "accpub"
Bech32PubKeyTypeValPub Bech32PubKeyType = "valpub"
Bech32PubKeyTypeConsPub Bech32PubKeyType = "conspub"
)

// Bech32ifyPubKey returns a Bech32 encoded string containing the appropriate
// prefix based on the key type provided for a given PublicKey.
func Bech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) (string, error) {
var bech32Prefix string

switch pkt {
case Bech32PubKeyTypeAccPub:
bech32Prefix = GetConfig().GetBech32AccountPubPrefix()

case Bech32PubKeyTypeValPub:
bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix()

case Bech32PubKeyTypeConsPub:
bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix()

}

// This piece of code is to keep backwards-compatibility.
// For ed25519 keys, our own ed25519 is registered in Amino under a
// different name than TM's ed25519. But since users are already using
// TM's ed25519 bech32 encoding, we explicitly say to bech32-encode our own
// ed25519 the same way as TM's ed25519.
// TODO: Remove Bech32ifyPubKey and all usages (cosmos/cosmos-sdk/issues/#7357)
pkToMarshal := pubkey
if ed25519Pk, ok := pubkey.(*ed25519.PubKey); ok {
pkToMarshal = ed25519Pk.AsTmPubKey()
}

return bech32.ConvertAndEncode(bech32Prefix, legacy.Cdc.MustMarshalBinaryBare(pkToMarshal))
}

// MustBech32ifyPubKey calls Bech32ifyPubKey except it panics on error.
func MustBech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) string {
res, err := Bech32ifyPubKey(pkt, pubkey)
if err != nil {
panic(err)
}

return res
}

// GetPubKeyFromBech32 returns a PublicKey from a bech32-encoded PublicKey with
// a given key type.
func GetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) (crypto.PubKey, error) {
var bech32Prefix string

switch pkt {
case Bech32PubKeyTypeAccPub:
bech32Prefix = GetConfig().GetBech32AccountPubPrefix()

case Bech32PubKeyTypeValPub:
bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix()

case Bech32PubKeyTypeConsPub:
bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix()

}

bz, err := GetFromBech32(pubkeyStr, bech32Prefix)
if err != nil {
return nil, err
}

aminoPk, err := cryptocodec.PubKeyFromBytes(bz)
if err != nil {
return nil, err
}

var protoPk crypto.PubKey
switch aminoPk.(type) {

// We are bech32ifying some secp256k1 keys in tests.
case *secp256k1.PubKey:
protoPk = aminoPk
case *ed25519.PubKey:
protoPk = aminoPk

// Real-life case.
case tmed25519.PubKey:
protoPk = &ed25519.PubKey{
Key: aminoPk.Bytes(),
}

default:
// We only allow ed25519 pubkeys to be bech32-ed right now.
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "bech32 pubkey does not support %T", aminoPk)
}

return protoPk, nil
}

// MustGetPubKeyFromBech32 calls GetPubKeyFromBech32 except it panics on error.
func MustGetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) crypto.PubKey {
res, err := GetPubKeyFromBech32(pkt, pubkeyStr)
if err != nil {
panic(err)
}

return res
}
var errBech32EmptyAddress = errors.New("decoding Bech32 address failed: must provide a non empty address")

// GetFromBech32 decodes a bytestring from a Bech32 encoded string.
func GetFromBech32(bech32str, prefix string) ([]byte, error) {
if len(bech32str) == 0 {
return nil, errors.New("decoding Bech32 address failed: must provide an address")
return nil, errBech32EmptyAddress
}

hrp, bz, err := bech32.DecodeAndConvert(bech32str)
Expand Down
42 changes: 0 additions & 42 deletions types/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,48 +68,6 @@ func (s *addressTestSuite) TestEmptyAddresses() {
s.Require().Error(err)
}

func (s *addressTestSuite) TestRandBech32PubkeyConsistency() {
pubBz := make([]byte, ed25519.PubKeySize)
pub := &ed25519.PubKey{Key: pubBz}

for i := 0; i < 1000; i++ {
rand.Read(pub.Key)

mustBech32AccPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeAccPub, pub)
bech32AccPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeAccPub, pub)
s.Require().Nil(err)
s.Require().Equal(bech32AccPub, mustBech32AccPub)

mustBech32ValPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeValPub, pub)
bech32ValPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeValPub, pub)
s.Require().Nil(err)
s.Require().Equal(bech32ValPub, mustBech32ValPub)

mustBech32ConsPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeConsPub, pub)
bech32ConsPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeConsPub, pub)
s.Require().Nil(err)
s.Require().Equal(bech32ConsPub, mustBech32ConsPub)

mustAccPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeAccPub, bech32AccPub)
accPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeAccPub, bech32AccPub)
s.Require().Nil(err)
s.Require().Equal(accPub, mustAccPub)

mustValPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeValPub, bech32ValPub)
valPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeValPub, bech32ValPub)
s.Require().Nil(err)
s.Require().Equal(valPub, mustValPub)

mustConsPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeConsPub, bech32ConsPub)
consPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeConsPub, bech32ConsPub)
s.Require().Nil(err)
s.Require().Equal(consPub, mustConsPub)

s.Require().Equal(valPub, accPub)
s.Require().Equal(valPub, consPub)
}
}

func (s *addressTestSuite) TestYAMLMarshalers() {
addr := secp256k1.GenPrivKey().PubKey().Address()

Expand Down
Loading

0 comments on commit faa822a

Please sign in to comment.