Add PublicKeyCodec (#6372)
* Add PublicKeyCodec * Add tests * Remove cache codec * Remove cache codec * Revert proto changes * Revert proto changes * refactor and move docs * Lint * Apply suggestions from code review Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
08b7557fe5
commit
6740d27b55
|
@ -0,0 +1,15 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// PublicKeyCodec defines a type which can encode and decode crypto.PubKey's
|
||||
// to and from protobuf PublicKey's
|
||||
type PublicKeyCodec interface {
|
||||
// Encode encodes the crypto.PubKey as a protobuf PublicKey or returns an error
|
||||
Encode(key crypto.PubKey) (*PublicKey, error)
|
||||
|
||||
// Decode decodes a crypto.PubKey from a protobuf PublicKey or returns an error
|
||||
Decode(key *PublicKey) (crypto.PubKey, error)
|
||||
}
|
3
go.sum
3
go.sum
|
@ -78,7 +78,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/confio/ics23 v0.6.0 h1:bQsi55t2+xjW6EWDl83IBF1VWurplbUu+OT6pukeiEo=
|
||||
github.com/confio/ics23-iavl v0.6.0 h1:vVRCuVaP38FCw1kTeEdFuGuiY+2vAGTBQoH7Zxkq/ws=
|
||||
github.com/confio/ics23-iavl v0.6.0/go.mod h1:mmXAxD1vWoO0VP8YHu6mM1QHGv71NQqa1iSVm4HeKcY=
|
||||
github.com/confio/ics23/go v0.0.0-20200323120010-7d9a00f0a2fa/go.mod h1:W1I3XC8d9N8OTu/ct5VJ84ylcOunZwMXsWkd27nvVts=
|
||||
|
@ -467,8 +466,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
|
||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package std
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
ed255192 "github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/crypto/sr25519"
|
||||
)
|
||||
|
||||
// DefaultPublicKeyCodec implements the standard PublicKeyCodec for the SDK which
|
||||
// supports a standard set of public key types
|
||||
type DefaultPublicKeyCodec struct{}
|
||||
|
||||
var _ types.PublicKeyCodec = DefaultPublicKeyCodec{}
|
||||
|
||||
// Decode implements the PublicKeyCodec.Decode method
|
||||
func (cdc DefaultPublicKeyCodec) Decode(key *types.PublicKey) (crypto.PubKey, error) {
|
||||
switch key := key.Sum.(type) {
|
||||
case *types.PublicKey_Secp256K1:
|
||||
n := len(key.Secp256K1)
|
||||
if n != secp256k1.PubKeySecp256k1Size {
|
||||
return nil, fmt.Errorf("wrong length %d for secp256k1 public key", n)
|
||||
}
|
||||
var res secp256k1.PubKeySecp256k1
|
||||
copy(res[:], key.Secp256K1)
|
||||
return res, nil
|
||||
case *types.PublicKey_Ed25519:
|
||||
n := len(key.Ed25519)
|
||||
if n != ed255192.PubKeyEd25519Size {
|
||||
return nil, fmt.Errorf("wrong length %d for ed25519 public key", n)
|
||||
}
|
||||
var res ed255192.PubKeyEd25519
|
||||
copy(res[:], key.Ed25519)
|
||||
return res, nil
|
||||
case *types.PublicKey_Sr25519:
|
||||
n := len(key.Sr25519)
|
||||
if n != sr25519.PubKeySr25519Size {
|
||||
return nil, fmt.Errorf("wrong length %d for sr25519 public key", n)
|
||||
}
|
||||
var res sr25519.PubKeySr25519
|
||||
copy(res[:], key.Sr25519)
|
||||
return res, nil
|
||||
case *types.PublicKey_Multisig:
|
||||
pubKeys := key.Multisig.PubKeys
|
||||
resKeys := make([]crypto.PubKey, len(pubKeys))
|
||||
for i, k := range pubKeys {
|
||||
dk, err := cdc.Decode(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resKeys[i] = dk
|
||||
}
|
||||
return multisig.NewPubKeyMultisigThreshold(int(key.Multisig.K), resKeys), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("can't decode PubKey of type %T. Use a custom PublicKeyCodec instead", key)
|
||||
}
|
||||
}
|
||||
|
||||
// Encode implements the PublicKeyCodec.Encode method
|
||||
func (cdc DefaultPublicKeyCodec) Encode(key crypto.PubKey) (*types.PublicKey, error) {
|
||||
switch key := key.(type) {
|
||||
case secp256k1.PubKeySecp256k1:
|
||||
return &types.PublicKey{Sum: &types.PublicKey_Secp256K1{Secp256K1: key[:]}}, nil
|
||||
case ed255192.PubKeyEd25519:
|
||||
return &types.PublicKey{Sum: &types.PublicKey_Ed25519{Ed25519: key[:]}}, nil
|
||||
case sr25519.PubKeySr25519:
|
||||
return &types.PublicKey{Sum: &types.PublicKey_Sr25519{Sr25519: key[:]}}, nil
|
||||
case multisig.PubKeyMultisigThreshold:
|
||||
pubKeys := key.PubKeys
|
||||
resKeys := make([]*types.PublicKey, len(pubKeys))
|
||||
for i, k := range pubKeys {
|
||||
dk, err := cdc.Encode(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resKeys[i] = dk
|
||||
}
|
||||
return &types.PublicKey{Sum: &types.PublicKey_Multisig{Multisig: &types.PubKeyMultisigThreshold{
|
||||
K: uint32(key.K),
|
||||
PubKeys: resKeys,
|
||||
}}}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("can't encode PubKey of type %T. Use a custom PublicKeyCodec instead", key)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package std_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/crypto/sr25519"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
||||
)
|
||||
|
||||
func roundTripTest(t *testing.T, pubKey crypto.PubKey) {
|
||||
cdc := std.DefaultPublicKeyCodec{}
|
||||
|
||||
pubKeyEnc, err := cdc.Encode(pubKey)
|
||||
require.NoError(t, err)
|
||||
pubKeyDec, err := cdc.Decode(pubKeyEnc)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubKey, pubKeyDec)
|
||||
}
|
||||
|
||||
func TestDefaultPublicKeyCodec(t *testing.T) {
|
||||
pubKeySecp256k1 := secp256k1.GenPrivKey().PubKey()
|
||||
roundTripTest(t, pubKeySecp256k1)
|
||||
|
||||
pubKeyEd25519 := ed25519.GenPrivKey().PubKey()
|
||||
roundTripTest(t, pubKeyEd25519)
|
||||
|
||||
pubKeySr25519 := sr25519.GenPrivKey().PubKey()
|
||||
roundTripTest(t, pubKeySr25519)
|
||||
|
||||
pubKeyMultisig := multisig.NewPubKeyMultisigThreshold(2, []crypto.PubKey{
|
||||
pubKeySecp256k1, pubKeyEd25519, pubKeySr25519,
|
||||
})
|
||||
roundTripTest(t, pubKeyMultisig)
|
||||
}
|
Loading…
Reference in New Issue