github.com/Finschia/finschia-sdk@v0.48.1/types/address_test.go (about) 1 package types_test 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "fmt" 7 "math/rand" 8 "strings" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 "github.com/stretchr/testify/suite" 13 "gopkg.in/yaml.v2" 14 15 "github.com/Finschia/finschia-sdk/crypto/keys/ed25519" 16 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 17 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 18 "github.com/Finschia/finschia-sdk/types" 19 "github.com/Finschia/finschia-sdk/types/bech32/legacybech32" 20 ) 21 22 type addressTestSuite struct { 23 suite.Suite 24 } 25 26 func TestAddressTestSuite(t *testing.T) { 27 suite.Run(t, new(addressTestSuite)) 28 } 29 30 func (s *addressTestSuite) SetupSuite() { 31 s.T().Parallel() 32 } 33 34 var invalidStrs = []string{ 35 "hello, world!", 36 "0xAA", 37 "AAA", 38 types.Bech32PrefixAccAddr + "AB0C", 39 types.Bech32PrefixAccPub + "1234", 40 types.Bech32PrefixValAddr + "5678", 41 types.Bech32PrefixValPub + "BBAB", 42 types.Bech32PrefixConsAddr + "FF04", 43 types.Bech32PrefixConsPub + "6789", 44 } 45 46 func (s *addressTestSuite) testMarshal(original interface{}, res interface{}, marshal func() ([]byte, error), unmarshal func([]byte) error) { 47 bz, err := marshal() 48 s.Require().Nil(err) 49 s.Require().Nil(unmarshal(bz)) 50 s.Require().Equal(original, res) 51 } 52 53 func (s *addressTestSuite) TestEmptyAddresses() { 54 s.T().Parallel() 55 s.Require().Equal((types.AccAddress{}).String(), "") 56 s.Require().Equal((types.ValAddress{}).String(), "") 57 s.Require().Equal((types.ConsAddress{}).String(), "") 58 59 accAddr, err := types.AccAddressFromBech32("") 60 s.Require().True(accAddr.Empty()) 61 s.Require().Error(err) 62 63 valAddr, err := types.ValAddressFromBech32("") 64 s.Require().True(valAddr.Empty()) 65 s.Require().Error(err) 66 67 consAddr, err := types.ConsAddressFromBech32("") 68 s.Require().True(consAddr.Empty()) 69 s.Require().Error(err) 70 } 71 72 func (s *addressTestSuite) TestYAMLMarshalers() { 73 addr := secp256k1.GenPrivKey().PubKey().Address() 74 75 acc := types.AccAddress(addr) 76 val := types.ValAddress(addr) 77 cons := types.ConsAddress(addr) 78 79 got, _ := yaml.Marshal(&acc) 80 s.Require().Equal(acc.String()+"\n", string(got)) 81 82 got, _ = yaml.Marshal(&val) 83 s.Require().Equal(val.String()+"\n", string(got)) 84 85 got, _ = yaml.Marshal(&cons) 86 s.Require().Equal(cons.String()+"\n", string(got)) 87 } 88 89 func (s *addressTestSuite) TestRandBech32AccAddrConsistency() { 90 pubBz := make([]byte, ed25519.PubKeySize) 91 pub := &ed25519.PubKey{Key: pubBz} 92 93 for i := 0; i < 1000; i++ { 94 rand.Read(pub.Key) 95 96 acc := types.AccAddress(pub.Address()) 97 res := types.AccAddress{} 98 99 s.testMarshal(&acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 100 s.testMarshal(&acc, &res, acc.Marshal, (&res).Unmarshal) 101 102 str := acc.String() 103 res, err := types.AccAddressFromBech32(str) 104 s.Require().Nil(err) 105 s.Require().Equal(acc, res) 106 107 str = hex.EncodeToString(acc) 108 res, err = types.AccAddressFromHex(str) 109 s.Require().Nil(err) 110 s.Require().Equal(acc, res) 111 } 112 113 for _, str := range invalidStrs { 114 _, err := types.AccAddressFromHex(str) 115 s.Require().NotNil(err) 116 117 _, err = types.AccAddressFromBech32(str) 118 s.Require().NotNil(err) 119 120 err = (*types.AccAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 121 s.Require().NotNil(err) 122 } 123 124 _, err := types.AccAddressFromHex("") 125 s.Require().Equal("decoding Bech32 address failed: must provide an address", err.Error()) 126 } 127 128 func (s *addressTestSuite) TestValAddr() { 129 pubBz := make([]byte, ed25519.PubKeySize) 130 pub := &ed25519.PubKey{Key: pubBz} 131 132 for i := 0; i < 20; i++ { 133 rand.Read(pub.Key) 134 135 acc := types.ValAddress(pub.Address()) 136 res := types.ValAddress{} 137 138 s.testMarshal(&acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 139 s.testMarshal(&acc, &res, acc.Marshal, (&res).Unmarshal) 140 141 str := acc.String() 142 res, err := types.ValAddressFromBech32(str) 143 s.Require().Nil(err) 144 s.Require().Equal(acc, res) 145 146 str = hex.EncodeToString(acc) 147 res, err = types.ValAddressFromHex(str) 148 s.Require().Nil(err) 149 s.Require().Equal(acc, res) 150 151 } 152 153 for _, str := range invalidStrs { 154 _, err := types.ValAddressFromHex(str) 155 s.Require().NotNil(err) 156 157 _, err = types.ValAddressFromBech32(str) 158 s.Require().NotNil(err) 159 160 err = (*types.ValAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 161 s.Require().NotNil(err) 162 } 163 164 // test empty string 165 _, err := types.ValAddressFromHex("") 166 s.Require().Equal("decoding Bech32 address failed: must provide an address", err.Error()) 167 } 168 169 func (s *addressTestSuite) TestConsAddress() { 170 pubBz := make([]byte, ed25519.PubKeySize) 171 pub := &ed25519.PubKey{Key: pubBz} 172 173 for i := 0; i < 20; i++ { 174 rand.Read(pub.Key[:]) 175 176 acc := types.ConsAddress(pub.Address()) 177 res := types.ConsAddress{} 178 179 s.testMarshal(&acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) 180 s.testMarshal(&acc, &res, acc.Marshal, (&res).Unmarshal) 181 182 str := acc.String() 183 res, err := types.ConsAddressFromBech32(str) 184 s.Require().Nil(err) 185 s.Require().Equal(acc, res) 186 187 str = hex.EncodeToString(acc) 188 res, err = types.ConsAddressFromHex(str) 189 s.Require().Nil(err) 190 s.Require().Equal(acc, res) 191 } 192 193 for _, str := range invalidStrs { 194 _, err := types.ConsAddressFromHex(str) 195 s.Require().NotNil(err) 196 197 _, err = types.ConsAddressFromBech32(str) 198 s.Require().NotNil(err) 199 200 err = (*types.ConsAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) 201 s.Require().NotNil(err) 202 } 203 204 // test empty string 205 _, err := types.ConsAddressFromHex("") 206 s.Require().Equal("decoding Bech32 address failed: must provide an address", err.Error()) 207 } 208 209 const letterBytes = "abcdefghijklmnopqrstuvwxyz" 210 211 func RandString(n int) string { 212 b := make([]byte, n) 213 for i := range b { 214 b[i] = letterBytes[rand.Intn(len(letterBytes))] 215 } 216 return string(b) 217 } 218 219 func (s *addressTestSuite) TestConfiguredPrefix() { 220 pubBz := make([]byte, ed25519.PubKeySize) 221 pub := &ed25519.PubKey{Key: pubBz} 222 for length := 1; length < 10; length++ { 223 for times := 1; times < 20; times++ { 224 rand.Read(pub.Key[:]) 225 // Test if randomly generated prefix of a given length works 226 prefix := RandString(length) 227 228 // Assuming that GetConfig is not sealed. 229 config := types.GetConfig() 230 config.SetBech32PrefixForAccount( 231 prefix+types.PrefixAccount, 232 prefix+types.PrefixPublic) 233 234 acc := types.AccAddress(pub.Address()) 235 s.Require().True(strings.HasPrefix( 236 acc.String(), 237 prefix+types.PrefixAccount), acc.String()) 238 239 bech32Pub := legacybech32.MustMarshalPubKey(legacybech32.AccPK, pub) 240 s.Require().True(strings.HasPrefix( 241 bech32Pub, 242 prefix+types.PrefixPublic)) 243 244 config.SetBech32PrefixForValidator( 245 prefix+types.PrefixValidator+types.PrefixAddress, 246 prefix+types.PrefixValidator+types.PrefixPublic) 247 248 val := types.ValAddress(pub.Address()) 249 s.Require().True(strings.HasPrefix( 250 val.String(), 251 prefix+types.PrefixValidator+types.PrefixAddress)) 252 253 bech32ValPub := legacybech32.MustMarshalPubKey(legacybech32.ValPK, pub) 254 s.Require().True(strings.HasPrefix( 255 bech32ValPub, 256 prefix+types.PrefixValidator+types.PrefixPublic)) 257 258 config.SetBech32PrefixForConsensusNode( 259 prefix+types.PrefixConsensus+types.PrefixAddress, 260 prefix+types.PrefixConsensus+types.PrefixPublic) 261 262 cons := types.ConsAddress(pub.Address()) 263 s.Require().True(strings.HasPrefix( 264 cons.String(), 265 prefix+types.PrefixConsensus+types.PrefixAddress)) 266 267 bech32ConsPub := legacybech32.MustMarshalPubKey(legacybech32.ConsPK, pub) 268 s.Require().True(strings.HasPrefix( 269 bech32ConsPub, 270 prefix+types.PrefixConsensus+types.PrefixPublic)) 271 } 272 } 273 } 274 275 func (s *addressTestSuite) TestAddressInterface() { 276 pubBz := make([]byte, ed25519.PubKeySize) 277 pub := &ed25519.PubKey{Key: pubBz} 278 rand.Read(pub.Key) 279 280 addrs := []types.Address{ 281 types.ConsAddress(pub.Address()), 282 types.ValAddress(pub.Address()), 283 types.AccAddress(pub.Address()), 284 } 285 286 for _, addr := range addrs { 287 switch addr := addr.(type) { 288 case types.AccAddress: 289 _, err := types.AccAddressFromBech32(addr.String()) 290 s.Require().Nil(err) 291 case types.ValAddress: 292 _, err := types.ValAddressFromBech32(addr.String()) 293 s.Require().Nil(err) 294 case types.ConsAddress: 295 _, err := types.ConsAddressFromBech32(addr.String()) 296 s.Require().Nil(err) 297 default: 298 s.T().Fail() 299 } 300 } 301 } 302 303 func (s *addressTestSuite) TestVerifyAddressFormat() { 304 addr0 := make([]byte, 0) 305 addr5 := make([]byte, 5) 306 addr20 := make([]byte, 20) 307 addr32 := make([]byte, 32) 308 addr256 := make([]byte, 256) 309 310 err := types.VerifyAddressFormat(addr0) 311 s.Require().EqualError(err, "addresses cannot be empty: unknown address") 312 err = types.VerifyAddressFormat(addr5) 313 s.Require().NoError(err) 314 err = types.VerifyAddressFormat(addr20) 315 s.Require().NoError(err) 316 err = types.VerifyAddressFormat(addr32) 317 s.Require().NoError(err) 318 err = types.VerifyAddressFormat(addr256) 319 s.Require().EqualError(err, "address max length is 255, got 256: unknown address") 320 } 321 322 func (s *addressTestSuite) TestCustomAddressVerifier() { 323 // Create a 10 byte address 324 addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 325 accBech := types.AccAddress(addr).String() 326 valBech := types.ValAddress(addr).String() 327 consBech := types.ConsAddress(addr).String() 328 // Verify that the default logic doesn't reject this 10 byte address 329 // The default verifier is nil, we're only checking address length is 330 // between 1-255 bytes. 331 err := types.VerifyAddressFormat(addr) 332 s.Require().Nil(err) 333 _, err = types.AccAddressFromBech32(accBech) 334 s.Require().Nil(err) 335 _, err = types.ValAddressFromBech32(valBech) 336 s.Require().Nil(err) 337 _, err = types.ConsAddressFromBech32(consBech) 338 s.Require().Nil(err) 339 340 // Set a custom address verifier only accepts 20 byte addresses 341 types.GetConfig().SetAddressVerifier(func(bz []byte) error { 342 n := len(bz) 343 if n == 20 { 344 return nil 345 } 346 return fmt.Errorf("incorrect address length %d", n) 347 }) 348 349 // Verifiy that the custom logic rejects this 10 byte address 350 err = types.VerifyAddressFormat(addr) 351 s.Require().NotNil(err) 352 _, err = types.AccAddressFromBech32(accBech) 353 s.Require().NotNil(err) 354 _, err = types.ValAddressFromBech32(valBech) 355 s.Require().NotNil(err) 356 _, err = types.ConsAddressFromBech32(consBech) 357 s.Require().NotNil(err) 358 359 // Reinitialize the global config to default address verifier (nil) 360 types.GetConfig().SetAddressVerifier(nil) 361 } 362 363 func (s *addressTestSuite) TestBech32ifyAddressBytes() { 364 addr10byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 365 addr20byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} 366 type args struct { 367 prefix string 368 bs []byte 369 } 370 tests := []struct { 371 name string 372 args args 373 want string 374 wantErr bool 375 }{ 376 {"empty address", args{"prefixa", []byte{}}, "", false}, 377 {"empty prefix", args{"", addr20byte}, "", true}, 378 {"10-byte address", args{"prefixa", addr10byte}, "prefixa1qqqsyqcyq5rqwzqf3953cc", false}, 379 {"10-byte address", args{"prefixb", addr10byte}, "prefixb1qqqsyqcyq5rqwzqf20xxpc", false}, 380 {"20-byte address", args{"prefixa", addr20byte}, "prefixa1qqqsyqcyq5rqwzqfpg9scrgwpugpzysn7hzdtn", false}, 381 {"20-byte address", args{"prefixb", addr20byte}, "prefixb1qqqsyqcyq5rqwzqfpg9scrgwpugpzysnrujsuw", false}, 382 } 383 for _, tt := range tests { 384 tt := tt 385 s.T().Run(tt.name, func(t *testing.T) { 386 got, err := types.Bech32ifyAddressBytes(tt.args.prefix, tt.args.bs) 387 if (err != nil) != tt.wantErr { 388 t.Errorf("Bech32ifyBytes() error = %v, wantErr %v", err, tt.wantErr) 389 return 390 } 391 require.Equal(t, tt.want, got) 392 }) 393 } 394 } 395 396 func (s *addressTestSuite) TestMustBech32ifyAddressBytes() { 397 addr10byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 398 addr20byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} 399 type args struct { 400 prefix string 401 bs []byte 402 } 403 tests := []struct { 404 name string 405 args args 406 want string 407 wantPanic bool 408 }{ 409 {"empty address", args{"prefixa", []byte{}}, "", false}, 410 {"empty prefix", args{"", addr20byte}, "", true}, 411 {"10-byte address", args{"prefixa", addr10byte}, "prefixa1qqqsyqcyq5rqwzqf3953cc", false}, 412 {"10-byte address", args{"prefixb", addr10byte}, "prefixb1qqqsyqcyq5rqwzqf20xxpc", false}, 413 {"20-byte address", args{"prefixa", addr20byte}, "prefixa1qqqsyqcyq5rqwzqfpg9scrgwpugpzysn7hzdtn", false}, 414 {"20-byte address", args{"prefixb", addr20byte}, "prefixb1qqqsyqcyq5rqwzqfpg9scrgwpugpzysnrujsuw", false}, 415 } 416 for _, tt := range tests { 417 tt := tt 418 s.T().Run(tt.name, func(t *testing.T) { 419 if tt.wantPanic { 420 require.Panics(t, func() { types.MustBech32ifyAddressBytes(tt.args.prefix, tt.args.bs) }) 421 return 422 } 423 require.Equal(t, tt.want, types.MustBech32ifyAddressBytes(tt.args.prefix, tt.args.bs)) 424 }) 425 } 426 } 427 428 func (s *addressTestSuite) TestAddressTypesEquals() { 429 addr1 := secp256k1.GenPrivKey().PubKey().Address() 430 accAddr1 := types.AccAddress(addr1) 431 consAddr1 := types.ConsAddress(addr1) 432 valAddr1 := types.ValAddress(addr1) 433 434 addr2 := secp256k1.GenPrivKey().PubKey().Address() 435 accAddr2 := types.AccAddress(addr2) 436 consAddr2 := types.ConsAddress(addr2) 437 valAddr2 := types.ValAddress(addr2) 438 439 // equality 440 s.Require().True(accAddr1.Equals(accAddr1)) 441 s.Require().True(consAddr1.Equals(consAddr1)) 442 s.Require().True(valAddr1.Equals(valAddr1)) 443 444 // emptiness 445 s.Require().True(types.AccAddress{}.Equals(types.AccAddress{})) 446 s.Require().True(types.AccAddress{}.Equals(types.AccAddress(nil))) 447 s.Require().True(types.AccAddress(nil).Equals(types.AccAddress{})) 448 s.Require().True(types.AccAddress(nil).Equals(types.AccAddress(nil))) 449 450 s.Require().True(types.ConsAddress{}.Equals(types.ConsAddress{})) 451 s.Require().True(types.ConsAddress{}.Equals(types.ConsAddress(nil))) 452 s.Require().True(types.ConsAddress(nil).Equals(types.ConsAddress{})) 453 s.Require().True(types.ConsAddress(nil).Equals(types.ConsAddress(nil))) 454 455 s.Require().True(types.ValAddress{}.Equals(types.ValAddress{})) 456 s.Require().True(types.ValAddress{}.Equals(types.ValAddress(nil))) 457 s.Require().True(types.ValAddress(nil).Equals(types.ValAddress{})) 458 s.Require().True(types.ValAddress(nil).Equals(types.ValAddress(nil))) 459 460 s.Require().False(accAddr1.Equals(accAddr2)) 461 s.Require().Equal(accAddr1.Equals(accAddr2), accAddr2.Equals(accAddr1)) 462 s.Require().False(consAddr1.Equals(consAddr2)) 463 s.Require().Equal(consAddr1.Equals(consAddr2), consAddr2.Equals(consAddr1)) 464 s.Require().False(valAddr1.Equals(valAddr2)) 465 s.Require().Equal(valAddr1.Equals(valAddr2), valAddr2.Equals(valAddr1)) 466 } 467 468 func (s *addressTestSuite) TestNilAddressTypesEmpty() { 469 s.Require().True(types.AccAddress(nil).Empty()) 470 s.Require().True(types.ConsAddress(nil).Empty()) 471 s.Require().True(types.ValAddress(nil).Empty()) 472 } 473 474 func (s *addressTestSuite) TestGetConsAddress() { 475 pk := secp256k1.GenPrivKey().PubKey() 476 s.Require().NotEqual(types.GetConsAddress(pk), pk.Address()) 477 s.Require().True(bytes.Equal(types.GetConsAddress(pk).Bytes(), pk.Address().Bytes())) 478 s.Require().Panics(func() { types.GetConsAddress(cryptotypes.PubKey(nil)) }) 479 } 480 481 func (s *addressTestSuite) TestGetFromBech32() { 482 _, err := types.GetFromBech32("", "prefix") 483 s.Require().Error(err) 484 s.Require().Equal("decoding Bech32 address failed: must provide a non empty address", err.Error()) 485 _, err = types.GetFromBech32("link1qqqsyqcyq5rqwzqf97tnae", "x") 486 s.Require().Error(err) 487 s.Require().Equal("invalid Bech32 prefix; expected x, got link", err.Error()) 488 } 489 490 func (s *addressTestSuite) TestMustAccAddressFromBech32() { 491 // Create a 10 byte address 492 addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 493 accBech := types.AccAddress(addr).String() 494 res := types.MustAccAddressFromBech32(accBech) 495 s.Require().Equal(types.AccAddress(res).String(), accBech) 496 497 // Set a custom address verifier only accepts 20 byte addresses 498 types.GetConfig().SetAddressVerifier(func(bz []byte) error { 499 n := len(bz) 500 if n == 20 { 501 return nil 502 } 503 return fmt.Errorf("incorrect address length %d", n) 504 }) 505 506 s.Require().Panics(func() { types.MustAccAddressFromBech32(accBech) }) 507 508 // Reinitialize the global config to default address verifier (nil) 509 types.GetConfig().SetAddressVerifier(nil) 510 }