github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/address_test.go (about) 1 package types_test 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "math/rand" 7 "strings" 8 "testing" 9 10 evmtypes "github.com/fibonacci-chain/fbc/x/evm/types" 11 12 "github.com/stretchr/testify/require" 13 yaml "gopkg.in/yaml.v2" 14 15 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519" 16 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1" 17 18 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 19 ) 20 21 var invalidStrs = []string{ 22 "hello, world!", 23 "AAA", 24 types.Bech32PrefixAccAddr + "AB0C", 25 types.Bech32PrefixAccPub + "1234", 26 types.Bech32PrefixValAddr + "5678", 27 types.Bech32PrefixValPub + "BBAB", 28 types.Bech32PrefixConsAddr + "FF04", 29 types.Bech32PrefixConsPub + "6789", 30 } 31 32 func testMarshal(t *testing.T, original interface{}, res interface{}, marshal func() ([]byte, error), unmarshal func([]byte) error) { 33 bz, err := marshal() 34 require.Nil(t, err) 35 err = unmarshal(bz) 36 require.Nil(t, err) 37 require.Equal(t, original, res) 38 } 39 40 func TestEmptyAddresses(t *testing.T) { 41 require.Equal(t, (types.AccAddress{}).String(), "") 42 require.Equal(t, (types.ValAddress{}).String(), "") 43 require.Equal(t, (types.ConsAddress{}).String(), "") 44 45 accAddr, err := types.AccAddressFromBech32("") 46 require.True(t, accAddr.Empty()) 47 require.Error(t, err) 48 49 valAddr, err := types.ValAddressFromBech32("") 50 require.True(t, valAddr.Empty()) 51 require.Error(t, err) 52 53 consAddr, err := types.ConsAddressFromBech32("") 54 require.True(t, consAddr.Empty()) 55 require.Error(t, err) 56 } 57 58 func TestRandBech32PubkeyConsistency(t *testing.T) { 59 var pub ed25519.PubKeyEd25519 60 61 for i := 0; i < 1000; i++ { 62 rand.Read(pub[:]) 63 64 mustBech32AccPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeAccPub, pub) 65 bech32AccPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeAccPub, pub) 66 require.Nil(t, err) 67 require.Equal(t, bech32AccPub, mustBech32AccPub) 68 69 mustBech32ValPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeValPub, pub) 70 bech32ValPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeValPub, pub) 71 require.Nil(t, err) 72 require.Equal(t, bech32ValPub, mustBech32ValPub) 73 74 mustBech32ConsPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeConsPub, pub) 75 bech32ConsPub, err := types.Bech32ifyPubKey(types.Bech32PubKeyTypeConsPub, pub) 76 require.Nil(t, err) 77 require.Equal(t, bech32ConsPub, mustBech32ConsPub) 78 79 mustAccPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeAccPub, bech32AccPub) 80 accPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeAccPub, bech32AccPub) 81 require.Nil(t, err) 82 require.Equal(t, accPub, mustAccPub) 83 84 mustValPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeValPub, bech32ValPub) 85 valPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeValPub, bech32ValPub) 86 require.Nil(t, err) 87 require.Equal(t, valPub, mustValPub) 88 89 mustConsPub := types.MustGetPubKeyFromBech32(types.Bech32PubKeyTypeConsPub, bech32ConsPub) 90 consPub, err := types.GetPubKeyFromBech32(types.Bech32PubKeyTypeConsPub, bech32ConsPub) 91 require.Nil(t, err) 92 require.Equal(t, consPub, mustConsPub) 93 94 require.Equal(t, valPub, accPub) 95 require.Equal(t, valPub, consPub) 96 } 97 } 98 99 func TestYAMLMarshalers(t *testing.T) { 100 addr := secp256k1.GenPrivKey().PubKey().Address() 101 102 acc := types.AccAddress(addr) 103 val := types.ValAddress(addr) 104 cons := types.ConsAddress(addr) 105 106 got, _ := yaml.Marshal(&acc) 107 require.Equal(t, acc.String()+"\n", string(got)) 108 109 got, _ = yaml.Marshal(&val) 110 require.Equal(t, val.String()+"\n", string(got)) 111 112 got, _ = yaml.Marshal(&cons) 113 require.Equal(t, cons.String()+"\n", string(got)) 114 } 115 116 func TestRandBech32AccAddrConsistency(t *testing.T) { 117 var pub ed25519.PubKeyEd25519 118 119 for i := 0; i < 1000; i++ { 120 rand.Read(pub[:]) 121 122 acc := types.AccAddress(pub.Address()) 123 res := types.AccAddress{} 124 125 testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 126 testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) 127 128 str := acc.String() 129 res, err := types.AccAddressFromBech32(str) 130 require.Nil(t, err) 131 require.Equal(t, acc, res) 132 133 str = hex.EncodeToString(acc) 134 res, err = types.AccAddressFromHex(str) 135 require.Nil(t, err) 136 require.Equal(t, acc, res) 137 } 138 139 for _, str := range invalidStrs { 140 _, err := types.AccAddressFromHex(str) 141 require.NotNil(t, err) 142 143 _, err = types.AccAddressFromBech32(str) 144 require.NotNil(t, err) 145 146 err = (*types.AccAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 147 require.NotNil(t, err) 148 } 149 } 150 151 func TestValAddr(t *testing.T) { 152 var pub ed25519.PubKeyEd25519 153 154 for i := 0; i < 20; i++ { 155 rand.Read(pub[:]) 156 157 acc := types.ValAddress(pub.Address()) 158 res := types.ValAddress{} 159 160 testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 161 testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) 162 163 str := acc.String() 164 res, err := types.ValAddressFromBech32(str) 165 require.Nil(t, err) 166 require.Equal(t, acc, res) 167 168 str = hex.EncodeToString(acc) 169 res, err = types.ValAddressFromHex(str) 170 require.Nil(t, err) 171 require.Equal(t, acc, res) 172 } 173 174 for _, str := range invalidStrs { 175 _, err := types.ValAddressFromHex(str) 176 require.NotNil(t, err) 177 178 _, err = types.ValAddressFromBech32(str) 179 require.NotNil(t, err) 180 181 err = (*types.ValAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 182 require.NotNil(t, err) 183 } 184 } 185 186 func TestConsAddress(t *testing.T) { 187 var pub ed25519.PubKeyEd25519 188 189 for i := 0; i < 20; i++ { 190 rand.Read(pub[:]) 191 192 acc := types.ConsAddress(pub.Address()) 193 res := types.ConsAddress{} 194 195 testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 196 testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) 197 198 str := acc.String() 199 res, err := types.ConsAddressFromBech32(str) 200 require.Nil(t, err) 201 require.Equal(t, acc, res) 202 203 str = hex.EncodeToString(acc) 204 res, err = types.ConsAddressFromHex(str) 205 require.Nil(t, err) 206 require.Equal(t, acc, res) 207 } 208 209 for _, str := range invalidStrs { 210 _, err := types.ConsAddressFromHex(str) 211 require.NotNil(t, err) 212 213 _, err = types.ConsAddressFromBech32(str) 214 require.NotNil(t, err) 215 216 err = (*types.ConsAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 217 require.NotNil(t, err) 218 } 219 } 220 221 const letterBytes = "abcdefghijklmnopqrstuvwxyz" 222 223 func RandString(n int) string { 224 b := make([]byte, n) 225 for i := range b { 226 b[i] = letterBytes[rand.Intn(len(letterBytes))] 227 } 228 return string(b) 229 } 230 231 func TestConfiguredPrefix(t *testing.T) { 232 var pub ed25519.PubKeyEd25519 233 for length := 1; length < 10; length++ { 234 for times := 1; times < 20; times++ { 235 rand.Read(pub[:]) 236 // Test if randomly generated prefix of a given length works 237 prefix := RandString(length) 238 239 // Assuming that GetConfig is not sealed. 240 config := types.GetConfig() 241 config.SetBech32PrefixForAccount( 242 prefix+types.PrefixAccount, 243 prefix+types.PrefixPublic) 244 245 acc := types.AccAddress(pub.Address()) 246 require.True(t, strings.HasPrefix( 247 acc.String(), 248 prefix+types.PrefixAccount), acc.String()) 249 250 bech32Pub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeAccPub, pub) 251 require.True(t, strings.HasPrefix( 252 bech32Pub, 253 prefix+types.PrefixPublic)) 254 255 config.SetBech32PrefixForValidator( 256 prefix+types.PrefixValidator+types.PrefixAddress, 257 prefix+types.PrefixValidator+types.PrefixPublic) 258 259 val := types.ValAddress(pub.Address()) 260 require.True(t, strings.HasPrefix( 261 val.String(), 262 prefix+types.PrefixValidator+types.PrefixAddress)) 263 264 bech32ValPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeValPub, pub) 265 require.True(t, strings.HasPrefix( 266 bech32ValPub, 267 prefix+types.PrefixValidator+types.PrefixPublic)) 268 269 config.SetBech32PrefixForConsensusNode( 270 prefix+types.PrefixConsensus+types.PrefixAddress, 271 prefix+types.PrefixConsensus+types.PrefixPublic) 272 273 cons := types.ConsAddress(pub.Address()) 274 require.True(t, strings.HasPrefix( 275 cons.String(), 276 prefix+types.PrefixConsensus+types.PrefixAddress)) 277 278 bech32ConsPub := types.MustBech32ifyPubKey(types.Bech32PubKeyTypeConsPub, pub) 279 require.True(t, strings.HasPrefix( 280 bech32ConsPub, 281 prefix+types.PrefixConsensus+types.PrefixPublic)) 282 } 283 } 284 } 285 286 func TestAddressInterface(t *testing.T) { 287 var pub ed25519.PubKeyEd25519 288 rand.Read(pub[:]) 289 290 addrs := []types.Address{ 291 types.ConsAddress(pub.Address()), 292 types.ValAddress(pub.Address()), 293 types.AccAddress(pub.Address()), 294 } 295 296 for _, addr := range addrs { 297 switch addr := addr.(type) { 298 case types.AccAddress: 299 _, err := types.AccAddressFromBech32(addr.String()) 300 require.Nil(t, err) 301 case types.ValAddress: 302 _, err := types.ValAddressFromBech32(addr.String()) 303 require.Nil(t, err) 304 case types.ConsAddress: 305 _, err := types.ConsAddressFromBech32(addr.String()) 306 require.Nil(t, err) 307 default: 308 t.Fail() 309 } 310 } 311 312 } 313 314 func TestCustomAddressVerifier(t *testing.T) { 315 // Create a 10 byte address 316 addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 317 accBech := types.AccAddress(addr).String() 318 valBech := types.ValAddress(addr).String() 319 consBech := types.ConsAddress(addr).String() 320 // Verifiy that the default logic rejects this 10 byte address 321 err := types.VerifyAddressFormat(addr) 322 require.NotNil(t, err) 323 _, err = types.AccAddressFromBech32(accBech) 324 require.NotNil(t, err) 325 _, err = types.ValAddressFromBech32(valBech) 326 require.NotNil(t, err) 327 _, err = types.ConsAddressFromBech32(consBech) 328 require.NotNil(t, err) 329 330 // Set a custom address verifier that accepts 10 or 20 byte addresses 331 types.GetConfig().SetAddressVerifier(func(bz []byte) error { 332 n := len(bz) 333 if n == 10 || n == types.AddrLen { 334 return nil 335 } 336 return fmt.Errorf("incorrect address length %d", n) 337 }) 338 339 // Verifiy that the custom logic accepts this 10 byte address 340 err = types.VerifyAddressFormat(addr) 341 require.Nil(t, err) 342 _, err = types.AccAddressFromBech32(accBech) 343 require.Nil(t, err) 344 _, err = types.ValAddressFromBech32(valBech) 345 require.Nil(t, err) 346 _, err = types.ConsAddressFromBech32(consBech) 347 require.Nil(t, err) 348 } 349 350 func BenchmarkAccAddress_Bech32String(b *testing.B) { 351 acc := types.AccAddress(evmtypes.GenerateEthAddress().Bytes()) 352 prefix := types.GetConfig().GetBech32AccountAddrPrefix() 353 b.ResetTimer() 354 b.Run("Bench32 origin", func(b *testing.B) { 355 b.ReportAllocs() 356 for i := 0; i < b.N; i++ { 357 _ = acc.Bech32String(prefix) 358 } 359 }) 360 b.Run("Bench32 Optimized", func(b *testing.B) { 361 b.ReportAllocs() 362 for i := 0; i < b.N; i++ { 363 _ = acc.Bech32StringOptimized(prefix) 364 } 365 }) 366 require.EqualValues(b, acc.Bech32String(prefix), acc.Bech32StringOptimized(prefix)) 367 } 368 369 func BenchmarkAccAddressFromBech32String(b *testing.B) { 370 buffer := make([]byte, 32) 371 copy(buffer, []byte("test")) 372 acc := types.AccAddress(buffer) 373 prefix := types.GetConfig().GetBech32AccountAddrPrefix() 374 sender := acc.Bech32String(prefix) 375 b.ResetTimer() 376 b.Run("AccAddressFromBech32", func(b *testing.B) { 377 b.ReportAllocs() 378 for i := 0; i < b.N; i++ { 379 _, err := types.AccAddressFromBech32(sender) 380 require.NoError(b, err) 381 } 382 }) 383 }