package types_test import ( "encoding/hex" "math/rand" "testing" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" "strings" "github.com/cosmos/cosmos-sdk/types" ) var invalidStrs = []string{ "", "hello, world!", "0xAA", "AAA", types.Bech32PrefixAccAddr + "AB0C", types.Bech32PrefixAccPub + "1234", types.Bech32PrefixValAddr + "5678", types.Bech32PrefixValPub + "BBAB", types.Bech32PrefixConsAddr + "FF04", types.Bech32PrefixConsPub + "6789", } func testMarshal(t *testing.T, original interface{}, res interface{}, marshal func() ([]byte, error), unmarshal func([]byte) error) { bz, err := marshal() require.Nil(t, err) err = unmarshal(bz) require.Nil(t, err) require.Equal(t, original, res) } func TestRandBech32PubkeyConsistency(t *testing.T) { var pub ed25519.PubKeyEd25519 for i := 0; i < 1000; i++ { rand.Read(pub[:]) mustBech32AccPub := types.MustBech32ifyAccPub(pub) bech32AccPub, err := types.Bech32ifyAccPub(pub) require.Nil(t, err) require.Equal(t, bech32AccPub, mustBech32AccPub) mustBech32ValPub := types.MustBech32ifyValPub(pub) bech32ValPub, err := types.Bech32ifyValPub(pub) require.Nil(t, err) require.Equal(t, bech32ValPub, mustBech32ValPub) mustBech32ConsPub := types.MustBech32ifyConsPub(pub) bech32ConsPub, err := types.Bech32ifyConsPub(pub) require.Nil(t, err) require.Equal(t, bech32ConsPub, mustBech32ConsPub) mustAccPub := types.MustGetAccPubKeyBech32(bech32AccPub) accPub, err := types.GetAccPubKeyBech32(bech32AccPub) require.Nil(t, err) require.Equal(t, accPub, mustAccPub) mustValPub := types.MustGetValPubKeyBech32(bech32ValPub) valPub, err := types.GetValPubKeyBech32(bech32ValPub) require.Nil(t, err) require.Equal(t, valPub, mustValPub) mustConsPub := types.MustGetConsPubKeyBech32(bech32ConsPub) consPub, err := types.GetConsPubKeyBech32(bech32ConsPub) require.Nil(t, err) require.Equal(t, consPub, mustConsPub) require.Equal(t, valPub, accPub) require.Equal(t, valPub, consPub) } } func TestRandBech32AccAddrConsistency(t *testing.T) { var pub ed25519.PubKeyEd25519 for i := 0; i < 1000; i++ { rand.Read(pub[:]) acc := types.AccAddress(pub.Address()) res := types.AccAddress{} testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) str := acc.String() res, err := types.AccAddressFromBech32(str) require.Nil(t, err) require.Equal(t, acc, res) str = hex.EncodeToString(acc) res, err = types.AccAddressFromHex(str) require.Nil(t, err) require.Equal(t, acc, res) } for _, str := range invalidStrs { _, err := types.AccAddressFromHex(str) require.NotNil(t, err) _, err = types.AccAddressFromBech32(str) require.NotNil(t, err) err = (*types.AccAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } } func TestValAddr(t *testing.T) { var pub ed25519.PubKeyEd25519 for i := 0; i < 20; i++ { rand.Read(pub[:]) acc := types.ValAddress(pub.Address()) res := types.ValAddress{} testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) str := acc.String() res, err := types.ValAddressFromBech32(str) require.Nil(t, err) require.Equal(t, acc, res) str = hex.EncodeToString(acc) res, err = types.ValAddressFromHex(str) require.Nil(t, err) require.Equal(t, acc, res) } for _, str := range invalidStrs { _, err := types.ValAddressFromHex(str) require.NotNil(t, err) _, err = types.ValAddressFromBech32(str) require.NotNil(t, err) err = (*types.ValAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } } func TestConsAddress(t *testing.T) { var pub ed25519.PubKeyEd25519 for i := 0; i < 20; i++ { rand.Read(pub[:]) acc := types.ConsAddress(pub.Address()) res := types.ConsAddress{} testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON) testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal) str := acc.String() res, err := types.ConsAddressFromBech32(str) require.Nil(t, err) require.Equal(t, acc, res) str = hex.EncodeToString(acc) res, err = types.ConsAddressFromHex(str) require.Nil(t, err) require.Equal(t, acc, res) } for _, str := range invalidStrs { _, err := types.ConsAddressFromHex(str) require.NotNil(t, err) _, err = types.ConsAddressFromBech32(str) require.NotNil(t, err) err = (*types.ConsAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } } const letterBytes = "abcdefghijklmnopqrstuvwxyz" func RandString(n int) string { b := make([]byte, n) for i := range b { b[i] = letterBytes[rand.Intn(len(letterBytes))] } return string(b) } func TestConfiguredPrefix(t *testing.T) { var pub ed25519.PubKeyEd25519 for length := 1; length < 10; length++ { for times := 1; times < 20; times++ { rand.Read(pub[:]) // Test if randomly generated prefix of a given length works prefix := RandString(length) // Assuming that GetConfig is not sealed. config := types.GetConfig() config.SetBech32PrefixForAccount(prefix+"acc", prefix+"pub") acc := types.AccAddress(pub.Address()) require.True(t, strings.HasPrefix(acc.String(), prefix+"acc")) bech32Pub := types.MustBech32ifyAccPub(pub) require.True(t, strings.HasPrefix(bech32Pub, prefix+"pub")) config.SetBech32PrefixForValidator(prefix+"valaddr", prefix+"valpub") val := types.ValAddress(pub.Address()) require.True(t, strings.HasPrefix(val.String(), prefix+"valaddr")) bech32ValPub := types.MustBech32ifyValPub(pub) require.True(t, strings.HasPrefix(bech32ValPub, prefix+"valpub")) config.SetBech32PrefixForConsensusNode(prefix+"consaddr", prefix+"conspub") cons := types.ConsAddress(pub.Address()) require.True(t, strings.HasPrefix(cons.String(), prefix+"consaddr")) bech32ConsPub := types.MustBech32ifyConsPub(pub) require.True(t, strings.HasPrefix(bech32ConsPub, prefix+"conspub")) } } }