diff --git a/x/ibc-transfer/alias.go b/x/ibc-transfer/alias.go index 2fa2b8bb0f..8a882d31a0 100644 --- a/x/ibc-transfer/alias.go +++ b/x/ibc-transfer/alias.go @@ -11,21 +11,19 @@ import ( ) const ( - DefaultPacketTimeoutHeight = keeper.DefaultPacketTimeoutHeight - DefaultPacketTimeoutTimestamp = keeper.DefaultPacketTimeoutTimestamp - EventTypeTimeout = types.EventTypeTimeout - EventTypePacket = types.EventTypePacket - EventTypeChannelClose = types.EventTypeChannelClose - AttributeKeyReceiver = types.AttributeKeyReceiver - AttributeKeyValue = types.AttributeKeyValue - AttributeKeyRefundReceiver = types.AttributeKeyRefundReceiver - AttributeKeyRefundValue = types.AttributeKeyRefundValue - AttributeKeyAckSuccess = types.AttributeKeyAckSuccess - AttributeKeyAckError = types.AttributeKeyAckError - ModuleName = types.ModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute + EventTypeTimeout = types.EventTypeTimeout + EventTypePacket = types.EventTypePacket + EventTypeChannelClose = types.EventTypeChannelClose + AttributeKeyReceiver = types.AttributeKeyReceiver + AttributeKeyValue = types.AttributeKeyValue + AttributeKeyRefundReceiver = types.AttributeKeyRefundReceiver + AttributeKeyRefundValue = types.AttributeKeyRefundValue + AttributeKeyAckSuccess = types.AttributeKeyAckSuccess + AttributeKeyAckError = types.AttributeKeyAckError + ModuleName = types.ModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( @@ -38,8 +36,7 @@ var ( RegisterInterfaces = types.RegisterInterfaces // variable aliases - ModuleCdc = types.ModuleCdc - AttributeValueCategory = types.AttributeValueCategory + ModuleCdc = types.ModuleCdc ) type ( diff --git a/x/ibc-transfer/client/cli/cli.go b/x/ibc-transfer/client/cli/cli.go index 03b26c5cb2..9180fc1c93 100644 --- a/x/ibc-transfer/client/cli/cli.go +++ b/x/ibc-transfer/client/cli/cli.go @@ -3,6 +3,7 @@ package cli import ( "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -10,8 +11,11 @@ import ( // GetQueryCmd returns the query commands for IBC fungible token transfer func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { ics20TransferQueryCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer query subcommands", + Use: "ibc-transfer", + Short: "IBC fungible token transfer query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } ics20TransferQueryCmd.AddCommand(flags.GetCommands( @@ -24,8 +28,11 @@ func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { // GetTxCmd returns the transaction commands for IBC fungible token transfer func GetTxCmd(cdc *codec.Codec) *cobra.Command { ics20TransferTxCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer transaction subcommands", + Use: "ibc-transfer", + Short: "IBC fungible token transfer transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } ics20TransferTxCmd.AddCommand(flags.PostCommands( diff --git a/x/ibc-transfer/client/cli/query.go b/x/ibc-transfer/client/cli/query.go index 7843286bad..ad282bec8b 100644 --- a/x/ibc-transfer/client/cli/query.go +++ b/x/ibc-transfer/client/cli/query.go @@ -22,10 +22,10 @@ func GetCmdQueryNextSequence(cdc *codec.Codec, queryRoute string) *cobra.Command Long: strings.TrimSpace(fmt.Sprintf(`Query an IBC channel end Example: -$ %s query ibc channel next-recv [port-id] [channel-id] +$ %s query ibc-transfer next-recv [port-id] [channel-id] `, version.ClientName), ), - Example: fmt.Sprintf("%s query ibc channel next-recv [port-id] [channel-id]", version.ClientName), + Example: fmt.Sprintf("%s query ibc-transfer next-recv [port-id] [channel-id]", version.ClientName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.NewContext().WithCodec(cdc) diff --git a/x/ibc-transfer/client/cli/tx.go b/x/ibc-transfer/client/cli/tx.go index 634eb33500..56332b90d5 100644 --- a/x/ibc-transfer/client/cli/tx.go +++ b/x/ibc-transfer/client/cli/tx.go @@ -2,36 +2,33 @@ package cli import ( "bufio" - "strconv" + "fmt" "github.com/spf13/cobra" + "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc-transfer/types" ) -// IBC transfer flags -var ( - FlagNode1 = "node1" - FlagNode2 = "node2" - FlagFrom1 = "from1" - FlagFrom2 = "from2" - FlagChainID2 = "chain-id2" - FlagSequence = "packet-sequence" - FlagTimeout = "timeout" +const ( + flagTimeoutHeight = "timeout-height" + flagTimeoutTimestamp = "timeout-timestamp" ) // GetTransferTxCmd returns the command to create a NewMsgTransfer transaction func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "transfer [src-port] [src-channel] [dest-height] [receiver] [amount]", - Short: "Transfer fungible token through IBC", - Args: cobra.ExactArgs(5), + Use: "transfer [src-port] [src-channel] [receiver] [amount]", + Short: "Transfer a fungible token through IBC", + Example: fmt.Sprintf("%s tx ibc-transfer transfer [src-port] [src-channel] [receiver] [amount]", version.ClientName), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) @@ -40,18 +37,19 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { sender := clientCtx.GetFromAddress() srcPort := args[0] srcChannel := args[1] - destHeight, err := strconv.Atoi(args[2]) + receiver := args[2] + + coins, err := sdk.ParseCoins(args[3]) if err != nil { return err } - // parse coin trying to be sent - coins, err := sdk.ParseCoins(args[4]) - if err != nil { - return err - } + timeoutHeight := viper.GetUint64(flagTimeoutHeight) + timeoutTimestamp := viper.GetUint64(flagTimeoutHeight) - msg := types.NewMsgTransfer(srcPort, srcChannel, uint64(destHeight), coins, sender, args[3]) + msg := types.NewMsgTransfer( + srcPort, srcChannel, coins, sender, receiver, timeoutHeight, timeoutTimestamp, + ) if err := msg.ValidateBasic(); err != nil { return err } @@ -59,5 +57,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return authclient.GenerateOrBroadcastMsgs(clientCtx, txBldr, []sdk.Msg{msg}) }, } + cmd.Flags().Uint64(flagTimeoutHeight, types.DefaultAbsolutePacketTimeoutHeight, "Absolute timeout block height. The timeout is disabled when set to 0.") + cmd.Flags().Uint64(flagTimeoutTimestamp, types.DefaultAbsolutePacketTimeoutTimestamp, "Absolute timeout timestamp in nanoseconds. The timeout is disabled when set to 0.") return cmd } diff --git a/x/ibc-transfer/client/rest/rest.go b/x/ibc-transfer/client/rest/rest.go index a9c58394ac..2d790698fb 100644 --- a/x/ibc-transfer/client/rest/rest.go +++ b/x/ibc-transfer/client/rest/rest.go @@ -21,8 +21,9 @@ func RegisterRoutes(clientCtx client.Context, r *mux.Router) { // TransferTxReq defines the properties of a transfer tx request's body. type TransferTxReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - DestHeight uint64 `json:"dest_height" yaml:"dest_height"` - Amount sdk.Coins `json:"amount" yaml:"amount"` - Receiver string `json:"receiver" yaml:"receiver"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Receiver string `json:"receiver" yaml:"receiver"` + TimeoutHeight uint64 `json:"timeout_height" yaml:"timeout_height"` + TimeoutTimestamp uint64 `json:"timeout_timestamp" yaml:"timeout_timestamp"` } diff --git a/x/ibc-transfer/client/rest/tx.go b/x/ibc-transfer/client/rest/tx.go index 0849e76b00..c1d20e7612 100644 --- a/x/ibc-transfer/client/rest/tx.go +++ b/x/ibc-transfer/client/rest/tx.go @@ -56,10 +56,11 @@ func transferHandlerFn(clientCtx client.Context) http.HandlerFunc { msg := types.NewMsgTransfer( portID, channelID, - req.DestHeight, req.Amount, fromAddr, req.Receiver, + req.TimeoutHeight, + req.TimeoutTimestamp, ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc-transfer/handler.go b/x/ibc-transfer/handler.go index f5e30fc1f8..f1e51547ea 100644 --- a/x/ibc-transfer/handler.go +++ b/x/ibc-transfer/handler.go @@ -22,7 +22,7 @@ func NewHandler(k Keeper) sdk.Handler { // See createOutgoingPacket in spec:https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay func handleMsgTransfer(ctx sdk.Context, k Keeper, msg *MsgTransfer) (*sdk.Result, error) { if err := k.SendTransfer( - ctx, msg.SourcePort, msg.SourceChannel, msg.DestinationHeight, msg.Amount, msg.Sender, msg.Receiver, + ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp, ); err != nil { return nil, err } @@ -32,7 +32,7 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg *MsgTransfer) (*sdk.Result ctx.EventManager().EmitEvent( sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), sdk.NewAttribute(AttributeKeyReceiver, msg.Receiver), ), diff --git a/x/ibc-transfer/handler_test.go b/x/ibc-transfer/handler_test.go index 4509fd2e96..f2f50c4cdc 100644 --- a/x/ibc-transfer/handler_test.go +++ b/x/ibc-transfer/handler_test.go @@ -79,7 +79,7 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { suite.Require().Nil(err, "transfer module could not claim capability") ctx := suite.chainA.GetContext() - msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2.String()) + msg := transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2.String(), 110, 0) res, err := handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // channel does not exist @@ -105,14 +105,14 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { suite.Require().NotNil(res, "%+v", res) // successfully executed // test when the source is false - msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2.String()) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2.String(), 110, 0) _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins2) res, err = handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // incorrect denom prefix - msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2.String()) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2.String(), 110, 0) suite.chainA.App.BankKeeper.SetSupply(ctx, bank.NewSupply(testPrefixedCoins1)) _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins1) diff --git a/x/ibc-transfer/keeper/keeper.go b/x/ibc-transfer/keeper/keeper.go index 1202f1a7d1..0fb21aa417 100644 --- a/x/ibc-transfer/keeper/keeper.go +++ b/x/ibc-transfer/keeper/keeper.go @@ -16,17 +16,7 @@ import ( host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) -const ( - // DefaultPacketTimeoutHeight is the default packet timeout height relative - // to the current block height. The timeout is disabled when set to 0. - DefaultPacketTimeoutHeight = 1000 // NOTE: in blocks - - // DefaultPacketTimeoutTimestamp is the default packet timeout timestamp relative - // to the current block timestamp. The timeout is disabled when set to 0. - DefaultPacketTimeoutTimestamp = 0 // NOTE: in nanoseconds -) - -// Keeper defines the IBC transfer keeper +// Keeper defines the IBC fungible transfer keeper type Keeper struct { storeKey sdk.StoreKey cdc codec.Marshaler @@ -63,7 +53,7 @@ func NewKeeper( // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", host.ModuleName, types.ModuleName)) + return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", host.ModuleName, types.ModuleName)) } // GetTransferAccount returns the ICS20 - transfers ModuleAccount diff --git a/x/ibc-transfer/keeper/relay.go b/x/ibc-transfer/keeper/relay.go index ec711067b0..6477d4467e 100644 --- a/x/ibc-transfer/keeper/relay.go +++ b/x/ibc-transfer/keeper/relay.go @@ -24,10 +24,11 @@ func (k Keeper) SendTransfer( ctx sdk.Context, sourcePort, sourceChannel string, - destHeight uint64, amount sdk.Coins, sender sdk.AccAddress, receiver string, + timeoutHeight, + timeoutTimestamp uint64, ) error { sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { @@ -44,10 +45,12 @@ func (k Keeper) SendTransfer( channeltypes.ErrSequenceSendNotFound, "source port: %s, source channel: %s", sourcePort, sourceChannel, ) - } - return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, amount, sender, receiver) + return k.createOutgoingPacket( + ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, + amount, sender, receiver, timeoutHeight, timeoutTimestamp, + ) } // See spec for this function: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay @@ -56,10 +59,10 @@ func (k Keeper) createOutgoingPacket( seq uint64, sourcePort, sourceChannel, destinationPort, destinationChannel string, - destHeight uint64, amount sdk.Coins, sender sdk.AccAddress, receiver string, + timeoutHeight, timeoutTimestamp uint64, ) error { channelCap, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePort, sourceChannel)) if !ok { @@ -138,8 +141,8 @@ func (k Keeper) createOutgoingPacket( sourceChannel, destinationPort, destinationChannel, - destHeight+DefaultPacketTimeoutHeight, - DefaultPacketTimeoutTimestamp, + timeoutHeight, + timeoutTimestamp, ) return k.channelKeeper.SendPacket(ctx, channelCap, packet) diff --git a/x/ibc-transfer/keeper/relay_test.go b/x/ibc-transfer/keeper/relay_test.go index ece3a4e71e..edb49363e0 100644 --- a/x/ibc-transfer/keeper/relay_test.go +++ b/x/ibc-transfer/keeper/relay_test.go @@ -93,7 +93,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { tc.malleate() err = suite.chainA.App.TransferKeeper.SendTransfer( - suite.chainA.GetContext(), testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2.String(), + suite.chainA.GetContext(), testPort1, testChannel1, tc.amount, testAddr1, testAddr2.String(), 110, 0, ) if tc.expPass { diff --git a/x/ibc-transfer/module.go b/x/ibc-transfer/module.go index f75e360157..31eac43135 100644 --- a/x/ibc-transfer/module.go +++ b/x/ibc-transfer/module.go @@ -304,7 +304,7 @@ func (am AppModule) OnRecvPacket( ctx.EventManager().EmitEvent( sdk.NewEvent( EventTypePacket, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), sdk.NewAttribute(AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(AttributeKeyValue, data.Amount.String()), ), @@ -336,7 +336,7 @@ func (am AppModule) OnAcknowledgementPacket( ctx.EventManager().EmitEvent( sdk.NewEvent( EventTypePacket, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), sdk.NewAttribute(AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(AttributeKeyValue, data.Amount.String()), sdk.NewAttribute(AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success)), @@ -375,7 +375,7 @@ func (am AppModule) OnTimeoutPacket( EventTypeTimeout, sdk.NewAttribute(AttributeKeyRefundReceiver, data.Sender), sdk.NewAttribute(AttributeKeyRefundValue, data.Amount.String()), - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), ), ) diff --git a/x/ibc-transfer/types/codec.go b/x/ibc-transfer/types/codec.go index 2e16ce038e..c7dea82f2a 100644 --- a/x/ibc-transfer/types/codec.go +++ b/x/ibc-transfer/types/codec.go @@ -23,11 +23,11 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { var ( amino = codec.New() - // ModuleCdc references the global x/transfer module codec. Note, the codec + // ModuleCdc references the global x/ibc-transfer module codec. Note, the codec // should ONLY be used in certain instances of tests and for JSON encoding as Amino // is still used for that purpose. // - // The actual codec used for serialization should be provided to x/transfer and + // The actual codec used for serialization should be provided to x/ibc-transfer and // defined at the application level. ModuleCdc = codec.NewHybridCodec(amino, cdctypes.NewInterfaceRegistry()) ) diff --git a/x/ibc-transfer/types/events.go b/x/ibc-transfer/types/events.go index a3f4376600..f66958de6f 100644 --- a/x/ibc-transfer/types/events.go +++ b/x/ibc-transfer/types/events.go @@ -1,11 +1,5 @@ package types -import ( - "fmt" - - host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" -) - // IBC transfer events const ( EventTypeTimeout = "timeout" @@ -19,8 +13,3 @@ const ( AttributeKeyAckSuccess = "success" AttributeKeyAckError = "error" ) - -// IBC transfer events vars -var ( - AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, ModuleName) -) diff --git a/x/ibc-transfer/types/msgs.go b/x/ibc-transfer/types/msgs.go index eb69fbf220..ad352a2c81 100644 --- a/x/ibc-transfer/types/msgs.go +++ b/x/ibc-transfer/types/msgs.go @@ -13,15 +13,18 @@ const ( // NewMsgTransfer creates a new MsgTransfer instance func NewMsgTransfer( - sourcePort, sourceChannel string, destHeight uint64, amount sdk.Coins, sender sdk.AccAddress, receiver string, + sourcePort, sourceChannel string, + amount sdk.Coins, sender sdk.AccAddress, receiver string, + timeoutHeight, timeoutTimestamp uint64, ) *MsgTransfer { return &MsgTransfer{ - SourcePort: sourcePort, - SourceChannel: sourceChannel, - DestinationHeight: destHeight, - Amount: amount, - Sender: sender, - Receiver: receiver, + SourcePort: sourcePort, + SourceChannel: sourceChannel, + Amount: amount, + Sender: sender, + Receiver: receiver, + TimeoutHeight: timeoutHeight, + TimeoutTimestamp: timeoutTimestamp, } } @@ -35,7 +38,8 @@ func (MsgTransfer) Type() string { return TypeMsgTransfer } -// ValidateBasic implements sdk.Msg +// ValidateBasic performs a basic check of the MsgTransfer fields. +// NOTE: timeout height and timestamp values can be 0 to disable the timeout. func (msg MsgTransfer) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.SourcePort); err != nil { return sdkerrors.Wrap(err, "invalid source port ID") @@ -44,10 +48,10 @@ func (msg MsgTransfer) ValidateBasic() error { return sdkerrors.Wrap(err, "invalid source channel ID") } if !msg.Amount.IsAllPositive() { - return sdkerrors.ErrInsufficientFunds + return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, msg.Amount.String()) } if !msg.Amount.IsValid() { - return sdkerrors.ErrInvalidCoins + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } if msg.Sender.Empty() { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") diff --git a/x/ibc-transfer/types/msgs_test.go b/x/ibc-transfer/types/msgs_test.go index 6b332fc4d8..027b3f944a 100644 --- a/x/ibc-transfer/types/msgs_test.go +++ b/x/ibc-transfer/types/msgs_test.go @@ -34,14 +34,14 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) + msg := NewMsgTransfer(validPort, validChannel, coins, addr1, addr2, 10, 0) require.Equal(t, RouterKey, msg.Route()) } // TestMsgTransferType tests Type for MsgTransfer func TestMsgTransferType(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) + msg := NewMsgTransfer(validPort, validChannel, coins, addr1, addr2, 10, 0) require.Equal(t, "transfer", msg.Type()) } @@ -49,18 +49,18 @@ func TestMsgTransferType(t *testing.T) { // TestMsgTransferValidation tests ValidateBasic for MsgTransfer func TestMsgTransferValidation(t *testing.T) { testMsgs := []*MsgTransfer{ - NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2), // valid msg - NewMsgTransfer(invalidShortPort, validChannel, 10, coins, addr1, addr2), // too short port id - NewMsgTransfer(invalidLongPort, validChannel, 10, coins, addr1, addr2), // too long port id - NewMsgTransfer(invalidPort, validChannel, 10, coins, addr1, addr2), // port id contains non-alpha - NewMsgTransfer(validPort, invalidShortChannel, 10, coins, addr1, addr2), // too short channel id - NewMsgTransfer(validPort, invalidLongChannel, 10, coins, addr1, addr2), // too long channel id - NewMsgTransfer(validPort, invalidChannel, 10, coins, addr1, addr2), // channel id contains non-alpha - NewMsgTransfer(validPort, validChannel, 10, invalidDenomCoins, addr1, addr2), // invalid amount - NewMsgTransfer(validPort, validChannel, 10, negativeCoins, addr1, addr2), // amount contains negative coin - NewMsgTransfer(validPort, validChannel, 10, coins, emptyAddr, addr2), // missing sender address - NewMsgTransfer(validPort, validChannel, 10, coins, addr1, ""), // missing recipient address - NewMsgTransfer(validPort, validChannel, 10, sdk.Coins{}, addr1, addr2), // not possitive coin + NewMsgTransfer(validPort, validChannel, coins, addr1, addr2, 10, 0), // valid msg + NewMsgTransfer(invalidShortPort, validChannel, coins, addr1, addr2, 10, 0), // too short port id + NewMsgTransfer(invalidLongPort, validChannel, coins, addr1, addr2, 10, 0), // too long port id + NewMsgTransfer(invalidPort, validChannel, coins, addr1, addr2, 10, 0), // port id contains non-alpha + NewMsgTransfer(validPort, invalidShortChannel, coins, addr1, addr2, 10, 0), // too short channel id + NewMsgTransfer(validPort, invalidLongChannel, coins, addr1, addr2, 10, 0), // too long channel id + NewMsgTransfer(validPort, invalidChannel, coins, addr1, addr2, 10, 0), // channel id contains non-alpha + NewMsgTransfer(validPort, validChannel, invalidDenomCoins, addr1, addr2, 10, 0), // invalid amount + NewMsgTransfer(validPort, validChannel, negativeCoins, addr1, addr2, 10, 0), // amount contains negative coin + NewMsgTransfer(validPort, validChannel, coins, emptyAddr, addr2, 10, 0), // missing sender address + NewMsgTransfer(validPort, validChannel, coins, addr1, "", 10, 0), // missing recipient address + NewMsgTransfer(validPort, validChannel, sdk.Coins{}, addr1, addr2, 10, 0), // not possitive coin } testCases := []struct { @@ -93,16 +93,16 @@ func TestMsgTransferValidation(t *testing.T) { // TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer func TestMsgTransferGetSignBytes(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) + msg := NewMsgTransfer(validPort, validChannel, coins, addr1, addr2, 110, 10) res := msg.GetSignBytes() - expected := `{"type":"cosmos-sdk/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"destination_height":"10","receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source_channel":"testchannel","source_port":"testportid"}}` + expected := `{"type":"cosmos-sdk/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source_channel":"testchannel","source_port":"testportid","timeout_height":"110","timeout_timestamp":"10"}}` require.Equal(t, expected, string(res)) } // TestMsgTransferGetSigners tests GetSigners for MsgTransfer func TestMsgTransferGetSigners(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) + msg := NewMsgTransfer(validPort, validChannel, coins, addr1, addr2, 10, 0) res := msg.GetSigners() expected := "[746573746164647231]" diff --git a/x/ibc-transfer/types/packet.go b/x/ibc-transfer/types/packet.go index 5ce4a4dfc4..f107643ba9 100644 --- a/x/ibc-transfer/types/packet.go +++ b/x/ibc-transfer/types/packet.go @@ -1,10 +1,30 @@ package types import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) +const ( + // DefaultRelativePacketTimeoutHeight is the default packet timeout height (in blocks) relative + // to the current block height. The timeout is disabled when set to 0. + DefaultRelativePacketTimeoutHeight = 1000 + + // DefaultRelativePacketTimeoutTimestamp is the default packet timeout timestamp (in nanoseconds) + // relative to the current block timestamp. The timeout is disabled when set to 0. + DefaultRelativePacketTimeoutTimestamp = 0 + + // DefaultAbsolutePacketTimeoutHeight is the default packet timeout in blocks. + // The timeout is disabled when set to 0. + DefaultAbsolutePacketTimeoutHeight = 0 + + // DefaultAbsolutePacketTimeoutTimestamp is the default packet timeout timestamp (in nanoseconds) + // relative to the current block timestamp. The timeout is disabled when set to 0. + DefaultAbsolutePacketTimeoutTimestamp = 0 +) + // NewFungibleTokenPacketData contructs a new FungibleTokenPacketData instance func NewFungibleTokenPacketData( amount sdk.Coins, sender, receiver string) FungibleTokenPacketData { @@ -18,16 +38,16 @@ func NewFungibleTokenPacketData( // ValidateBasic is used for validating the token transfer func (ftpd FungibleTokenPacketData) ValidateBasic() error { if !ftpd.Amount.IsAllPositive() { - return sdkerrors.ErrInsufficientFunds + return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, ftpd.Amount.String()) } if !ftpd.Amount.IsValid() { - return sdkerrors.ErrInvalidCoins + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, ftpd.Amount.String()) } - if ftpd.Sender == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") + if strings.TrimSpace(ftpd.Sender) == "" { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be blank") } - if ftpd.Receiver == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing receiver address") + if strings.TrimSpace(ftpd.Receiver) == "" { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be blank") } return nil } diff --git a/x/ibc-transfer/types/types.pb.go b/x/ibc-transfer/types/types.pb.go index b4f770a2e5..dbccda8ee8 100644 --- a/x/ibc-transfer/types/types.pb.go +++ b/x/ibc-transfer/types/types.pb.go @@ -32,14 +32,18 @@ type MsgTransfer struct { SourcePort string `protobuf:"bytes,1,opt,name=source_port,json=sourcePort,proto3" json:"source_port,omitempty" yaml:"source_port"` // the channel by which the packet will be sent SourceChannel string `protobuf:"bytes,2,opt,name=source_channel,json=sourceChannel,proto3" json:"source_channel,omitempty" yaml:"source_channel"` - // the current height of the destination chain - DestinationHeight uint64 `protobuf:"varint,3,opt,name=destination_height,json=destinationHeight,proto3" json:"destination_height,omitempty" yaml:"destination_height"` // the tokens to be transferred - Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` // the sender address - Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,5,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` + Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,4,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` // the recipient address on the destination chain - Receiver string `protobuf:"bytes,6,opt,name=receiver,proto3" json:"receiver,omitempty"` + Receiver string `protobuf:"bytes,5,opt,name=receiver,proto3" json:"receiver,omitempty"` + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + TimeoutHeight uint64 `protobuf:"varint,6,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty" yaml:"timeout_height"` + // Timeout timestamp (in nanoseconds) relative to the current block timestamp. + // The timeout is disabled when set to 0. + TimeoutTimestamp uint64 `protobuf:"varint,7,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty" yaml:"timeout_timestamp"` } func (m *MsgTransfer) Reset() { *m = MsgTransfer{} } @@ -89,13 +93,6 @@ func (m *MsgTransfer) GetSourceChannel() string { return "" } -func (m *MsgTransfer) GetDestinationHeight() uint64 { - if m != nil { - return m.DestinationHeight - } - return 0 -} - func (m *MsgTransfer) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Amount @@ -117,6 +114,20 @@ func (m *MsgTransfer) GetReceiver() string { return "" } +func (m *MsgTransfer) GetTimeoutHeight() uint64 { + if m != nil { + return m.TimeoutHeight + } + return 0 +} + +func (m *MsgTransfer) GetTimeoutTimestamp() uint64 { + if m != nil { + return m.TimeoutTimestamp + } + return 0 +} + // FungibleTokenPacketData defines a struct for the packet payload // See FungibleTokenPacketData spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures type FungibleTokenPacketData struct { @@ -246,37 +257,39 @@ func init() { func init() { proto.RegisterFile("x/ibc-transfer/types/types.proto", fileDescriptor_36db19b72d57f809) } var fileDescriptor_36db19b72d57f809 = []byte{ - // 480 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x53, 0xc1, 0x6e, 0xd3, 0x40, - 0x10, 0x8d, 0x49, 0x1b, 0xca, 0x06, 0x90, 0xba, 0x40, 0x71, 0x23, 0x61, 0x47, 0x3e, 0x20, 0x5f, - 0x62, 0x13, 0x38, 0x20, 0x71, 0x22, 0x2e, 0x42, 0x20, 0x40, 0xaa, 0xac, 0x9c, 0x90, 0x50, 0xb4, - 0x59, 0x0f, 0xf6, 0xca, 0xf1, 0x6e, 0xb4, 0xbb, 0x0e, 0xcd, 0x5f, 0xf0, 0x01, 0x7c, 0x01, 0xe2, - 0x43, 0x7a, 0xec, 0x91, 0x93, 0x41, 0xc9, 0x1f, 0xe4, 0xc8, 0x09, 0xd5, 0x76, 0x4a, 0xa0, 0x11, - 0xe2, 0xc2, 0xc5, 0xf6, 0x9b, 0x79, 0xf3, 0x3c, 0x6f, 0x76, 0x16, 0x75, 0x4f, 0x7c, 0x36, 0xa6, - 0x3d, 0x2d, 0x09, 0x57, 0xef, 0x41, 0xfa, 0x7a, 0x3e, 0x05, 0x55, 0x3d, 0xbd, 0xa9, 0x14, 0x5a, - 0x60, 0x93, 0x0a, 0x95, 0x09, 0x35, 0x52, 0x51, 0xea, 0x9d, 0x78, 0x6b, 0xa2, 0x37, 0xeb, 0x77, - 0xee, 0xeb, 0x84, 0xc9, 0x68, 0x34, 0x25, 0x52, 0xcf, 0xfd, 0x92, 0xec, 0xc7, 0x22, 0x16, 0xbf, - 0xbe, 0x2a, 0x85, 0xce, 0xfe, 0x25, 0x51, 0xe7, 0x53, 0x13, 0xb5, 0xdf, 0xa8, 0x78, 0x58, 0xab, - 0xe1, 0xc7, 0xa8, 0xad, 0x44, 0x2e, 0x29, 0x8c, 0xa6, 0x42, 0x6a, 0xd3, 0xe8, 0x1a, 0xee, 0xb5, - 0xe0, 0x60, 0x55, 0xd8, 0x78, 0x4e, 0xb2, 0xc9, 0x13, 0x67, 0x23, 0xe9, 0x84, 0xa8, 0x42, 0xc7, - 0x42, 0x6a, 0xfc, 0x14, 0xdd, 0xac, 0x73, 0x34, 0x21, 0x9c, 0xc3, 0xc4, 0xbc, 0x52, 0xd6, 0x1e, - 0xae, 0x0a, 0xfb, 0xce, 0x6f, 0xb5, 0x75, 0xde, 0x09, 0x6f, 0x54, 0x81, 0xa3, 0x0a, 0xe3, 0xd7, - 0x08, 0x47, 0xa0, 0x34, 0xe3, 0x44, 0x33, 0xc1, 0x47, 0x09, 0xb0, 0x38, 0xd1, 0x66, 0xb3, 0x6b, - 0xb8, 0x3b, 0xc1, 0xbd, 0x55, 0x61, 0x1f, 0x56, 0x2a, 0x97, 0x39, 0x4e, 0xb8, 0xbf, 0x11, 0x7c, - 0x51, 0xc6, 0xf0, 0x3b, 0xd4, 0x22, 0x99, 0xc8, 0xb9, 0x36, 0x77, 0xba, 0x4d, 0xb7, 0xfd, 0xf0, - 0x96, 0xb7, 0x31, 0xbe, 0x59, 0xdf, 0x3b, 0x12, 0x8c, 0x07, 0x0f, 0x4e, 0x0b, 0xbb, 0xf1, 0xf9, - 0x9b, 0xed, 0xc6, 0x4c, 0x27, 0xf9, 0xd8, 0xa3, 0x22, 0xf3, 0x2b, 0x5a, 0xfd, 0xea, 0xa9, 0x28, - 0xad, 0xe7, 0x75, 0x5e, 0xa0, 0xc2, 0x5a, 0x14, 0xbf, 0x44, 0x2d, 0x05, 0x3c, 0x02, 0x69, 0xee, - 0x76, 0x0d, 0xf7, 0x7a, 0xd0, 0xff, 0x51, 0xd8, 0xbd, 0x7f, 0x50, 0x19, 0x50, 0x3a, 0x88, 0x22, - 0x09, 0x4a, 0x85, 0xb5, 0x00, 0xee, 0xa0, 0x3d, 0x09, 0x14, 0xd8, 0x0c, 0xa4, 0xd9, 0x3a, 0x9f, - 0x59, 0x78, 0x81, 0x9d, 0x2f, 0x06, 0xba, 0xfb, 0x3c, 0xe7, 0x31, 0x1b, 0x4f, 0x60, 0x28, 0x52, - 0xe0, 0xc7, 0x84, 0xa6, 0xa0, 0x9f, 0x11, 0x4d, 0x36, 0x1c, 0x1a, 0xff, 0xc3, 0xe1, 0xc1, 0x85, - 0xc3, 0xf2, 0x20, 0xb7, 0xb6, 0xdb, 0xfc, 0xa3, 0xdd, 0x21, 0x72, 0xb6, 0x74, 0x3b, 0xa0, 0x29, - 0x17, 0x1f, 0x26, 0x10, 0xc5, 0x90, 0x01, 0xd7, 0xd8, 0x44, 0x57, 0x55, 0x4e, 0x29, 0x28, 0x55, - 0xee, 0xd7, 0x5e, 0xb8, 0x86, 0xf8, 0x36, 0xda, 0x05, 0x29, 0xc5, 0xfa, 0x97, 0x15, 0x08, 0x5e, - 0x9d, 0x2e, 0x2c, 0xe3, 0x6c, 0x61, 0x19, 0xdf, 0x17, 0x96, 0xf1, 0x71, 0x69, 0x35, 0xce, 0x96, - 0x56, 0xe3, 0xeb, 0xd2, 0x6a, 0xbc, 0xed, 0xff, 0xd5, 0xd5, 0xb6, 0x1b, 0x35, 0x6e, 0x95, 0x7b, - 0xff, 0xe8, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x62, 0x70, 0xeb, 0x70, 0x03, 0x00, 0x00, + // 498 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x53, 0x41, 0x8b, 0xd3, 0x40, + 0x14, 0x6e, 0xec, 0x6e, 0x77, 0x9d, 0xba, 0xe2, 0x8e, 0xba, 0x8e, 0x45, 0x92, 0x92, 0x83, 0xe4, + 0xd2, 0xc4, 0xea, 0x41, 0xf0, 0x64, 0xbb, 0x22, 0x2e, 0x22, 0x2c, 0xa1, 0x27, 0x41, 0x4a, 0x3a, + 0x79, 0x26, 0x21, 0xcd, 0x4c, 0x98, 0x99, 0xd4, 0xed, 0xbf, 0xf0, 0x77, 0x88, 0x3f, 0x64, 0x8f, + 0x7b, 0x14, 0x84, 0x28, 0xed, 0x3f, 0xe8, 0xd1, 0x93, 0x34, 0x49, 0x6b, 0x8b, 0x45, 0xbc, 0xec, + 0x25, 0x93, 0xef, 0xbd, 0xef, 0x7d, 0xc9, 0xf7, 0x31, 0x0f, 0xb5, 0x2f, 0x9c, 0x68, 0x44, 0x3b, + 0x4a, 0x78, 0x4c, 0x7e, 0x04, 0xe1, 0xa8, 0x69, 0x0a, 0xb2, 0x7c, 0xda, 0xa9, 0xe0, 0x8a, 0x63, + 0x42, 0xb9, 0x4c, 0xb8, 0x1c, 0x4a, 0x3f, 0xb6, 0x2f, 0xec, 0x15, 0xd1, 0x9e, 0x74, 0x5b, 0x8f, + 0x55, 0x18, 0x09, 0x7f, 0x98, 0x7a, 0x42, 0x4d, 0x9d, 0x82, 0xec, 0x04, 0x3c, 0xe0, 0x7f, 0xde, + 0x4a, 0x85, 0xd6, 0xf1, 0x5f, 0xa2, 0xe6, 0xf7, 0x3a, 0x6a, 0xbe, 0x93, 0xc1, 0xa0, 0x52, 0xc3, + 0xcf, 0x51, 0x53, 0xf2, 0x4c, 0x50, 0x18, 0xa6, 0x5c, 0x28, 0xa2, 0xb5, 0x35, 0xeb, 0x66, 0xff, + 0x64, 0x91, 0x1b, 0x78, 0xea, 0x25, 0xe3, 0x17, 0xe6, 0x46, 0xd3, 0x74, 0x51, 0x89, 0xce, 0xb9, + 0x50, 0xf8, 0x25, 0xba, 0x5d, 0xf5, 0x68, 0xe8, 0x31, 0x06, 0x63, 0x72, 0xa3, 0x98, 0x7d, 0xb8, + 0xc8, 0x8d, 0xfb, 0x5b, 0xb3, 0x55, 0xdf, 0x74, 0x8f, 0xca, 0xc2, 0x69, 0x89, 0xf1, 0x07, 0xd4, + 0xf0, 0x12, 0x9e, 0x31, 0x45, 0xea, 0xed, 0xba, 0xd5, 0x7c, 0x7a, 0xd7, 0xde, 0x30, 0x3c, 0xe9, + 0xda, 0xa7, 0x3c, 0x62, 0xfd, 0x27, 0x97, 0xb9, 0x51, 0xfb, 0xf2, 0xc3, 0xb0, 0x82, 0x48, 0x85, + 0xd9, 0xc8, 0xa6, 0x3c, 0x71, 0x4a, 0x5a, 0x75, 0x74, 0xa4, 0x1f, 0x57, 0x0e, 0x97, 0x03, 0xd2, + 0xad, 0x44, 0xf1, 0x19, 0x6a, 0x48, 0x60, 0x3e, 0x08, 0xb2, 0xd7, 0xd6, 0xac, 0x5b, 0xfd, 0xee, + 0xaf, 0xdc, 0xe8, 0xfc, 0x87, 0x4a, 0x8f, 0xd2, 0x9e, 0xef, 0x0b, 0x90, 0xd2, 0xad, 0x04, 0x70, + 0x0b, 0x1d, 0x0a, 0xa0, 0x10, 0x4d, 0x40, 0x90, 0xfd, 0xa5, 0x4b, 0x77, 0x8d, 0x97, 0x39, 0xa8, + 0x28, 0x01, 0x9e, 0xa9, 0x61, 0x08, 0x51, 0x10, 0x2a, 0xd2, 0x68, 0x6b, 0xd6, 0xde, 0x66, 0x0e, + 0xdb, 0x7d, 0xd3, 0x3d, 0xaa, 0x0a, 0x6f, 0x0a, 0x8c, 0xcf, 0xd0, 0xf1, 0x8a, 0xb1, 0x3c, 0xa5, + 0xf2, 0x92, 0x94, 0x1c, 0x14, 0x22, 0x8f, 0x16, 0xb9, 0x41, 0xb6, 0x45, 0xd6, 0x14, 0xd3, 0xbd, + 0x53, 0xd5, 0x06, 0xeb, 0xd2, 0x57, 0x0d, 0x3d, 0x78, 0x9d, 0xb1, 0x20, 0x1a, 0x8d, 0x61, 0xc0, + 0x63, 0x60, 0xe7, 0x1e, 0x8d, 0x41, 0xbd, 0xf2, 0x94, 0xb7, 0x11, 0xb7, 0x76, 0x1d, 0x71, 0x9f, + 0xac, 0xe3, 0x2e, 0xee, 0xc1, 0xce, 0xec, 0xea, 0xdb, 0xd9, 0x99, 0x03, 0x64, 0xee, 0xf8, 0xdb, + 0x1e, 0x8d, 0x19, 0xff, 0x34, 0x06, 0x3f, 0x80, 0x04, 0x98, 0xc2, 0x04, 0x1d, 0xc8, 0x8c, 0x52, + 0x90, 0xb2, 0xb8, 0x9e, 0x87, 0xee, 0x0a, 0xe2, 0x7b, 0x68, 0x1f, 0x84, 0xe0, 0xab, 0x4f, 0x96, + 0xa0, 0xff, 0xf6, 0x72, 0xa6, 0x6b, 0x57, 0x33, 0x5d, 0xfb, 0x39, 0xd3, 0xb5, 0xcf, 0x73, 0xbd, + 0x76, 0x35, 0xd7, 0x6b, 0xdf, 0xe6, 0x7a, 0xed, 0x7d, 0xf7, 0x9f, 0xae, 0x76, 0x2d, 0xe4, 0xa8, + 0x51, 0xac, 0xcd, 0xb3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x83, 0xf7, 0x16, 0x2f, 0xaf, 0x03, + 0x00, 0x00, } func (m *MsgTransfer) Marshal() (dAtA []byte, err error) { @@ -299,19 +312,29 @@ func (m *MsgTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TimeoutTimestamp != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.TimeoutTimestamp)) + i-- + dAtA[i] = 0x38 + } + if m.TimeoutHeight != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.TimeoutHeight)) + i-- + dAtA[i] = 0x30 + } if len(m.Receiver) > 0 { i -= len(m.Receiver) copy(dAtA[i:], m.Receiver) i = encodeVarintTypes(dAtA, i, uint64(len(m.Receiver))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } if len(m.Sender) > 0 { i -= len(m.Sender) copy(dAtA[i:], m.Sender) i = encodeVarintTypes(dAtA, i, uint64(len(m.Sender))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } if len(m.Amount) > 0 { for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { @@ -324,14 +347,9 @@ func (m *MsgTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTypes(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } } - if m.DestinationHeight != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.DestinationHeight)) - i-- - dAtA[i] = 0x18 - } if len(m.SourceChannel) > 0 { i -= len(m.SourceChannel) copy(dAtA[i:], m.SourceChannel) @@ -465,9 +483,6 @@ func (m *MsgTransfer) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - if m.DestinationHeight != 0 { - n += 1 + sovTypes(uint64(m.DestinationHeight)) - } if len(m.Amount) > 0 { for _, e := range m.Amount { l = e.Size() @@ -482,6 +497,12 @@ func (m *MsgTransfer) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + if m.TimeoutHeight != 0 { + n += 1 + sovTypes(uint64(m.TimeoutHeight)) + } + if m.TimeoutTimestamp != 0 { + n += 1 + sovTypes(uint64(m.TimeoutTimestamp)) + } return n } @@ -624,25 +645,6 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { m.SourceChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DestinationHeight", wireType) - } - m.DestinationHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DestinationHeight |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) } @@ -676,7 +678,7 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) } @@ -710,7 +712,7 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { m.Sender = []byte{} } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) } @@ -742,6 +744,44 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { } m.Receiver = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutHeight", wireType) + } + m.TimeoutHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeoutHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + m.TimeoutTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeoutTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/x/ibc-transfer/types/types.proto b/x/ibc-transfer/types/types.proto index 4384eb6a7d..3fee31361c 100644 --- a/x/ibc-transfer/types/types.proto +++ b/x/ibc-transfer/types/types.proto @@ -17,21 +17,23 @@ message MsgTransfer { string source_channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; - // the current height of the destination chain - uint64 destination_height = 3 [ - (gogoproto.moretags) = "yaml:\"destination_height\"" - ]; // the tokens to be transferred - repeated cosmos_sdk.v1.Coin amount = 4 [ + repeated cosmos_sdk.v1.Coin amount = 3 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; // the sender address - bytes sender = 5 [ + bytes sender = 4 [ (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; // the recipient address on the destination chain - string receiver = 6; + string receiver = 5; + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + uint64 timeout_height = 6 [(gogoproto.moretags) = "yaml:\"timeout_height\""]; + // Timeout timestamp (in nanoseconds) relative to the current block timestamp. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; } // FungibleTokenPacketData defines a struct for the packet payload diff --git a/x/ibc/07-tendermint/client/cli/tx.go b/x/ibc/07-tendermint/client/cli/tx.go index ff261ee616..c68b9564cc 100644 --- a/x/ibc/07-tendermint/client/cli/tx.go +++ b/x/ibc/07-tendermint/client/cli/tx.go @@ -33,13 +33,11 @@ const flagTrustLevel = "trust-level" // in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift]", - Short: "create new tendermint client", - Long: "create new tendermint client. Trust level can be a fraction (eg: '1/3') or 'default'", - Example: fmt.Sprintf( - "%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --from node0 --home ../node0/cli --chain-id $CID", - version.ClientName, ibctmtypes.SubModuleName), - Args: cobra.ExactArgs(5), + Use: "create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift]", + Short: "create new tendermint client", + Long: "create new tendermint client. Trust level can be a fraction (eg: '1/3') or 'default'", + Example: fmt.Sprintf("%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --from node0 --home ../node0/cli --chain-id $CID", version.ClientName, ibctmtypes.SubModuleName), + Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) diff --git a/x/ibc/spec/README.md b/x/ibc/spec/README.md index f70fd74e2b..cf0b56e330 100644 --- a/x/ibc/spec/README.md +++ b/x/ibc/spec/README.md @@ -40,11 +40,11 @@ in the SDK's `x/ibc` module: * [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics): Implemented in [`x/ibc/03-connection`](https://github.com/cosmos/x/ibc/03-connection) * [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics): Implemented in [`x/ibc/04-channel`](https://github.com/cosmos/x/ibc/04-channel) * [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation): Implemented in [`x/ibc/05-port`](https://github.com/cosmos/x/ibc/05-port) -* [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): To be implemented in [`x/ibc/06-solo`](https://github.com/cosmos/x/ibc/06-solo) +* [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): Implemented in [`x/ibc/06-solomachine`](https://github.com/cosmos/x/ibc/06-solomachine) * [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client): Implemented in [`x/ibc/07-tendermint`](https://github.com/cosmos/x/ibc/07-tendermint) -* [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): To be implemented in [`x/ibc/09-loopback`](https://github.com/cosmos/x/ibc/09-loopback) +* [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): Implemented in [`x/ibc/09-localhost`](https://github.com/cosmos/x/ibc/09-localhost) * [ICS 018- Relayer Algorithms](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms): Implemented in it's own [relayer repository](https://github.com/cosmos/relayer) -* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/transfer`](https://github.com/cosmos/x/transfer) +* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/ibc-transfer`](https://github.com/cosmos/x/ibc-transfer) * [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments): Implemented in [`x/ibc/23-commitment`](https://github.com/cosmos/x/ibc/23-commitment) * [ICS 024 - Host Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements): Implemented in [`x/ibc/24-host`](https://github.com/cosmos/x/ibc/24-host) * [ICS 025 - Handler Interface](https://github.com/cosmos/ics/tree/master/spec/ics-025-handler-interface): Handler interfaces are implemented at the top level in `x/ibc/handler.go`, @@ -75,35 +75,37 @@ the SDK modules, please check this [document](../../../docs/building-modules/str prerequisite reading. For ease of auditing, every Interchain Standard has been developed in its own -package. The following tree describes the architecture of the directories within -the IBC module: +package. The development team separated the IBC TAO (Transport, Authentication, Ordering) ICS specifications from the IBC application level +specification. The following tree describes the architecture of the directories that +the `ibc` (TAO) and `ibc-transfer` ([ICS20](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer)) modules: ```shell -x/ibc -├── 02-client/ -├── 03-connection/ -├── 04-channel/ -├── 05-port/ -├── 06-solo/ -├── 07-tendermint/ -├── 09-loopback/ -├── 20-transfer/ -├── 23-commitment/ -├── 24-host/ -├── ante -│   └── ante.go -├── client -│   ├── cli -│   │   └── cli.go -│   └── rest -│   └── rest.go -├── keeper -│   ├── keeper.go -│   └── querier.go -├── types -│   ├── errors.go -│   └── keys.go -├── alias.go -├── handler.go -└── module.go +x/ +├── ibc/ +│ ├── 02-client/ +│ ├── 03-connection/ +│ ├── 04-channel/ +│ ├── 05-port/ +│ ├── 06-solo/ +│ ├── 07-tendermint/ +│ ├── 09-localhost/ +│ ├── 23-commitment/ +│ ├── 24-host/ +│ ├── ante +│ │ └── ante.go +│ ├── client +│  │ ├── cli +│  │ │   └── cli.go +│  │ └── rest +│  │ └── rest.go +│ ├── keeper +│  │ ├── keeper.go +│  │ └── querier.go +│ ├── types +│ │   ├── errors.go +│ │   └── keys.go +│ ├── alias.go +│ ├── handler.go +│ └── module.go +└── ibc-transfer/ ```