diff --git a/modules/apps/transfer/types/errors.go b/modules/apps/transfer/types/errors.go index 0f0cb7c4..2a8d0164 100644 --- a/modules/apps/transfer/types/errors.go +++ b/modules/apps/transfer/types/errors.go @@ -14,4 +14,5 @@ var ( ErrSendDisabled = sdkerrors.Register(ModuleName, 7, "fungible token transfers from this chain are disabled") ErrReceiveDisabled = sdkerrors.Register(ModuleName, 8, "fungible token transfers to this chain are disabled") ErrMaxTransferChannels = sdkerrors.Register(ModuleName, 9, "max transfer channels") + ErrInvalidMemo = sdkerrors.Register(ModuleName, 10, "invalid memo") ) diff --git a/modules/apps/transfer/types/msgs.go b/modules/apps/transfer/types/msgs.go index 13c0b8b4..40aa4c8c 100644 --- a/modules/apps/transfer/types/msgs.go +++ b/modules/apps/transfer/types/msgs.go @@ -12,7 +12,8 @@ import ( // msg types const ( - TypeMsgTransfer = "transfer" + TypeMsgTransfer = "transfer" + MaximumMemoLength = 32768 // maximum length of the memo in bytes (value chosen arbitrarily) ) // NewMsgTransfer creates a new MsgTransfer instance @@ -69,6 +70,9 @@ func (msg MsgTransfer) ValidateBasic() error { if strings.TrimSpace(msg.Receiver) == "" { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address") } + if len(msg.Memo) > MaximumMemoLength { + return sdkerrors.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } return ValidateIBCDenom(msg.Token.Denom) } diff --git a/modules/apps/transfer/types/msgs_test.go b/modules/apps/transfer/types/msgs_test.go index 00570ac1..a3e91056 100644 --- a/modules/apps/transfer/types/msgs_test.go +++ b/modules/apps/transfer/types/msgs_test.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "math/rand" "testing" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" @@ -62,8 +63,20 @@ func TestMsgTransferGetSignBytes(t *testing.T) { }) } +// GenerateString generates a random string of the given length in bytes +func GenerateString(length uint) string { + charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + bytes := make([]byte, length) + for i := range bytes { + bytes[i] = charset[rand.Intn(len(charset))] + } + return string(bytes) +} + // TestMsgTransferValidation tests ValidateBasic for MsgTransfer func TestMsgTransferValidation(t *testing.T) { + largeMemoTransfer := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) + largeMemoTransfer.Memo = GenerateString(MaximumMemoLength + 1) testCases := []struct { name string msg *MsgTransfer @@ -77,6 +90,7 @@ func TestMsgTransferValidation(t *testing.T) { {"port id contains non-alpha", NewMsgTransfer(invalidPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), false}, {"too short channel id", NewMsgTransfer(validPort, invalidShortChannel, coin, addr1, addr2, timeoutHeight, 0), false}, {"too long channel id", NewMsgTransfer(validPort, invalidLongChannel, coin, addr1, addr2, timeoutHeight, 0), false}, + {"too long memo", largeMemoTransfer, false}, {"channel id contains non-alpha", NewMsgTransfer(validPort, invalidChannel, coin, addr1, addr2, timeoutHeight, 0), false}, {"invalid denom", NewMsgTransfer(validPort, validChannel, invalidDenomCoin, addr1, addr2, timeoutHeight, 0), false}, {"zero coin", NewMsgTransfer(validPort, validChannel, zeroCoin, addr1, addr2, timeoutHeight, 0), false}, diff --git a/testing/simapp/utils.go b/testing/simapp/utils.go index 51788f5a..aea7fabb 100644 --- a/testing/simapp/utils.go +++ b/testing/simapp/utils.go @@ -3,8 +3,6 @@ package simapp import ( "encoding/json" "fmt" - "io/ioutil" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" @@ -12,6 +10,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" + "io/ioutil" "github.com/cosmos/ibc-go/v3/testing/simapp/helpers" )