github.com/devwanda/aphelion-staking@v0.33.9/crypto/encoding/amino/encode_test.go (about)

     1  package cryptoamino
     2  
     3  import (
     4  	"os"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	amino "github.com/evdatsion/go-amino"
    12  
    13  	"github.com/devwanda/aphelion-staking/crypto"
    14  	"github.com/devwanda/aphelion-staking/crypto/ed25519"
    15  	"github.com/devwanda/aphelion-staking/crypto/multisig"
    16  	"github.com/devwanda/aphelion-staking/crypto/secp256k1"
    17  	"github.com/devwanda/aphelion-staking/crypto/sr25519"
    18  )
    19  
    20  type byter interface {
    21  	Bytes() []byte
    22  }
    23  
    24  func checkAminoBinary(t *testing.T, src, dst interface{}, size int) {
    25  	// Marshal to binary bytes.
    26  	bz, err := cdc.MarshalBinaryBare(src)
    27  	require.Nil(t, err, "%+v", err)
    28  	if byterSrc, ok := src.(byter); ok {
    29  		// Make sure this is compatible with current (Bytes()) encoding.
    30  		assert.Equal(t, byterSrc.Bytes(), bz, "Amino binary vs Bytes() mismatch")
    31  	}
    32  	// Make sure we have the expected length.
    33  	assert.Equal(t, size, len(bz), "Amino binary size mismatch")
    34  
    35  	// Unmarshal.
    36  	err = cdc.UnmarshalBinaryBare(bz, dst)
    37  	require.Nil(t, err, "%+v", err)
    38  }
    39  
    40  func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) {
    41  	// Marshal to JSON bytes.
    42  	js, err := cdc.MarshalJSON(src)
    43  	require.Nil(t, err, "%+v", err)
    44  	if isNil {
    45  		assert.Equal(t, string(js), `null`)
    46  	} else {
    47  		assert.Contains(t, string(js), `"type":`)
    48  		assert.Contains(t, string(js), `"value":`)
    49  	}
    50  	// Unmarshal.
    51  	err = cdc.UnmarshalJSON(js, dst)
    52  	require.Nil(t, err, "%+v", err)
    53  }
    54  
    55  // ExamplePrintRegisteredTypes refers to unknown identifier: PrintRegisteredTypes
    56  //nolint:govet
    57  func ExamplePrintRegisteredTypes() {
    58  	cdc.PrintTypes(os.Stdout)
    59  	// Output: | Type | Name | Prefix | Length | Notes |
    60  	//| ---- | ---- | ------ | ----- | ------ |
    61  	//| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 |  |
    62  	//| PubKeySr25519 | tendermint/PubKeySr25519 | 0x0DFB1005 | 0x20 |  |
    63  	//| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 |  |
    64  	//| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable |  |
    65  	//| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 |  |
    66  	//| PrivKeySr25519 | tendermint/PrivKeySr25519 | 0x2F82D78B | 0x20 |  |
    67  	//| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 |  |
    68  }
    69  
    70  func TestKeyEncodings(t *testing.T) {
    71  	cases := []struct {
    72  		privKey                    crypto.PrivKey
    73  		privSize, pubSize, sigSize int // binary sizes
    74  	}{
    75  		{
    76  			privKey:  ed25519.GenPrivKey(),
    77  			privSize: 69,
    78  			pubSize:  37,
    79  			sigSize:  65,
    80  		},
    81  		{
    82  			privKey:  sr25519.GenPrivKey(),
    83  			privSize: 37,
    84  			pubSize:  37,
    85  			sigSize:  65,
    86  		},
    87  		{
    88  			privKey:  secp256k1.GenPrivKey(),
    89  			privSize: 37,
    90  			pubSize:  38,
    91  			sigSize:  65,
    92  		},
    93  	}
    94  
    95  	for tcIndex, tc := range cases {
    96  
    97  		// Check (de/en)codings of PrivKeys.
    98  		var priv2, priv3 crypto.PrivKey
    99  		checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
   100  		assert.EqualValues(t, tc.privKey, priv2, "tc #%d", tcIndex)
   101  		checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
   102  		assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex)
   103  
   104  		// Check (de/en)codings of Signatures.
   105  		var sig1, sig2 []byte
   106  		sig1, err := tc.privKey.Sign([]byte("something"))
   107  		assert.NoError(t, err, "tc #%d", tcIndex)
   108  		checkAminoBinary(t, sig1, &sig2, tc.sigSize)
   109  		assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex)
   110  
   111  		// Check (de/en)codings of PubKeys.
   112  		pubKey := tc.privKey.PubKey()
   113  		var pub2, pub3 crypto.PubKey
   114  		checkAminoBinary(t, pubKey, &pub2, tc.pubSize)
   115  		assert.EqualValues(t, pubKey, pub2, "tc #%d", tcIndex)
   116  		checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
   117  		assert.EqualValues(t, pubKey, pub3, "tc #%d", tcIndex)
   118  	}
   119  }
   120  
   121  func TestNilEncodings(t *testing.T) {
   122  
   123  	// Check nil Signature.
   124  	var a, b []byte
   125  	checkAminoJSON(t, &a, &b, true)
   126  	assert.EqualValues(t, a, b)
   127  
   128  	// Check nil PubKey.
   129  	var c, d crypto.PubKey
   130  	checkAminoJSON(t, &c, &d, true)
   131  	assert.EqualValues(t, c, d)
   132  
   133  	// Check nil PrivKey.
   134  	var e, f crypto.PrivKey
   135  	checkAminoJSON(t, &e, &f, true)
   136  	assert.EqualValues(t, e, f)
   137  }
   138  
   139  func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
   140  	pk, err := PubKeyFromBytes([]byte("foo"))
   141  	require.NotNil(t, err)
   142  	require.Nil(t, pk)
   143  }
   144  
   145  func TestPubkeyAminoName(t *testing.T) {
   146  	tests := []struct {
   147  		key   crypto.PubKey
   148  		want  string
   149  		found bool
   150  	}{
   151  		{ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, true},
   152  		{sr25519.PubKeySr25519{}, sr25519.PubKeyAminoName, true},
   153  		{secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, true},
   154  		{multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, true},
   155  	}
   156  	for i, tc := range tests {
   157  		got, found := PubkeyAminoName(cdc, tc.key)
   158  		require.Equal(t, tc.found, found, "not equal on tc %d", i)
   159  		if tc.found {
   160  			require.Equal(t, tc.want, got, "not equal on tc %d", i)
   161  		}
   162  	}
   163  }
   164  
   165  var _ crypto.PrivKey = testPriv{}
   166  var _ crypto.PubKey = testPub{}
   167  var testCdc = amino.NewCodec()
   168  
   169  type testPriv []byte
   170  
   171  func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
   172  func (privkey testPriv) Bytes() []byte {
   173  	return testCdc.MustMarshalBinaryBare(privkey)
   174  }
   175  func (privkey testPriv) Sign(msg []byte) ([]byte, error)  { return []byte{}, nil }
   176  func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
   177  
   178  type testPub []byte
   179  
   180  func (key testPub) Address() crypto.Address { return crypto.Address{} }
   181  func (key testPub) Bytes() []byte {
   182  	return testCdc.MustMarshalBinaryBare(key)
   183  }
   184  func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
   185  func (key testPub) Equals(other crypto.PubKey) bool         { return true }
   186  
   187  var (
   188  	privAminoName = "registerTest/Priv"
   189  	pubAminoName  = "registerTest/Pub"
   190  )
   191  
   192  func TestRegisterKeyType(t *testing.T) {
   193  	RegisterAmino(testCdc)
   194  	testCdc.RegisterConcrete(testPriv{}, privAminoName, nil)
   195  	testCdc.RegisterConcrete(testPub{}, pubAminoName, nil)
   196  
   197  	pub := testPub{0x1}
   198  	priv := testPriv{0x2}
   199  
   200  	// Check to make sure key cannot be decoded before registering
   201  	_, err := PrivKeyFromBytes(priv.Bytes())
   202  	require.Error(t, err)
   203  	_, err = PubKeyFromBytes(pub.Bytes())
   204  	require.Error(t, err)
   205  
   206  	// Check that name is not registered
   207  	_, found := PubkeyAminoName(testCdc, pub)
   208  	require.False(t, found)
   209  
   210  	// Register key types
   211  	RegisterKeyType(testPriv{}, privAminoName)
   212  	RegisterKeyType(testPub{}, pubAminoName)
   213  
   214  	// Name should exist after registering
   215  	name, found := PubkeyAminoName(testCdc, pub)
   216  	require.True(t, found)
   217  	require.Equal(t, name, pubAminoName)
   218  
   219  	// Decode keys using the encoded bytes from encoding with the other codec
   220  	decodedPriv, err := PrivKeyFromBytes(priv.Bytes())
   221  	require.NoError(t, err)
   222  	require.Equal(t, priv, decodedPriv)
   223  
   224  	decodedPub, err := PubKeyFromBytes(pub.Bytes())
   225  	require.NoError(t, err)
   226  	require.Equal(t, pub, decodedPub)
   227  
   228  	// Reset module codec after testing
   229  	cdc = amino.NewCodec()
   230  	nameTable = make(map[reflect.Type]string, 3)
   231  	RegisterAmino(cdc)
   232  	nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
   233  	nameTable[reflect.TypeOf(sr25519.PubKeySr25519{})] = sr25519.PubKeyAminoName
   234  	nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
   235  	nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
   236  }