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  }