Merge PR #4790: Fix multisig output

This commit is contained in:
Federico Kunze 2019-07-31 17:47:18 +02:00 committed by Alexander Bezobchuk
parent 8c989fd424
commit 7c70912263
5 changed files with 82 additions and 36 deletions

View File

@ -0,0 +1 @@
#4338 fix multisig key output for CLI

View File

@ -7,19 +7,29 @@ import (
// KeyOutput defines a structure wrapping around an Info object used for output
// functionality.
type KeyOutput struct {
Name string `json:"name"`
Type string `json:"type"`
Address string `json:"address"`
PubKey string `json:"pubkey"`
Mnemonic string `json:"mnemonic,omitempty"`
Threshold uint `json:"threshold,omitempty"`
PubKeys []multisigPubKeyOutput `json:"pubkeys,omitempty"`
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Address string `json:"address" yaml:"address"`
PubKey string `json:"pubkey" yaml:"pubkey"`
Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"`
Threshold uint `json:"threshold,omitempty" yaml:"threshold"`
PubKeys []multisigPubKeyOutput `json:"pubkeys,omitempty" yaml:"pubkeys"`
}
// NewKeyOutput creates a default KeyOutput instance without Mnemonic, Threshold and PubKeys
func NewKeyOutput(name, keyType, address, pubkey string) KeyOutput {
return KeyOutput{
Name: name,
Type: keyType,
Address: address,
PubKey: pubkey,
}
}
type multisigPubKeyOutput struct {
Address string `json:"address"`
PubKey string `json:"pubkey"`
Weight uint `json:"weight"`
Address string `json:"address" yaml:"address"`
PubKey string `json:"pubkey" yaml:"pubkey"`
Weight uint `json:"weight" yaml:"weight"`
}
// Bech32KeysOutput returns a slice of KeyOutput objects, each with the "acc"
@ -47,12 +57,7 @@ func Bech32ConsKeyOutput(keyInfo Info) (KeyOutput, error) {
return KeyOutput{}, err
}
return KeyOutput{
Name: keyInfo.GetName(),
Type: keyInfo.GetType().String(),
Address: consAddr.String(),
PubKey: bechPubKey,
}, nil
return NewKeyOutput(keyInfo.GetName(), keyInfo.GetType().String(), consAddr.String(), bechPubKey), nil
}
// Bech32ValKeyOutput create a KeyOutput in with "val" Bech32 prefixes.
@ -64,32 +69,22 @@ func Bech32ValKeyOutput(keyInfo Info) (KeyOutput, error) {
return KeyOutput{}, err
}
return KeyOutput{
Name: keyInfo.GetName(),
Type: keyInfo.GetType().String(),
Address: valAddr.String(),
PubKey: bechPubKey,
}, nil
return NewKeyOutput(keyInfo.GetName(), keyInfo.GetType().String(), valAddr.String(), bechPubKey), nil
}
// Bech32KeyOutput create a KeyOutput in with "acc" Bech32 prefixes. If the
// public key is a multisig public key, then the threshold and constituent
// public keys will be added.
func Bech32KeyOutput(info Info) (KeyOutput, error) {
accAddr := sdk.AccAddress(info.GetPubKey().Address().Bytes())
bechPubKey, err := sdk.Bech32ifyAccPub(info.GetPubKey())
func Bech32KeyOutput(keyInfo Info) (KeyOutput, error) {
accAddr := sdk.AccAddress(keyInfo.GetPubKey().Address().Bytes())
bechPubKey, err := sdk.Bech32ifyAccPub(keyInfo.GetPubKey())
if err != nil {
return KeyOutput{}, err
}
ko := KeyOutput{
Name: info.GetName(),
Type: info.GetType().String(),
Address: accAddr.String(),
PubKey: bechPubKey,
}
ko := NewKeyOutput(keyInfo.GetName(), keyInfo.GetType().String(), accAddr.String(), bechPubKey)
if mInfo, ok := info.(multiInfo); ok {
if mInfo, ok := keyInfo.(*multiInfo); ok {
pubKeys := make([]multisigPubKeyOutput, len(mInfo.PubKeys))
for i, pk := range mInfo.PubKeys {

View File

@ -0,0 +1,30 @@
package keys
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/multisig"
"github.com/tendermint/tendermint/crypto/secp256k1"
)
func TestBech32KeysOutput(t *testing.T) {
tmpKey := secp256k1.GenPrivKey().PubKey()
bechTmpKey := sdk.MustBech32ifyAccPub(tmpKey)
tmpAddr := sdk.AccAddress(tmpKey.Address().Bytes())
multisigPks := multisig.NewPubKeyMultisigThreshold(1, []crypto.PubKey{tmpKey})
multiInfo := NewMultiInfo("multisig", multisigPks)
accAddr := sdk.AccAddress(multiInfo.GetPubKey().Address().Bytes())
bechPubKey := sdk.MustBech32ifyAccPub(multiInfo.GetPubKey())
expectedOutput := NewKeyOutput(multiInfo.GetName(), multiInfo.GetType().String(), accAddr.String(), bechPubKey)
expectedOutput.Threshold = 1
expectedOutput.PubKeys = []multisigPubKeyOutput{{tmpAddr.String(), bechTmpKey, 1}}
outputs, err := Bech32KeysOutput([]Info{multiInfo})
require.NoError(t, err)
require.Equal(t, expectedOutput, outputs[0])
}

View File

@ -118,22 +118,27 @@ func newLocalInfo(name string, pub crypto.PubKey, privArmor string) Info {
}
}
// GetType implements Info interface
func (i localInfo) GetType() KeyType {
return TypeLocal
}
// GetType implements Info interface
func (i localInfo) GetName() string {
return i.Name
}
// GetType implements Info interface
func (i localInfo) GetPubKey() crypto.PubKey {
return i.PubKey
}
// GetType implements Info interface
func (i localInfo) GetAddress() types.AccAddress {
return i.PubKey.Address().Bytes()
}
// GetType implements Info interface
func (i localInfo) GetPath() (*hd.BIP44Params, error) {
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
}
@ -153,22 +158,27 @@ func newLedgerInfo(name string, pub crypto.PubKey, path hd.BIP44Params) Info {
}
}
// GetType implements Info interface
func (i ledgerInfo) GetType() KeyType {
return TypeLedger
}
// GetName implements Info interface
func (i ledgerInfo) GetName() string {
return i.Name
}
// GetPubKey implements Info interface
func (i ledgerInfo) GetPubKey() crypto.PubKey {
return i.PubKey
}
// GetAddress implements Info interface
func (i ledgerInfo) GetAddress() types.AccAddress {
return i.PubKey.Address().Bytes()
}
// GetPath implements Info interface
func (i ledgerInfo) GetPath() (*hd.BIP44Params, error) {
tmp := i.Path
return &tmp, nil
@ -187,22 +197,27 @@ func newOfflineInfo(name string, pub crypto.PubKey) Info {
}
}
// GetType implements Info interface
func (i offlineInfo) GetType() KeyType {
return TypeOffline
}
// GetName implements Info interface
func (i offlineInfo) GetName() string {
return i.Name
}
// GetPubKey implements Info interface
func (i offlineInfo) GetPubKey() crypto.PubKey {
return i.PubKey
}
// GetAddress implements Info interface
func (i offlineInfo) GetAddress() types.AccAddress {
return i.PubKey.Address().Bytes()
}
// GetPath implements Info interface
func (i offlineInfo) GetPath() (*hd.BIP44Params, error) {
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
}
@ -211,6 +226,8 @@ type multisigPubKeyInfo struct {
PubKey crypto.PubKey `json:"pubkey"`
Weight uint `json:"weight"`
}
// multiInfo is the public information about a multisig key
type multiInfo struct {
Name string `json:"name"`
PubKey crypto.PubKey `json:"pubkey"`
@ -218,6 +235,7 @@ type multiInfo struct {
PubKeys []multisigPubKeyInfo `json:"pubkeys"`
}
// NewMultiInfo creates a new multiInfo instance
func NewMultiInfo(name string, pub crypto.PubKey) Info {
multiPK := pub.(multisig.PubKeyMultisigThreshold)
@ -235,22 +253,27 @@ func NewMultiInfo(name string, pub crypto.PubKey) Info {
}
}
// GetType implements Info interface
func (i multiInfo) GetType() KeyType {
return TypeMulti
}
// GetName implements Info interface
func (i multiInfo) GetName() string {
return i.Name
}
// GetPubKey implements Info interface
func (i multiInfo) GetPubKey() crypto.PubKey {
return i.PubKey
}
// GetAddress implements Info interface
func (i multiInfo) GetAddress() types.AccAddress {
return i.PubKey.Address().Bytes()
}
// GetPath implements Info interface
func (i multiInfo) GetPath() (*hd.BIP44Params, error) {
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
}

View File

@ -16,10 +16,7 @@ func Test_writeReadLedgerInfo(t *testing.T) {
bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A")
copy(tmpKey[:], bz)
lInfo := ledgerInfo{
"some_name",
tmpKey,
*hd.NewFundraiserParams(5, types.CoinType, 1)}
lInfo := newLedgerInfo("some_name", tmpKey, *hd.NewFundraiserParams(5, types.CoinType, 1))
assert.Equal(t, TypeLedger, lInfo.GetType())
path, err := lInfo.GetPath()