From da0426a2ddb9100595077c10e77d82dbf8c3ca28 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 8 Feb 2019 15:54:40 -0800 Subject: [PATCH] Merge PR #2601: Bech32 Empty Addresses --- PENDING.md | 2 ++ types/address.go | 43 +++++++++++++++++++++++++++++++++ types/address_test.go | 21 ++++++++++++++-- x/distribution/types/msg.go | 10 ++++---- x/gov/msgs.go | 4 +-- x/slashing/msg.go | 2 +- x/staking/keeper/query_utils.go | 4 +-- x/staking/types/msg.go | 20 +++++++-------- 8 files changed, 84 insertions(+), 22 deletions(-) diff --git a/PENDING.md b/PENDING.md index f3117616e5..6a550057b1 100644 --- a/PENDING.md +++ b/PENDING.md @@ -35,6 +35,7 @@ BREAKING CHANGES * [\#3522](https://github.com/cosmos/cosmos-sdk/pull/3522) Get rid of double negatives: Coins.IsNotNegative() -> Coins.IsAnyNegative(). * \#3561 Don't unnecessarily store denominations in staking + * Tendermint @@ -59,6 +60,7 @@ FEATURES * [\#3477][distribution] new query endpoint "delegator_validators" * [\#3514](https://github.com/cosmos/cosmos-sdk/pull/3514) Provided a lazy loading implementation of Keybase that locks the underlying storage only for the time needed to perform the required operation. Also added Keybase reference to TxBuilder struct. + * [types] [\#2580](https://github.com/cosmos/cosmos-sdk/issues/2580) Addresses now Bech32 empty addresses to an empty string * Tendermint diff --git a/types/address.go b/types/address.go index 5a3b2d2a80..62c535d6ed 100644 --- a/types/address.go +++ b/types/address.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding/amino" @@ -71,12 +72,21 @@ func AccAddressFromHex(address string) (addr AccAddress, err error) { // AccAddressFromBech32 creates an AccAddress from a Bech32 string. func AccAddressFromBech32(address string) (addr AccAddress, err error) { + if len(strings.TrimSpace(address)) == 0 { + return AccAddress{}, nil + } + bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix() + bz, err := GetFromBech32(address, bech32PrefixAccAddr) if err != nil { return nil, err } + if len(bz) != AddrLen { + return nil, errors.New("Incorrect address length") + } + return AccAddress(bz), nil } @@ -141,7 +151,12 @@ func (aa AccAddress) Bytes() []byte { // String implements the Stringer interface. func (aa AccAddress) String() string { + if aa.Empty() { + return "" + } + bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix() + bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixAccAddr, aa.Bytes()) if err != nil { panic(err) @@ -187,12 +202,21 @@ func ValAddressFromHex(address string) (addr ValAddress, err error) { // ValAddressFromBech32 creates a ValAddress from a Bech32 string. func ValAddressFromBech32(address string) (addr ValAddress, err error) { + if len(strings.TrimSpace(address)) == 0 { + return ValAddress{}, nil + } + bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() + bz, err := GetFromBech32(address, bech32PrefixValAddr) if err != nil { return nil, err } + if len(bz) != AddrLen { + return nil, errors.New("Incorrect address length") + } + return ValAddress(bz), nil } @@ -258,7 +282,12 @@ func (va ValAddress) Bytes() []byte { // String implements the Stringer interface. func (va ValAddress) String() string { + if va.Empty() { + return "" + } + bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() + bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixValAddr, va.Bytes()) if err != nil { panic(err) @@ -304,12 +333,21 @@ func ConsAddressFromHex(address string) (addr ConsAddress, err error) { // ConsAddressFromBech32 creates a ConsAddress from a Bech32 string. func ConsAddressFromBech32(address string) (addr ConsAddress, err error) { + if len(strings.TrimSpace(address)) == 0 { + return ConsAddress{}, nil + } + bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() + bz, err := GetFromBech32(address, bech32PrefixConsAddr) if err != nil { return nil, err } + if len(bz) != AddrLen { + return nil, errors.New("Incorrect address length") + } + return ConsAddress(bz), nil } @@ -380,7 +418,12 @@ func (ca ConsAddress) Bytes() []byte { // String implements the Stringer interface. func (ca ConsAddress) String() string { + if ca.Empty() { + return "" + } + bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() + bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixConsAddr, ca.Bytes()) if err != nil { panic(err) diff --git a/types/address_test.go b/types/address_test.go index 251ceb9f06..6aed5d565f 100644 --- a/types/address_test.go +++ b/types/address_test.go @@ -13,7 +13,6 @@ import ( ) var invalidStrs = []string{ - "", "hello, world!", "0xAA", "AAA", @@ -33,6 +32,24 @@ func testMarshal(t *testing.T, original interface{}, res interface{}, marshal fu require.Equal(t, original, res) } +func TestEmptyAddresses(t *testing.T) { + require.Equal(t, (types.AccAddress{}).String(), "") + require.Equal(t, (types.ValAddress{}).String(), "") + require.Equal(t, (types.ConsAddress{}).String(), "") + + accAddr, err := types.AccAddressFromBech32("") + require.True(t, accAddr.Empty()) + require.Nil(t, err) + + valAddr, err := types.ValAddressFromBech32("") + require.True(t, valAddr.Empty()) + require.Nil(t, err) + + consAddr, err := types.ConsAddressFromBech32("") + require.True(t, consAddr.Empty()) + require.Nil(t, err) +} + func TestRandBech32PubkeyConsistency(t *testing.T) { var pub ed25519.PubKeyEd25519 @@ -200,7 +217,7 @@ func TestConfiguredPrefix(t *testing.T) { config := types.GetConfig() config.SetBech32PrefixForAccount(prefix+"acc", prefix+"pub") acc := types.AccAddress(pub.Address()) - require.True(t, strings.HasPrefix(acc.String(), prefix+"acc")) + require.True(t, strings.HasPrefix(acc.String(), prefix+"acc"), acc.String()) bech32Pub := types.MustBech32ifyAccPub(pub) require.True(t, strings.HasPrefix(bech32Pub, prefix+"pub")) diff --git a/x/distribution/types/msg.go b/x/distribution/types/msg.go index 9c977ea910..a6fb7d5181 100644 --- a/x/distribution/types/msg.go +++ b/x/distribution/types/msg.go @@ -40,10 +40,10 @@ func (msg MsgSetWithdrawAddress) GetSignBytes() []byte { // quick validity check func (msg MsgSetWithdrawAddress) ValidateBasic() sdk.Error { - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.WithdrawAddr == nil { + if msg.WithdrawAddr.Empty() { return ErrNilWithdrawAddr(DefaultCodespace) } return nil @@ -78,10 +78,10 @@ func (msg MsgWithdrawDelegatorReward) GetSignBytes() []byte { // quick validity check func (msg MsgWithdrawDelegatorReward) ValidateBasic() sdk.Error { - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } return nil @@ -114,7 +114,7 @@ func (msg MsgWithdrawValidatorCommission) GetSignBytes() []byte { // quick validity check func (msg MsgWithdrawValidatorCommission) ValidateBasic() sdk.Error { - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } return nil diff --git a/x/gov/msgs.go b/x/gov/msgs.go index ef671a48b9..78ad6f5ad7 100644 --- a/x/gov/msgs.go +++ b/x/gov/msgs.go @@ -59,7 +59,7 @@ func (msg MsgSubmitProposal) ValidateBasic() sdk.Error { if !validProposalType(msg.ProposalType) { return ErrInvalidProposalType(DefaultCodespace, msg.ProposalType) } - if len(msg.Proposer) == 0 { + if msg.Proposer.Empty() { return sdk.ErrInvalidAddress(msg.Proposer.String()) } if !msg.InitialDeposit.IsValid() { @@ -172,7 +172,7 @@ func (msg MsgVote) Type() string { return TypeMsgVote } // Implements Msg. func (msg MsgVote) ValidateBasic() sdk.Error { - if len(msg.Voter.Bytes()) == 0 { + if msg.Voter.Empty() { return sdk.ErrInvalidAddress(msg.Voter.String()) } if msg.ProposalID < 0 { diff --git a/x/slashing/msg.go b/x/slashing/msg.go index 5512586277..a108142f77 100644 --- a/x/slashing/msg.go +++ b/x/slashing/msg.go @@ -36,7 +36,7 @@ func (msg MsgUnjail) GetSignBytes() []byte { // quick validity check func (msg MsgUnjail) ValidateBasic() sdk.Error { - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrBadValidatorAddr(DefaultCodespace) } return nil diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 9de7f627f4..5a13fbcd14 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -90,8 +90,8 @@ func (k Keeper) GetAllRedelegations(ctx sdk.Context, delegator sdk.AccAddress, s iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) // smallest to largest defer iterator.Close() - srcValFilter := !(srcValAddress.Empty() || srcValAddress == nil) - dstValFilter := !(dstValAddress.Empty() || dstValAddress == nil) + srcValFilter := !(srcValAddress.Empty()) + dstValFilter := !(dstValAddress.Empty()) for ; iterator.Valid(); iterator.Next() { redelegation := types.MustUnmarshalRED(k.cdc, iterator.Value()) diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index 2e9a751e64..3602382ad7 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -123,10 +123,10 @@ func (msg MsgCreateValidator) GetSignBytes() []byte { // quick validity check func (msg MsgCreateValidator) ValidateBasic() sdk.Error { // note that unmarshaling from bech32 ensures either empty or valid - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } if msg.Value.Amount.LTE(sdk.ZeroInt()) { @@ -186,7 +186,7 @@ func (msg MsgEditValidator) GetSignBytes() []byte { // quick validity check func (msg MsgEditValidator) ValidateBasic() sdk.Error { - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return sdk.NewError(DefaultCodespace, CodeInvalidInput, "nil validator address") } @@ -237,10 +237,10 @@ func (msg MsgDelegate) GetSignBytes() []byte { // quick validity check func (msg MsgDelegate) ValidateBasic() sdk.Error { - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } if msg.Value.Amount.LTE(sdk.ZeroInt()) { @@ -285,13 +285,13 @@ func (msg MsgBeginRedelegate) GetSignBytes() []byte { // quick validity check func (msg MsgBeginRedelegate) ValidateBasic() sdk.Error { - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.ValidatorSrcAddr == nil { + if msg.ValidatorSrcAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } - if msg.ValidatorDstAddr == nil { + if msg.ValidatorDstAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } if msg.SharesAmount.LTE(sdk.ZeroDec()) { @@ -328,10 +328,10 @@ func (msg MsgUndelegate) GetSignBytes() []byte { // quick validity check func (msg MsgUndelegate) ValidateBasic() sdk.Error { - if msg.DelegatorAddr == nil { + if msg.DelegatorAddr.Empty() { return ErrNilDelegatorAddr(DefaultCodespace) } - if msg.ValidatorAddr == nil { + if msg.ValidatorAddr.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } if msg.SharesAmount.LTE(sdk.ZeroDec()) {