x/ibc-transfer: custom absolute packet timeout (#6248)

* x/ibc-transfer: custom timeout

* remove destHeight field

* cleanup

* fix test

* replace CLI arg for flag

* update CLI

* viper get flag

* address comments from review

* update cmd example:

* update spec

* address comments from review
This commit is contained in:
Federico Kunze 2020-06-04 15:30:56 -04:00 committed by GitHub
parent c1355d0b45
commit 1a5f2b7859
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 296 additions and 242 deletions

View File

@ -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 (

View File

@ -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(

View File

@ -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)

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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 {

View File

@ -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),
),

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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),
),
)

View File

@ -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())
)

View File

@ -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)
)

View File

@ -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")

View File

@ -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]"

View File

@ -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
}

View File

@ -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:])

View File

@ -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

View File

@ -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/<app>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/<app>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))

View File

@ -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/
```