mirror of
https://github.com/tendermint/tendermint.git
synced 2026-03-26 19:45:03 +00:00
crypto/amino: add function to modify key codec (#4112)
## 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
This commit is contained in:
committed by
Anton Kaliaev
parent
79500277ae
commit
7cd55a7733
@@ -29,6 +29,7 @@ program](https://hackerone.com/tendermint).
|
||||
- [p2p] [\#3991](https://github.com/tendermint/tendermint/issues/3991) Log "has been established or dialed" as debug log instead of Error for connected peers (@whunmr)
|
||||
- [rpc] [\#4077](https://github.com/tendermint/tendermint/pull/4077) Added support for `EXISTS` clause to the Websocket query interface.
|
||||
- [privval] Add `SignerDialerEndpointRetryWaitInterval` option (@cosmostuba)
|
||||
- [crypto] Add `RegisterKeyType` to amino to allow external key types registration (@austinabell)
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
|
||||
@@ -60,11 +60,19 @@ func RegisterAmino(cdc *amino.Codec) {
|
||||
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
|
||||
|
||||
@@ -2,10 +2,13 @@ package cryptoAmino
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/multisig"
|
||||
@@ -147,3 +150,75 @@ func TestPubkeyAminoName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ crypto.PrivKey = testPriv{}
|
||||
var _ crypto.PubKey = testPub{}
|
||||
var testCdc = amino.NewCodec()
|
||||
|
||||
type testPriv []byte
|
||||
|
||||
func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
|
||||
func (privkey testPriv) Bytes() []byte {
|
||||
return testCdc.MustMarshalBinaryBare(privkey)
|
||||
}
|
||||
func (privkey testPriv) Sign(msg []byte) ([]byte, error) { return []byte{}, nil }
|
||||
func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
|
||||
|
||||
type testPub []byte
|
||||
|
||||
func (key testPub) Address() crypto.Address { return crypto.Address{} }
|
||||
func (key testPub) Bytes() []byte {
|
||||
return testCdc.MustMarshalBinaryBare(key)
|
||||
}
|
||||
func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
|
||||
func (key testPub) Equals(other crypto.PubKey) bool { return true }
|
||||
|
||||
var (
|
||||
privAminoName = "registerTest/Priv"
|
||||
pubAminoName = "registerTest/Pub"
|
||||
)
|
||||
|
||||
func TestRegisterKeyType(t *testing.T) {
|
||||
RegisterAmino(testCdc)
|
||||
testCdc.RegisterConcrete(testPriv{}, privAminoName, nil)
|
||||
testCdc.RegisterConcrete(testPub{}, pubAminoName, nil)
|
||||
|
||||
pub := testPub{0x1}
|
||||
priv := testPriv{0x2}
|
||||
|
||||
// Check to make sure key cannot be decoded before registering
|
||||
_, err := PrivKeyFromBytes(priv.Bytes())
|
||||
require.Error(t, err)
|
||||
_, err = PubKeyFromBytes(pub.Bytes())
|
||||
require.Error(t, err)
|
||||
|
||||
// Check that name is not registered
|
||||
_, found := PubkeyAminoName(testCdc, pub)
|
||||
require.False(t, found)
|
||||
|
||||
// Register key types
|
||||
RegisterKeyType(testPriv{}, privAminoName)
|
||||
RegisterKeyType(testPub{}, pubAminoName)
|
||||
|
||||
// Name should exist after registering
|
||||
name, found := PubkeyAminoName(testCdc, pub)
|
||||
require.True(t, found)
|
||||
require.Equal(t, name, pubAminoName)
|
||||
|
||||
// Decode keys using the encoded bytes from encoding with the other codec
|
||||
decodedPriv, err := PrivKeyFromBytes(priv.Bytes())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv, decodedPriv)
|
||||
|
||||
decodedPub, err := PubKeyFromBytes(pub.Bytes())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pub, decodedPub)
|
||||
|
||||
// Reset module codec after testing
|
||||
cdc = amino.NewCodec()
|
||||
nameTable = make(map[reflect.Type]string, 3)
|
||||
RegisterAmino(cdc)
|
||||
nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
|
||||
nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
|
||||
nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user