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 }