mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-08 04:50:16 +00:00
## Issue: Hey, not sure if this is disallowed for any reason specifically, but it would be very beneficial to define additional types to decode tendermint key implementations from bytes, since it uses a static codec. If this is okay, let me know and I will add documentation. Context: For Ethermint to switch to using Cosmos' keybase, decoding the keys requires this codec to be updated Just to document, I did experiment with creating a mapping from string to objects to be able to keep track of the key types added to be able to be used in the RegisterAmino(..) call, but because of how go is compiled, cosmos would just use the base types. This may be a useful feature for someone just building on top of Tendermint and not going through Cosmos, but to not add confusion or unnecessary complexity, I left it out. ## Commits: * Exposes amino codec to be able to decode pk bytes in application * Change how codec is modified * Remove unneeded comment * Fix comment * Fix comment * Add registered type to nametable * Add pending changelog entry * Reorder change * Added check if type is registered and added test * Make test type private * Remove unnecessary duplicate exists check
80 lines
2.8 KiB
Go
80 lines
2.8 KiB
Go
package cryptoAmino
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
amino "github.com/tendermint/go-amino"
|
|
"github.com/tendermint/tendermint/crypto"
|
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
"github.com/tendermint/tendermint/crypto/multisig"
|
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
|
)
|
|
|
|
var cdc = amino.NewCodec()
|
|
|
|
// nameTable is used to map public key concrete types back
|
|
// to their registered amino names. This should eventually be handled
|
|
// by amino. Example usage:
|
|
// nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
|
|
var nameTable = make(map[reflect.Type]string, 3)
|
|
|
|
func init() {
|
|
// NOTE: It's important that there be no conflicts here,
|
|
// as that would change the canonical representations,
|
|
// and therefore change the address.
|
|
// TODO: Remove above note when
|
|
// https://github.com/tendermint/go-amino/issues/9
|
|
// is resolved
|
|
RegisterAmino(cdc)
|
|
|
|
// TODO: Have amino provide a way to go from concrete struct to route directly.
|
|
// Its currently a private API
|
|
nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
|
|
nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
|
|
nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
|
|
}
|
|
|
|
// PubkeyAminoName returns the amino route of a pubkey
|
|
// cdc is currently passed in, as eventually this will not be using
|
|
// a package level codec.
|
|
func PubkeyAminoName(cdc *amino.Codec, key crypto.PubKey) (string, bool) {
|
|
route, found := nameTable[reflect.TypeOf(key)]
|
|
return route, found
|
|
}
|
|
|
|
// RegisterAmino registers all crypto related types in the given (amino) codec.
|
|
func RegisterAmino(cdc *amino.Codec) {
|
|
// These are all written here instead of
|
|
cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
|
|
cdc.RegisterConcrete(ed25519.PubKeyEd25519{},
|
|
ed25519.PubKeyAminoName, nil)
|
|
cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{},
|
|
secp256k1.PubKeyAminoName, nil)
|
|
cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{},
|
|
multisig.PubKeyMultisigThresholdAminoRoute, nil)
|
|
|
|
cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
|
|
cdc.RegisterConcrete(ed25519.PrivKeyEd25519{},
|
|
ed25519.PrivKeyAminoName, nil)
|
|
cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{},
|
|
secp256k1.PrivKeyAminoName, nil)
|
|
}
|
|
|
|
// RegisterKeyType registers an external key type to allow decoding it from bytes
|
|
func RegisterKeyType(o interface{}, name string) {
|
|
cdc.RegisterConcrete(o, name, nil)
|
|
nameTable[reflect.TypeOf(o)] = name
|
|
}
|
|
|
|
// PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey
|
|
func PrivKeyFromBytes(privKeyBytes []byte) (privKey crypto.PrivKey, err error) {
|
|
err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
|
|
return
|
|
}
|
|
|
|
// PubKeyFromBytes unmarshals public key bytes and returns a PubKey
|
|
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey crypto.PubKey, err error) {
|
|
err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
|
|
return
|
|
}
|