github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/tendermint/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/tendermint/go-amino"
    12  
    13  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    14  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    15  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig"
    16  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    17  	"github.com/fibonacci-chain/fbc/libs/tendermint/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  //
    57  //nolint:govet
    58  func ExamplePrintRegisteredTypes() {
    59  	cdc.PrintTypes(os.Stdout)
    60  	// Output: | Type | Name | Prefix | Length | Notes |
    61  	//| ---- | ---- | ------ | ----- | ------ |
    62  	//| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 |  |
    63  	//| PubKeySr25519 | tendermint/PubKeySr25519 | 0x0DFB1005 | 0x20 |  |
    64  	//| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 |  |
    65  	//| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable |  |
    66  	//| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 |  |
    67  	//| PrivKeySr25519 | tendermint/PrivKeySr25519 | 0x2F82D78B | 0x20 |  |
    68  	//| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 |  |
    69  }
    70  
    71  func TestKeyEncodings(t *testing.T) {
    72  	cases := []struct {
    73  		privKey                    crypto.PrivKey
    74  		privSize, pubSize, sigSize int // binary sizes
    75  	}{
    76  		{
    77  			privKey:  ed25519.GenPrivKey(),
    78  			privSize: 69,
    79  			pubSize:  37,
    80  			sigSize:  65,
    81  		},
    82  		{
    83  			privKey:  sr25519.GenPrivKey(),
    84  			privSize: 37,
    85  			pubSize:  37,
    86  			sigSize:  65,
    87  		},
    88  		{
    89  			privKey:  secp256k1.GenPrivKey(),
    90  			privSize: 37,
    91  			pubSize:  38,
    92  			sigSize:  65,
    93  		},
    94  	}
    95  
    96  	for tcIndex, tc := range cases {
    97  
    98  		// Check (de/en)codings of PrivKeys.
    99  		var priv2, priv3 crypto.PrivKey
   100  		checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
   101  		assert.EqualValues(t, tc.privKey, priv2, "tc #%d", tcIndex)
   102  		checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
   103  		assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex)
   104  
   105  		// Check (de/en)codings of Signatures.
   106  		var sig1, sig2 []byte
   107  		sig1, err := tc.privKey.Sign([]byte("something"))
   108  		assert.NoError(t, err, "tc #%d", tcIndex)
   109  		checkAminoBinary(t, sig1, &sig2, tc.sigSize)
   110  		assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex)
   111  
   112  		// Check (de/en)codings of PubKeys.
   113  		pubKey := tc.privKey.PubKey()
   114  		var pub2, pub3 crypto.PubKey
   115  		checkAminoBinary(t, pubKey, &pub2, tc.pubSize)
   116  		assert.EqualValues(t, pubKey, pub2, "tc #%d", tcIndex)
   117  		checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
   118  		assert.EqualValues(t, pubKey, pub3, "tc #%d", tcIndex)
   119  	}
   120  }
   121  
   122  func TestNilEncodings(t *testing.T) {
   123  
   124  	// Check nil Signature.
   125  	var a, b []byte
   126  	checkAminoJSON(t, &a, &b, true)
   127  	assert.EqualValues(t, a, b)
   128  
   129  	// Check nil PubKey.
   130  	var c, d crypto.PubKey
   131  	checkAminoJSON(t, &c, &d, true)
   132  	assert.EqualValues(t, c, d)
   133  
   134  	// Check nil PrivKey.
   135  	var e, f crypto.PrivKey
   136  	checkAminoJSON(t, &e, &f, true)
   137  	assert.EqualValues(t, e, f)
   138  }
   139  
   140  func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
   141  	pk, err := PubKeyFromBytes([]byte("foo"))
   142  	require.NotNil(t, err)
   143  	require.Nil(t, pk)
   144  }
   145  
   146  func TestPubkeyAminoName(t *testing.T) {
   147  	tests := []struct {
   148  		key   crypto.PubKey
   149  		want  string
   150  		found bool
   151  	}{
   152  		{ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, true},
   153  		{sr25519.PubKeySr25519{}, sr25519.PubKeyAminoName, true},
   154  		{secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, true},
   155  		{multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, true},
   156  	}
   157  	for i, tc := range tests {
   158  		got, found := PubkeyAminoName(cdc, tc.key)
   159  		require.Equal(t, tc.found, found, "not equal on tc %d", i)
   160  		if tc.found {
   161  			require.Equal(t, tc.want, got, "not equal on tc %d", i)
   162  		}
   163  	}
   164  }
   165  
   166  var _ crypto.PrivKey = testPriv{}
   167  var _ crypto.PubKey = testPub{}
   168  var testCdc = amino.NewCodec()
   169  
   170  type testPriv []byte
   171  
   172  func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
   173  func (privkey testPriv) Bytes() []byte {
   174  	return testCdc.MustMarshalBinaryBare(privkey)
   175  }
   176  func (privkey testPriv) Sign(msg []byte) ([]byte, error)  { return []byte{}, nil }
   177  func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
   178  
   179  type testPub []byte
   180  
   181  func (key testPub) Address() crypto.Address { return crypto.Address{} }
   182  func (key testPub) Bytes() []byte {
   183  	return testCdc.MustMarshalBinaryBare(key)
   184  }
   185  func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
   186  func (key testPub) Equals(other crypto.PubKey) bool         { return true }
   187  
   188  var (
   189  	privAminoName = "registerTest/Priv"
   190  	pubAminoName  = "registerTest/Pub"
   191  )
   192  
   193  func TestRegisterKeyType(t *testing.T) {
   194  	RegisterAmino(testCdc)
   195  	testCdc.RegisterConcrete(testPriv{}, privAminoName, nil)
   196  	testCdc.RegisterConcrete(testPub{}, pubAminoName, nil)
   197  
   198  	pub := testPub{0x1}
   199  	priv := testPriv{0x2}
   200  
   201  	// Check to make sure key cannot be decoded before registering
   202  	_, err := PrivKeyFromBytes(priv.Bytes())
   203  	require.Error(t, err)
   204  	_, err = PubKeyFromBytes(pub.Bytes())
   205  	require.Error(t, err)
   206  
   207  	// Check that name is not registered
   208  	_, found := PubkeyAminoName(testCdc, pub)
   209  	require.False(t, found)
   210  
   211  	// Register key types
   212  	RegisterKeyType(testPriv{}, privAminoName)
   213  	RegisterKeyType(testPub{}, pubAminoName)
   214  
   215  	// Name should exist after registering
   216  	name, found := PubkeyAminoName(testCdc, pub)
   217  	require.True(t, found)
   218  	require.Equal(t, name, pubAminoName)
   219  
   220  	// Decode keys using the encoded bytes from encoding with the other codec
   221  	decodedPriv, err := PrivKeyFromBytes(priv.Bytes())
   222  	require.NoError(t, err)
   223  	require.Equal(t, priv, decodedPriv)
   224  
   225  	decodedPub, err := PubKeyFromBytes(pub.Bytes())
   226  	require.NoError(t, err)
   227  	require.Equal(t, pub, decodedPub)
   228  
   229  	// Reset module codec after testing
   230  	cdc = amino.NewCodec()
   231  	nameTable = make(map[reflect.Type]string, 3)
   232  	RegisterAmino(cdc)
   233  	nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
   234  	nameTable[reflect.TypeOf(sr25519.PubKeySr25519{})] = sr25519.PubKeyAminoName
   235  	nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
   236  	nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
   237  }
   238  
   239  func TestPubKeyAmino(t *testing.T) {
   240  	testCases := []crypto.PubKey{
   241  		ed25519.PubKeyEd25519{},
   242  		sr25519.PubKeySr25519{},
   243  		secp256k1.PubKeySecp256k1{},
   244  		multisig.PubKeyMultisigThreshold{},
   245  	}
   246  
   247  	for _, pubkey := range testCases {
   248  		bz, err := cdc.MarshalBinaryBare(pubkey)
   249  		require.NoError(t, err)
   250  
   251  		require.Equal(t, len(bz), PubKeyAminoSize(pubkey, cdc))
   252  
   253  		bz2, err := MarshalPubKeyToAmino(cdc, pubkey)
   254  		require.NoError(t, err)
   255  		require.EqualValues(t, bz, bz2)
   256  
   257  		var pubkey1 crypto.PubKey
   258  		err = cdc.UnmarshalBinaryBare(bz, &pubkey1)
   259  		require.NoError(t, err)
   260  
   261  		pubkey2, err := UnmarshalPubKeyFromAmino(cdc, bz)
   262  		require.NoError(t, err)
   263  
   264  		require.Equal(t, pubkey1, pubkey2)
   265  	}
   266  }