From d583964763f229c3a685dc64ad55f63f72c34329 Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 11:14:50 +0800 Subject: [PATCH 01/12] add ibc bank mock --- x/ibc/mock/bank/alias.go | 23 ++++ x/ibc/mock/bank/client/cli/tx.go | 20 ++++ x/ibc/mock/bank/handler.go | 25 +++++ x/ibc/mock/bank/internal/keeper/keeper.go | 67 +++++++++++ x/ibc/mock/bank/internal/types/codec.go | 16 +++ x/ibc/mock/bank/internal/types/errors.go | 14 +++ .../bank/internal/types/expected_keepers.go | 19 ++++ x/ibc/mock/bank/internal/types/keys.go | 21 ++++ x/ibc/mock/bank/internal/types/msgs.go | 57 ++++++++++ x/ibc/mock/bank/internal/types/packet.go | 55 +++++++++ x/ibc/mock/bank/module.go | 106 ++++++++++++++++++ 11 files changed, 423 insertions(+) create mode 100644 x/ibc/mock/bank/alias.go create mode 100644 x/ibc/mock/bank/client/cli/tx.go create mode 100644 x/ibc/mock/bank/handler.go create mode 100644 x/ibc/mock/bank/internal/keeper/keeper.go create mode 100644 x/ibc/mock/bank/internal/types/codec.go create mode 100644 x/ibc/mock/bank/internal/types/errors.go create mode 100644 x/ibc/mock/bank/internal/types/expected_keepers.go create mode 100644 x/ibc/mock/bank/internal/types/keys.go create mode 100644 x/ibc/mock/bank/internal/types/msgs.go create mode 100644 x/ibc/mock/bank/internal/types/packet.go create mode 100644 x/ibc/mock/bank/module.go diff --git a/x/ibc/mock/bank/alias.go b/x/ibc/mock/bank/alias.go new file mode 100644 index 000000000000..267bdab18d81 --- /dev/null +++ b/x/ibc/mock/bank/alias.go @@ -0,0 +1,23 @@ +package mockbank + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/types" +) + +// nolint +type ( + MsgTransfer = types.MsgTransfer + Keeper = keeper.Keeper +) + +// nolint +var ( + ModuleName = types.ModuleName + StoreKey = types.StoreKey + TStoreKey = types.TStoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey + + RegisterCdc = types.RegisterCodec +) diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go new file mode 100644 index 000000000000..2410fbd3ea62 --- /dev/null +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -0,0 +1,20 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" +) + +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: "ibcmockbank", + Short: "IBC mockbank module transaction subcommands", + // RunE: client.ValidateCmd, + } + txCmd.AddCommand( + // TransferTxCmd(cdc), + ) + + return txCmd +} diff --git a/x/ibc/mock/bank/handler.go b/x/ibc/mock/bank/handler.go new file mode 100644 index 000000000000..b1b66ea18a01 --- /dev/null +++ b/x/ibc/mock/bank/handler.go @@ -0,0 +1,25 @@ +package mockbank + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case MsgTransfer: + return handleMsgTransfer(ctx, k, msg) + default: + return sdk.ErrUnknownRequest("failed to parse message").Result() + } + } +} + +func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { + err := k.Transfer(ctx, msg.ChannelID, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + if err != nil { + return err.Result() + } + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go new file mode 100644 index 000000000000..2889af2cd310 --- /dev/null +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -0,0 +1,67 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc" + chantypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/types" + "github.com/tendermint/tendermint/crypto" +) + +type Keeper struct { + cdc *codec.Codec + key sdk.StoreKey + ibck ibc.Keeper + bk types.BankKeeper +} + +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ibck ibc.Keeper, bk types.BankKeeper) Keeper { + return Keeper{ + cdc: cdc, + key: key, + ibck: ibck, + bk: bk, + } +} + +// Transfer handles transfer logic +func (k Keeper) Transfer(ctx sdk.Context, srcPort, srcChan, dstPort, dstChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool) sdk.Error { + // TODO + if source { + // escrow tokens + escrowAddress := k.GetEscrowAddress(srcChan) + k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{amount}) + } else { + // burn vouchers from sender + k.bk.BurnCoins(ctx, sender, sdk.Coins{amount}) + } + + // get the next sequence + sequence, ok := k.ibck.ChannelKeeper.GetNextSequenceSend(ctx, srcPort, srcChan) + if !ok { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrGetSequence, "failed to retrieve sequence") + } + + // build packet + packetData := types.TransferPacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } + + packet := chantypes.NewPacket(sequence, 0, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) + + err := k.ibck.ChannelKeeper.SendPacket(ctx, packet) + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrSendPacket, "failed to send packet") + } + + return nil +} + +// GetEscrowAddress returns the escrow address for the specified channel +func (k Keeper) GetEscrowAddress(chanID string) sdk.AccAddress { + return sdk.AccAddress(crypto.AddressHash([]byte(chanID))) +} diff --git a/x/ibc/mock/bank/internal/types/codec.go b/x/ibc/mock/bank/internal/types/codec.go new file mode 100644 index 000000000000..199638b18e54 --- /dev/null +++ b/x/ibc/mock/bank/internal/types/codec.go @@ -0,0 +1,16 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(TransferPacketData{}, "ibcmockbank/TransferPacketData", nil) + cdc.RegisterConcrete(MsgTransfer{}, "ibcmockbank/MsgTransfer", nil) +} + +var MouduleCdc = codec.New() + +func init() { + RegisterCodec(MouduleCdc) +} diff --git a/x/ibc/mock/bank/internal/types/errors.go b/x/ibc/mock/bank/internal/types/errors.go new file mode 100644 index 000000000000..bd4103ead9d1 --- /dev/null +++ b/x/ibc/mock/bank/internal/types/errors.go @@ -0,0 +1,14 @@ +//nolint +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ibcmockbank errors reserve 100 ~ 199. +const ( + CodeErrGetSequence sdk.CodeType = 100 + CodeErrSendPacket sdk.CodeType = 101 + CodeInvalidAmount sdk.CodeType = 102 + CodeInvalidAddress sdk.CodeType = 103 +) diff --git a/x/ibc/mock/bank/internal/types/expected_keepers.go b/x/ibc/mock/bank/internal/types/expected_keepers.go new file mode 100644 index 000000000000..69438e82562b --- /dev/null +++ b/x/ibc/mock/bank/internal/types/expected_keepers.go @@ -0,0 +1,19 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type BankKeeper interface { + AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) + + SetTotalSupply(ctx sdk.Context, totalSupply sdk.Coin) + + GetTotalSupply(ctx sdk.Context, denom string) (coin sdk.Coin, found bool) + + IncreaseTotalSupply(ctx sdk.Context, amt sdk.Coin) sdk.Error + + BurnCoins(ctx sdk.Context, fromAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error +} diff --git a/x/ibc/mock/bank/internal/types/keys.go b/x/ibc/mock/bank/internal/types/keys.go new file mode 100644 index 000000000000..a5e764dfbb72 --- /dev/null +++ b/x/ibc/mock/bank/internal/types/keys.go @@ -0,0 +1,21 @@ +package types + +const ( + // ModuleName is the name of the module + ModuleName = "ibcmockbank" + + // StoreKey is the string store representation + StoreKey = ModuleName + + // TStoreKey is the string transient store representation + TStoreKey = "transient_" + ModuleName + + // QuerierRoute is the querier route for the module + QuerierRoute = ModuleName + + // RouterKey is the msg router key for the module + RouterKey = ModuleName + + // codespace + DefaultCodespace = ModuleName +) diff --git a/x/ibc/mock/bank/internal/types/msgs.go b/x/ibc/mock/bank/internal/types/msgs.go new file mode 100644 index 000000000000..be2e89802b58 --- /dev/null +++ b/x/ibc/mock/bank/internal/types/msgs.go @@ -0,0 +1,57 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type MsgTransfer struct { + SrcPort string + SrcChannel string + DstPort string + DstChannel string + Amount sdk.Coin + Sender sdk.AccAddress + Receiver sdk.AccAddress + Source bool +} + +func NewMsgTransfer(srcPort, srcChannel, dstPort, dstChannel string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool) MsgTransfer { + return MsgTransfer{ + SrcPort: srcPort, + SrcChannel: srcChannel, + DstPort: dstPort, + DstChannel: dstChannel, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } +} + +func (MsgTransfer) Route() string { + return RouterKey +} + +func (MsgTransfer) Type() string { + return "transfer" +} + +func (msg MsgTransfer) ValidateBasic() sdk.Error { + if !msg.Amount.IsValid() { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAmount, "invalid amount") + } + + if msg.Sender.Empty() || msg.Receiver.Empty() { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAddress, "invalid address") + } + + return nil +} + +func (msg MsgTransfer) GetSignBytes() []byte { + return sdk.MustSortJSON(MouduleCdc.MustMarshalJSON(msg)) +} + +func (msg MsgTransfer) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Sender} +} diff --git a/x/ibc/mock/bank/internal/types/packet.go b/x/ibc/mock/bank/internal/types/packet.go new file mode 100644 index 000000000000..f16f13e6f7f8 --- /dev/null +++ b/x/ibc/mock/bank/internal/types/packet.go @@ -0,0 +1,55 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type TransferPacketData struct { + Amount sdk.Coin + Sender sdk.AccAddress + Receiver sdk.AccAddress + Source bool +} + +func (packet TransferPacketData) MarshalAmino() ([]byte, error) { + return MouduleCdc.MarshalBinaryBare(packet) +} + +func (packet *TransferPacketData) UnmarshalAmino(bz []byte) (err error) { + return MouduleCdc.UnmarshalBinaryBare(bz, packet) +} + +func (packet TransferPacketData) Marshal() []byte { + return MouduleCdc.MustMarshalBinaryBare(packet) +} + +func (packet TransferPacketData) MarshalJSON() ([]byte, error) { + return MouduleCdc.MarshalJSON(packet) +} + +func (packet *TransferPacketData) UnmarshalJSON(bz []byte) (err error) { + return MouduleCdc.UnmarshalJSON(bz, packet) +} + +func (TransferPacketData) SourcePort() string { + return "ibcmockbank" +} + +func (TransferPacketData) DestPort() string { + return "ibcmockbank" +} + +func (packet TransferPacketData) String() string { + return fmt.Sprintf(`TransferPacketData: + Amount: %s + Sender: %s + Receiver: %s + Source: %v`, + packet.Amount.String(), + packet.Sender.String(), + packet.Receiver.String(), + packet.Source, + ) +} diff --git a/x/ibc/mock/bank/module.go b/x/ibc/mock/bank/module.go new file mode 100644 index 000000000000..1369abe1ac25 --- /dev/null +++ b/x/ibc/mock/bank/module.go @@ -0,0 +1,106 @@ +package mockbank + +import ( + "encoding/json" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/client/cli" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +func (AppModuleBasic) Name() string { + return ModuleName +} + +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + RegisterCdc(cdc) +} + +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return nil +} + +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + return nil +} + +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + //noop +} + +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(cdc) +} + +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return nil +} + +type AppModule struct { + AppModuleBasic + k Keeper +} + +func NewAppModule(k Keeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + + k: k, + } +} + +func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + +} + +func (AppModule) Name() string { + return ModuleName +} + +func (AppModule) Route() string { + return ModuleName +} + +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.k) +} + +func (am AppModule) QuerierRoute() string { + return ModuleName +} + +func (am AppModule) NewQuerierHandler() sdk.Querier { + return nil +} + +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return nil +} + +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + +} + +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} From e0f44bc6aadfd2b18d676391fc029a804458e30e Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 11:17:04 +0800 Subject: [PATCH 02/12] modify handler --- x/ibc/mock/bank/handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/mock/bank/handler.go b/x/ibc/mock/bank/handler.go index b1b66ea18a01..6ec924894aa1 100644 --- a/x/ibc/mock/bank/handler.go +++ b/x/ibc/mock/bank/handler.go @@ -16,7 +16,7 @@ func NewHandler(k Keeper) sdk.Handler { } func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { - err := k.Transfer(ctx, msg.ChannelID, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + err := k.Transfer(ctx, msg.SrcPort, msg.SrcChannel, msg.DstPort, msg.DstChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { return err.Result() } From 79ae5da7e99558a06f5fe3a748e3b46249c0a8d8 Mon Sep 17 00:00:00 2001 From: chengwenxi Date: Wed, 16 Oct 2019 11:59:04 +0800 Subject: [PATCH 03/12] import channel --- x/ibc/module.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/ibc/module.go b/x/ibc/module.go index 447ec2cb03fe..a186412e3a99 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" From a745374eebe0e88e62e466d92a1258e71cecd826 Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 15:04:33 +0800 Subject: [PATCH 04/12] add receiving logic --- x/ibc/mock/bank/alias.go | 2 + x/ibc/mock/bank/client/cli/flags.go | 27 ++++++++ x/ibc/mock/bank/client/cli/tx.go | 52 +++++++++++++- x/ibc/mock/bank/handler.go | 15 +++- x/ibc/mock/bank/internal/keeper/keeper.go | 84 ++++++++++++++++++++--- x/ibc/mock/bank/internal/types/errors.go | 11 +-- x/ibc/mock/bank/internal/types/msgs.go | 37 +++++----- x/ibc/mock/bank/internal/types/packet.go | 8 --- 8 files changed, 189 insertions(+), 47 deletions(-) create mode 100644 x/ibc/mock/bank/client/cli/flags.go diff --git a/x/ibc/mock/bank/alias.go b/x/ibc/mock/bank/alias.go index 267bdab18d81..98480c482287 100644 --- a/x/ibc/mock/bank/alias.go +++ b/x/ibc/mock/bank/alias.go @@ -20,4 +20,6 @@ var ( RouterKey = types.RouterKey RegisterCdc = types.RegisterCodec + + NewMsgTransfer = types.NewMsgTransfer ) diff --git a/x/ibc/mock/bank/client/cli/flags.go b/x/ibc/mock/bank/client/cli/flags.go new file mode 100644 index 000000000000..d3bde99fc0b0 --- /dev/null +++ b/x/ibc/mock/bank/client/cli/flags.go @@ -0,0 +1,27 @@ +package cli + +import ( + flag "github.com/spf13/pflag" +) + +const ( + FlagSrcPort = "src-port" + FlagSrcChannel = "src-channel" + FlagAmount = "amount" + FlagReceiver = "receiver" + FlagSource = "source" + FlagTimeout = "timeout" +) + +var ( + FsTransfer = flag.NewFlagSet("", flag.ContinueOnError) +) + +func init() { + FsTransfer.String(FlagSrcPort, "", "the source port ID") + FsTransfer.String(FlagSrcChannel, "", "the source channel ID") + FsTransfer.String(FlagAmount, "", "the amount to be transferred") + FsTransfer.String(FlagReceiver, "", "the recipient") + FsTransfer.Bool(FlagSource, true, "indicate if the sender is the source chain of the token") + FsTransfer.Uint64(FlagTimeout, 0, "the block height after which the packet will expire") +} diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index 2410fbd3ea62..025ca68f2dd7 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -1,9 +1,16 @@ package cli import ( - "github.com/spf13/cobra" - + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "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/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + mockbank "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank" + "github.com/spf13/cobra" + "github.com/spf13/viper" ) func GetTxCmd(cdc *codec.Codec) *cobra.Command { @@ -13,8 +20,47 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { // RunE: client.ValidateCmd, } txCmd.AddCommand( - // TransferTxCmd(cdc), + TransferTxCmd(cdc), ) return txCmd } + +func TransferTxCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "transfer ", + Short: "Transfer", + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + sender := ctx.GetFromAddress() + srcPort := viper.GetString(FlagSrcPort) + srcChan := viper.GetString(FlagSrcChannel) + source := viper.GetBool(FlagSource) + timeout := viper.GetUint64(FlagTimeout) + + amountStr := viper.GetString(FlagAmount) + amount, err := sdk.ParseCoin(amountStr) + if err != nil { + return err + } + + receiver, err := sdk.AccAddressFromBech32(viper.GetString(FlagReceiver)) + if err != nil { + return err + } + + msg := mockbank.NewMsgTransfer(srcPort, srcChan, amount, sender, receiver, source, timeout, nil, 0) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd = client.PostCommands(cmd)[0] + + return cmd +} diff --git a/x/ibc/mock/bank/handler.go b/x/ibc/mock/bank/handler.go index 6ec924894aa1..f7e0834dbe08 100644 --- a/x/ibc/mock/bank/handler.go +++ b/x/ibc/mock/bank/handler.go @@ -16,9 +16,18 @@ func NewHandler(k Keeper) sdk.Handler { } func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { - err := k.Transfer(ctx, msg.SrcPort, msg.SrcChannel, msg.DstPort, msg.DstChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) - if err != nil { - return err.Result() + if msg.Proof != nil { + // send packet + err := k.SendTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source, msg.Timeout) + if err != nil { + return err.Result() + } + } else { + // receive packet + err := k.ReceiveTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source, msg.Timeout, msg.Proof, msg.ProofHeight) + if err != nil { + return err.Result() + } } return sdk.Result{Events: ctx.EventManager().Events()} diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index 2889af2cd310..b4ea6a03bced 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc" chantypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/types" "github.com/tendermint/tendermint/crypto" ) @@ -25,24 +26,39 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ibck ibc.Keeper, bk types.Ban } } -// Transfer handles transfer logic -func (k Keeper) Transfer(ctx sdk.Context, srcPort, srcChan, dstPort, dstChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool) sdk.Error { - // TODO - if source { - // escrow tokens - escrowAddress := k.GetEscrowAddress(srcChan) - k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{amount}) - } else { - // burn vouchers from sender - k.bk.BurnCoins(ctx, sender, sdk.Coins{amount}) +// SendTransfer handles transfer sending logic +func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64) sdk.Error { + // get the port and channel of the counterparty + channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) + if !ok { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidChannel, "failed to get channel") } + dstPort := channel.Counterparty.PortID + dstChan := channel.Counterparty.ChannelID + // get the next sequence sequence, ok := k.ibck.ChannelKeeper.GetNextSequenceSend(ctx, srcPort, srcChan) if !ok { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrGetSequence, "failed to retrieve sequence") } + if source { + // escrow tokens + escrowAddress := k.GetEscrowAddress(srcChan) + err := k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{amount}) + if err != nil { + return err + } + + } else { + // burn vouchers from sender + err := k.bk.BurnCoins(ctx, sender, sdk.Coins{amount}) + if err != nil { + return err + } + } + // build packet packetData := types.TransferPacketData{ Amount: amount, @@ -51,7 +67,7 @@ func (k Keeper) Transfer(ctx sdk.Context, srcPort, srcChan, dstPort, dstChan str Source: source, } - packet := chantypes.NewPacket(sequence, 0, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) + packet := chantypes.NewPacket(sequence, timeout, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) err := k.ibck.ChannelKeeper.SendPacket(ctx, packet) if err != nil { @@ -61,6 +77,52 @@ func (k Keeper) Transfer(ctx sdk.Context, srcPort, srcChan, dstPort, dstChan str return nil } +// ReceiveTransfer handles transfer receiving logic +func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) sdk.Error { + // get the port and channel of the counterparty + channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) + if !ok { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidChannel, "failed to get channel") + } + + dstPort := channel.Counterparty.PortID + dstChan := channel.Counterparty.ChannelID + + if source { + // mint tokens + _, err := k.bk.AddCoins(ctx, receiver, sdk.Coins{amount}) + if err != nil { + return err + } + + } else { + // unescrow tokens + escrowAddress := k.GetEscrowAddress(dstChan) + err := k.bk.SendCoins(ctx, escrowAddress, receiver, sdk.Coins{amount}) + if err != nil { + return err + } + } + + // build packet + packetData := types.TransferPacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } + + sequence := uint64(0) // unordered channel + packet := chantypes.NewPacket(sequence, timeout, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) + + _, err := k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, proofHeight, nil) + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrReceivePacket, "failed to receive packet") + } + + return nil +} + // GetEscrowAddress returns the escrow address for the specified channel func (k Keeper) GetEscrowAddress(chanID string) sdk.AccAddress { return sdk.AccAddress(crypto.AddressHash([]byte(chanID))) diff --git a/x/ibc/mock/bank/internal/types/errors.go b/x/ibc/mock/bank/internal/types/errors.go index bd4103ead9d1..4e8158743f0f 100644 --- a/x/ibc/mock/bank/internal/types/errors.go +++ b/x/ibc/mock/bank/internal/types/errors.go @@ -1,4 +1,3 @@ -//nolint package types import ( @@ -7,8 +6,10 @@ import ( // ibcmockbank errors reserve 100 ~ 199. const ( - CodeErrGetSequence sdk.CodeType = 100 - CodeErrSendPacket sdk.CodeType = 101 - CodeInvalidAmount sdk.CodeType = 102 - CodeInvalidAddress sdk.CodeType = 103 + CodeInvalidAmount sdk.CodeType = 101 + CodeInvalidAddress sdk.CodeType = 102 + CodeErrGetSequence sdk.CodeType = 103 + CodeErrSendPacket sdk.CodeType = 104 + CodeErrReceivePacket sdk.CodeType = 105 + CodeInvalidChannel sdk.CodeType = 106 ) diff --git a/x/ibc/mock/bank/internal/types/msgs.go b/x/ibc/mock/bank/internal/types/msgs.go index be2e89802b58..79218fc5f83f 100644 --- a/x/ibc/mock/bank/internal/types/msgs.go +++ b/x/ibc/mock/bank/internal/types/msgs.go @@ -2,29 +2,32 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) type MsgTransfer struct { - SrcPort string - SrcChannel string - DstPort string - DstChannel string - Amount sdk.Coin - Sender sdk.AccAddress - Receiver sdk.AccAddress - Source bool + SrcPort string + SrcChannel string + Amount sdk.Coin + Sender sdk.AccAddress + Receiver sdk.AccAddress + Source bool + Timeout uint64 + Proof ics23.Proof + ProofHeight uint64 } -func NewMsgTransfer(srcPort, srcChannel, dstPort, dstChannel string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool) MsgTransfer { +func NewMsgTransfer(srcPort, srcChannel string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) MsgTransfer { return MsgTransfer{ - SrcPort: srcPort, - SrcChannel: srcChannel, - DstPort: dstPort, - DstChannel: dstChannel, - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: source, + SrcPort: srcPort, + SrcChannel: srcChannel, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + Timeout: timeout, + Proof: proof, + ProofHeight: proofHeight, } } diff --git a/x/ibc/mock/bank/internal/types/packet.go b/x/ibc/mock/bank/internal/types/packet.go index f16f13e6f7f8..4bb1897db1f9 100644 --- a/x/ibc/mock/bank/internal/types/packet.go +++ b/x/ibc/mock/bank/internal/types/packet.go @@ -33,14 +33,6 @@ func (packet *TransferPacketData) UnmarshalJSON(bz []byte) (err error) { return MouduleCdc.UnmarshalJSON(bz, packet) } -func (TransferPacketData) SourcePort() string { - return "ibcmockbank" -} - -func (TransferPacketData) DestPort() string { - return "ibcmockbank" -} - func (packet TransferPacketData) String() string { return fmt.Sprintf(`TransferPacketData: Amount: %s From 87448ca9497bfd6142e3feea1fc9ce11fecf45d7 Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 15:31:25 +0800 Subject: [PATCH 05/12] add cli proof handling --- x/ibc/mock/bank/client/cli/flags.go | 16 ++++++++++------ x/ibc/mock/bank/client/cli/tx.go | 24 ++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/x/ibc/mock/bank/client/cli/flags.go b/x/ibc/mock/bank/client/cli/flags.go index d3bde99fc0b0..01a24cdb6405 100644 --- a/x/ibc/mock/bank/client/cli/flags.go +++ b/x/ibc/mock/bank/client/cli/flags.go @@ -5,12 +5,14 @@ import ( ) const ( - FlagSrcPort = "src-port" - FlagSrcChannel = "src-channel" - FlagAmount = "amount" - FlagReceiver = "receiver" - FlagSource = "source" - FlagTimeout = "timeout" + FlagSrcPort = "src-port" + FlagSrcChannel = "src-channel" + FlagAmount = "amount" + FlagReceiver = "receiver" + FlagSource = "source" + FlagTimeout = "timeout" + FlagProofPath = "proof-path" + FlagProofHeight = "proof-height" ) var ( @@ -24,4 +26,6 @@ func init() { FsTransfer.String(FlagReceiver, "", "the recipient") FsTransfer.Bool(FlagSource, true, "indicate if the sender is the source chain of the token") FsTransfer.Uint64(FlagTimeout, 0, "the block height after which the packet will expire") + FsTransfer.String(FlagProofPath, "", "the path of the proof file") + FsTransfer.Uint64(FlagProofHeight, 0, "the block height at which the proof is generated") } diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index 025ca68f2dd7..7494675a5ed0 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -1,6 +1,8 @@ package cli import ( + "io/ioutil" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -8,6 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" mockbank "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -28,7 +31,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { func TransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "transfer ", + Use: "transfer [proof-path] [proof-height]", Short: "Transfer", RunE: func(cmd *cobra.Command, args []string) error { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -51,7 +54,24 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { return err } - msg := mockbank.NewMsgTransfer(srcPort, srcChan, amount, sender, receiver, source, timeout, nil, 0) + var proof ics23.Proof + var proofHeight uint64 + + proofPath := viper.GetString(FlagProofPath) + if proofPath != "" { + proofBz, err := ioutil.ReadFile(proofPath) + if err != nil { + return err + } + + if err := cdc.UnmarshalJSON(proofBz, &proof); err != nil { + return err + } + + proofHeight = viper.GetUint64(FlagProofHeight) + } + + msg := mockbank.NewMsgTransfer(srcPort, srcChan, amount, sender, receiver, source, timeout, proof, proofHeight) if err := msg.ValidateBasic(); err != nil { return err } From d353e165004700329c6de0a02da65dceed0a6bec Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 15:37:41 +0800 Subject: [PATCH 06/12] modify cli --- x/ibc/mock/bank/client/cli/tx.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index 7494675a5ed0..32f71485e759 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -32,7 +32,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { func TransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "transfer [proof-path] [proof-height]", - Short: "Transfer", + Short: "Transfer tokens across chains through IBC", RunE: func(cmd *cobra.Command, args []string) error { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) @@ -80,6 +80,12 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { }, } + cmd.MarkFlagRequired(FlagSrcPort) + cmd.MarkFlagRequired(FlagSrcChannel) + cmd.MarkFlagRequired(FlagAmount) + cmd.MarkFlagRequired(FlagReceiver) + cmd.MarkFlagRequired(FlagTimeout) + cmd = client.PostCommands(cmd)[0] return cmd From 46ad32430505f32b1548ad1815cb59278c0a8fe9 Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 18:35:59 +0800 Subject: [PATCH 07/12] modify receiver type --- x/ibc/mock/bank/client/cli/tx.go | 9 +++------ x/ibc/mock/bank/internal/keeper/keeper.go | 15 ++++++++++----- x/ibc/mock/bank/internal/types/errors.go | 9 +++++---- x/ibc/mock/bank/internal/types/msgs.go | 6 +++--- x/ibc/mock/bank/internal/types/packet.go | 4 ++-- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index 32f71485e759..5453efa2e1e9 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -31,13 +31,15 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { func TransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "transfer [proof-path] [proof-height]", + Use: "transfer --src-port --src-channel --amount --receiver --source --timeout " + + "[--proof-path --proof-height ]", Short: "Transfer tokens across chains through IBC", RunE: func(cmd *cobra.Command, args []string) error { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) sender := ctx.GetFromAddress() + receiver := viper.GetString(FlagReceiver) srcPort := viper.GetString(FlagSrcPort) srcChan := viper.GetString(FlagSrcChannel) source := viper.GetBool(FlagSource) @@ -49,11 +51,6 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { return err } - receiver, err := sdk.AccAddressFromBech32(viper.GetString(FlagReceiver)) - if err != nil { - return err - } - var proof ics23.Proof var proofHeight uint64 diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index b4ea6a03bced..4fdb0ed98a1f 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -27,7 +27,7 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ibck ibc.Keeper, bk types.Ban } // SendTransfer handles transfer sending logic -func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64) sdk.Error { +func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64) sdk.Error { // get the port and channel of the counterparty channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) if !ok { @@ -78,7 +78,7 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sd } // ReceiveTransfer handles transfer receiving logic -func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) sdk.Error { +func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) sdk.Error { // get the port and channel of the counterparty channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) if !ok { @@ -88,9 +88,14 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount dstPort := channel.Counterparty.PortID dstChan := channel.Counterparty.ChannelID + receiverAddr, err := sdk.AccAddressFromBech32(receiver) + if err != nil { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidReceiver, "invalid receiver address") + } + if source { // mint tokens - _, err := k.bk.AddCoins(ctx, receiver, sdk.Coins{amount}) + _, err := k.bk.AddCoins(ctx, receiverAddr, sdk.Coins{amount}) if err != nil { return err } @@ -98,7 +103,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount } else { // unescrow tokens escrowAddress := k.GetEscrowAddress(dstChan) - err := k.bk.SendCoins(ctx, escrowAddress, receiver, sdk.Coins{amount}) + err := k.bk.SendCoins(ctx, escrowAddress, receiverAddr, sdk.Coins{amount}) if err != nil { return err } @@ -115,7 +120,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount sequence := uint64(0) // unordered channel packet := chantypes.NewPacket(sequence, timeout, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) - _, err := k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, proofHeight, nil) + _, err = k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, proofHeight, nil) if err != nil { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrReceivePacket, "failed to receive packet") } diff --git a/x/ibc/mock/bank/internal/types/errors.go b/x/ibc/mock/bank/internal/types/errors.go index 4e8158743f0f..34d01b64834c 100644 --- a/x/ibc/mock/bank/internal/types/errors.go +++ b/x/ibc/mock/bank/internal/types/errors.go @@ -8,8 +8,9 @@ import ( const ( CodeInvalidAmount sdk.CodeType = 101 CodeInvalidAddress sdk.CodeType = 102 - CodeErrGetSequence sdk.CodeType = 103 - CodeErrSendPacket sdk.CodeType = 104 - CodeErrReceivePacket sdk.CodeType = 105 - CodeInvalidChannel sdk.CodeType = 106 + CodeInvalidReceiver sdk.CodeType = 103 + CodeErrGetSequence sdk.CodeType = 104 + CodeErrSendPacket sdk.CodeType = 105 + CodeErrReceivePacket sdk.CodeType = 106 + CodeInvalidChannel sdk.CodeType = 107 ) diff --git a/x/ibc/mock/bank/internal/types/msgs.go b/x/ibc/mock/bank/internal/types/msgs.go index 79218fc5f83f..76dea3440222 100644 --- a/x/ibc/mock/bank/internal/types/msgs.go +++ b/x/ibc/mock/bank/internal/types/msgs.go @@ -10,14 +10,14 @@ type MsgTransfer struct { SrcChannel string Amount sdk.Coin Sender sdk.AccAddress - Receiver sdk.AccAddress + Receiver string Source bool Timeout uint64 Proof ics23.Proof ProofHeight uint64 } -func NewMsgTransfer(srcPort, srcChannel string, amount sdk.Coin, sender, receiver sdk.AccAddress, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) MsgTransfer { +func NewMsgTransfer(srcPort, srcChannel string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) MsgTransfer { return MsgTransfer{ SrcPort: srcPort, SrcChannel: srcChannel, @@ -44,7 +44,7 @@ func (msg MsgTransfer) ValidateBasic() sdk.Error { return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAmount, "invalid amount") } - if msg.Sender.Empty() || msg.Receiver.Empty() { + if msg.Sender.Empty() || len(msg.Receiver) == 0 { return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAddress, "invalid address") } diff --git a/x/ibc/mock/bank/internal/types/packet.go b/x/ibc/mock/bank/internal/types/packet.go index 4bb1897db1f9..994e64aca621 100644 --- a/x/ibc/mock/bank/internal/types/packet.go +++ b/x/ibc/mock/bank/internal/types/packet.go @@ -9,7 +9,7 @@ import ( type TransferPacketData struct { Amount sdk.Coin Sender sdk.AccAddress - Receiver sdk.AccAddress + Receiver string Source bool } @@ -41,7 +41,7 @@ func (packet TransferPacketData) String() string { Source: %v`, packet.Amount.String(), packet.Sender.String(), - packet.Receiver.String(), + packet.Receiver, packet.Source, ) } From 3531e3ef68193b71f42b752958fe11df47814515 Mon Sep 17 00:00:00 2001 From: secret Date: Wed, 16 Oct 2019 19:16:51 +0800 Subject: [PATCH 08/12] modify errcode --- x/ibc/mock/bank/internal/keeper/keeper.go | 6 +++--- x/ibc/mock/bank/internal/types/errors.go | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index 4fdb0ed98a1f..d35b5ef9410b 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -31,7 +31,7 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sd // get the port and channel of the counterparty channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidChannel, "failed to get channel") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeChannelNotFound, "failed to get channel") } dstPort := channel.Counterparty.PortID @@ -40,7 +40,7 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sd // get the next sequence sequence, ok := k.ibck.ChannelKeeper.GetNextSequenceSend(ctx, srcPort, srcChan) if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrGetSequence, "failed to retrieve sequence") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeSequenceNotFound, "failed to retrieve sequence") } if source { @@ -82,7 +82,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount // get the port and channel of the counterparty channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidChannel, "failed to get channel") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeChannelNotFound, "failed to get channel") } dstPort := channel.Counterparty.PortID diff --git a/x/ibc/mock/bank/internal/types/errors.go b/x/ibc/mock/bank/internal/types/errors.go index 34d01b64834c..d7a09ec89f12 100644 --- a/x/ibc/mock/bank/internal/types/errors.go +++ b/x/ibc/mock/bank/internal/types/errors.go @@ -9,8 +9,6 @@ const ( CodeInvalidAmount sdk.CodeType = 101 CodeInvalidAddress sdk.CodeType = 102 CodeInvalidReceiver sdk.CodeType = 103 - CodeErrGetSequence sdk.CodeType = 104 - CodeErrSendPacket sdk.CodeType = 105 - CodeErrReceivePacket sdk.CodeType = 106 - CodeInvalidChannel sdk.CodeType = 107 + CodeErrSendPacket sdk.CodeType = 104 + CodeErrReceivePacket sdk.CodeType = 105 ) From a26369bee009a58a865474d6f4d69877bc36b766 Mon Sep 17 00:00:00 2001 From: secret Date: Fri, 18 Oct 2019 14:04:33 +0800 Subject: [PATCH 09/12] optimize codes --- x/ibc/mock/bank/alias.go | 8 +- x/ibc/mock/bank/client/cli/flags.go | 22 ++-- x/ibc/mock/bank/client/cli/tx.go | 36 ++---- x/ibc/mock/bank/handler.go | 40 +++++-- x/ibc/mock/bank/internal/keeper/keeper.go | 138 ++++++++++++++-------- x/ibc/mock/bank/internal/types/codec.go | 2 + x/ibc/mock/bank/internal/types/errors.go | 13 +- x/ibc/mock/bank/internal/types/msgs.go | 93 +++++++++++---- x/ibc/mock/bank/internal/types/packet.go | 113 +++++++++++++++--- 9 files changed, 310 insertions(+), 155 deletions(-) diff --git a/x/ibc/mock/bank/alias.go b/x/ibc/mock/bank/alias.go index 98480c482287..31d5145a011b 100644 --- a/x/ibc/mock/bank/alias.go +++ b/x/ibc/mock/bank/alias.go @@ -7,8 +7,9 @@ import ( // nolint type ( - MsgTransfer = types.MsgTransfer - Keeper = keeper.Keeper + MsgTransfer = types.MsgTransfer + MsgSendTransferPacket = types.MsgSendTransferPacket + Keeper = keeper.Keeper ) // nolint @@ -21,5 +22,6 @@ var ( RegisterCdc = types.RegisterCodec - NewMsgTransfer = types.NewMsgTransfer + NewMsgTransfer = types.NewMsgTransfer + NewMsgSendTransferPacket = types.NewMsgSendTransferPacket ) diff --git a/x/ibc/mock/bank/client/cli/flags.go b/x/ibc/mock/bank/client/cli/flags.go index 01a24cdb6405..24218867aa86 100644 --- a/x/ibc/mock/bank/client/cli/flags.go +++ b/x/ibc/mock/bank/client/cli/flags.go @@ -5,14 +5,12 @@ import ( ) const ( - FlagSrcPort = "src-port" - FlagSrcChannel = "src-channel" - FlagAmount = "amount" - FlagReceiver = "receiver" - FlagSource = "source" - FlagTimeout = "timeout" - FlagProofPath = "proof-path" - FlagProofHeight = "proof-height" + FlagSrcPort = "src-port" + FlagSrcChannel = "src-channel" + FlagDenom = "denom" + FlagAmount = "amount" + FlagReceiver = "receiver" + FlagSource = "source" ) var ( @@ -22,10 +20,8 @@ var ( func init() { FsTransfer.String(FlagSrcPort, "", "the source port ID") FsTransfer.String(FlagSrcChannel, "", "the source channel ID") - FsTransfer.String(FlagAmount, "", "the amount to be transferred") + FsTransfer.String(FlagDenom, "", "the denomination of the token to be transferred") + FsTransfer.String(FlagAmount, "", "the amount of the token to be transferred") FsTransfer.String(FlagReceiver, "", "the recipient") - FsTransfer.Bool(FlagSource, true, "indicate if the sender is the source chain of the token") - FsTransfer.Uint64(FlagTimeout, 0, "the block height after which the packet will expire") - FsTransfer.String(FlagProofPath, "", "the path of the proof file") - FsTransfer.Uint64(FlagProofHeight, 0, "the block height at which the proof is generated") + FsTransfer.Bool(FlagSource, true, "indicate if the sending chain is the source chain of the token") } diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index 5453efa2e1e9..b7f29247ce81 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -1,7 +1,7 @@ package cli import ( - "io/ioutil" + "fmt" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -10,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" mockbank "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -31,8 +30,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { func TransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "transfer --src-port --src-channel --amount --receiver --source --timeout " + - "[--proof-path --proof-height ]", + Use: "transfer --src-port --src-channel --denom --amount --receiver --source ", Short: "Transfer tokens across chains through IBC", RunE: func(cmd *cobra.Command, args []string) error { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -40,35 +38,17 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { sender := ctx.GetFromAddress() receiver := viper.GetString(FlagReceiver) + denom := viper.GetString(FlagDenom) srcPort := viper.GetString(FlagSrcPort) srcChan := viper.GetString(FlagSrcChannel) source := viper.GetBool(FlagSource) - timeout := viper.GetUint64(FlagTimeout) - amountStr := viper.GetString(FlagAmount) - amount, err := sdk.ParseCoin(amountStr) - if err != nil { - return err - } - - var proof ics23.Proof - var proofHeight uint64 - - proofPath := viper.GetString(FlagProofPath) - if proofPath != "" { - proofBz, err := ioutil.ReadFile(proofPath) - if err != nil { - return err - } - - if err := cdc.UnmarshalJSON(proofBz, &proof); err != nil { - return err - } - - proofHeight = viper.GetUint64(FlagProofHeight) + amount, ok := sdk.NewIntFromString(viper.GetString(FlagAmount)) + if !ok { + return fmt.Errorf("invalid amount") } - msg := mockbank.NewMsgTransfer(srcPort, srcChan, amount, sender, receiver, source, timeout, proof, proofHeight) + msg := mockbank.NewMsgTransfer(srcPort, srcChan, denom, amount, sender, receiver, source) if err := msg.ValidateBasic(); err != nil { return err } @@ -79,9 +59,9 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd.MarkFlagRequired(FlagSrcPort) cmd.MarkFlagRequired(FlagSrcChannel) + cmd.MarkFlagRequired(FlagDenom) cmd.MarkFlagRequired(FlagAmount) cmd.MarkFlagRequired(FlagReceiver) - cmd.MarkFlagRequired(FlagTimeout) cmd = client.PostCommands(cmd)[0] diff --git a/x/ibc/mock/bank/handler.go b/x/ibc/mock/bank/handler.go index f7e0834dbe08..d145d2357eb6 100644 --- a/x/ibc/mock/bank/handler.go +++ b/x/ibc/mock/bank/handler.go @@ -2,6 +2,7 @@ package mockbank import ( sdk "github.com/cosmos/cosmos-sdk/types" + ics04 "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) func NewHandler(k Keeper) sdk.Handler { @@ -9,6 +10,8 @@ func NewHandler(k Keeper) sdk.Handler { switch msg := msg.(type) { case MsgTransfer: return handleMsgTransfer(ctx, k, msg) + case MsgSendTransferPacket: + return handleMsgSendTransferPacket(ctx, k, msg) default: return sdk.ErrUnknownRequest("failed to parse message").Result() } @@ -16,18 +19,31 @@ func NewHandler(k Keeper) sdk.Handler { } func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { - if msg.Proof != nil { - // send packet - err := k.SendTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source, msg.Timeout) - if err != nil { - return err.Result() - } - } else { - // receive packet - err := k.ReceiveTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source, msg.Timeout, msg.Proof, msg.ProofHeight) - if err != nil { - return err.Result() - } + err := k.SendTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Denomination, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + if err != nil { + return err.Result() + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + ics04.EventTypeSendPacket, + sdk.NewAttribute(ics04.AttributeKeySenderPort, msg.SrcPort), + sdk.NewAttribute(ics04.AttributeKeyChannelID, msg.SrcChannel), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, ics04.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +func handleMsgSendTransferPacket(ctx sdk.Context, k Keeper, msg MsgSendTransferPacket) (res sdk.Result) { + err := k.ReceiveTransfer(ctx, msg.Packet, msg.Proofs[0], msg.Height) + if err != nil { + return err.Result() } return sdk.Result{Events: ctx.EventManager().Events()} diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index d35b5ef9410b..46f950a20ea1 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -1,15 +1,23 @@ package keeper import ( + "fmt" + "strings" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc" - chantypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + ics04 "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/types" "github.com/tendermint/tendermint/crypto" ) +const ( + DefaultPacketTimeout = 1000 // default packet timeout relative to the current block height +) + type Keeper struct { cdc *codec.Codec key sdk.StoreKey @@ -27,11 +35,11 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ibck ibc.Keeper, bk types.Ban } // SendTransfer handles transfer sending logic -func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64) sdk.Error { +func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, denom string, amount sdk.Int, sender sdk.AccAddress, receiver string, source bool) sdk.Error { // get the port and channel of the counterparty channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeChannelNotFound, "failed to get channel") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), ics04.CodeChannelNotFound, "failed to get channel") } dstPort := channel.Counterparty.PortID @@ -40,70 +48,91 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, amount sd // get the next sequence sequence, ok := k.ibck.ChannelKeeper.GetNextSequenceSend(ctx, srcPort, srcChan) if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeSequenceNotFound, "failed to retrieve sequence") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), ics04.CodeSequenceNotFound, "failed to retrieve sequence") } - if source { - // escrow tokens - escrowAddress := k.GetEscrowAddress(srcChan) - err := k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{amount}) - if err != nil { - return err + return k.createOutgoingPacket(ctx, sequence, srcPort, srcChan, dstPort, dstChan, denom, amount, sender, receiver, source) +} + +// ReceiveTransfer handles transfer receiving logic +func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet exported.PacketI, proof ics23.Proof, height uint64) sdk.Error { + _, err := k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, height, nil) + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrReceivePacket, "failed to receive packet") + } + + var data types.TransferPacketData + err = data.UnmarshalJSON(packet.Data()) + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + } + + receiverAddr, err := sdk.AccAddressFromBech32(data.Receiver) + if err != nil { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidReceiver, "invalid receiver address") + } + + if data.Source { + // mint tokens + + // check the denom prefix + prefix := fmt.Sprintf("%s/%s", packet.DestPort(), packet.DestChannel()) + if !strings.HasPrefix(data.Denomination, prefix) { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } - } else { - // burn vouchers from sender - err := k.bk.BurnCoins(ctx, sender, sdk.Coins{amount}) + _, err := k.bk.AddCoins(ctx, receiverAddr, sdk.Coins{sdk.NewCoin(data.Denomination, data.Amount)}) if err != nil { return err } - } - // build packet - packetData := types.TransferPacketData{ - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: source, - } + } else { + // unescrow tokens - packet := chantypes.NewPacket(sequence, timeout, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) + // check the denom prefix + prefix := fmt.Sprintf("%s/%s", packet.SourcePort(), packet.SourceChannel()) + if !strings.HasPrefix(data.Denomination, prefix) { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + } - err := k.ibck.ChannelKeeper.SendPacket(ctx, packet) - if err != nil { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrSendPacket, "failed to send packet") + escrowAddress := k.GetEscrowAddress(packet.DestChannel()) + err := k.bk.SendCoins(ctx, escrowAddress, receiverAddr, sdk.Coins{sdk.NewCoin(data.Denomination[len(prefix):], data.Amount)}) + if err != nil { + return err + } } return nil } -// ReceiveTransfer handles transfer receiving logic -func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) sdk.Error { - // get the port and channel of the counterparty - channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) - if !ok { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), chantypes.CodeChannelNotFound, "failed to get channel") - } +func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcChan, dstPort, dstChan string, denom string, amount sdk.Int, sender sdk.AccAddress, receiver string, source bool) sdk.Error { + if source { + // escrow tokens - dstPort := channel.Counterparty.PortID - dstChan := channel.Counterparty.ChannelID + // get escrow address + escrowAddress := k.GetEscrowAddress(srcChan) - receiverAddr, err := sdk.AccAddressFromBech32(receiver) - if err != nil { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidReceiver, "invalid receiver address") - } + // check the denom prefix + prefix := fmt.Sprintf("%s/%s", dstPort, dstChan) + if !strings.HasPrefix(denom, prefix) { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + } - if source { - // mint tokens - _, err := k.bk.AddCoins(ctx, receiverAddr, sdk.Coins{amount}) + err := k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{sdk.NewCoin(denom[len(prefix):], amount)}) if err != nil { return err } } else { - // unescrow tokens - escrowAddress := k.GetEscrowAddress(dstChan) - err := k.bk.SendCoins(ctx, escrowAddress, receiverAddr, sdk.Coins{amount}) + // burn vouchers from sender + + // check the denom prefix + prefix := fmt.Sprintf("%s/%s", srcPort, srcChan) + if !strings.HasPrefix(denom, prefix) { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + } + + err := k.bk.BurnCoins(ctx, sender, sdk.Coins{sdk.NewCoin(denom, amount)}) if err != nil { return err } @@ -111,18 +140,23 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, srcPort, srcChan string, amount // build packet packetData := types.TransferPacketData{ - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: source, + Denomination: denom, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } + + packetDataBz, err := packetData.MarshalJSON() + if err != nil { + sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") } - sequence := uint64(0) // unordered channel - packet := chantypes.NewPacket(sequence, timeout, srcPort, srcChan, dstPort, dstChan, packetData.Marshal()) + packet := types.NewPacket(seq, uint64(ctx.BlockHeight())+DefaultPacketTimeout, srcPort, srcChan, dstPort, dstChan, packetDataBz) - _, err = k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, proofHeight, nil) + err = k.ibck.ChannelKeeper.SendPacket(ctx, packet) if err != nil { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrReceivePacket, "failed to receive packet") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrSendPacket, "failed to send packet") } return nil diff --git a/x/ibc/mock/bank/internal/types/codec.go b/x/ibc/mock/bank/internal/types/codec.go index 199638b18e54..84ccb87b88aa 100644 --- a/x/ibc/mock/bank/internal/types/codec.go +++ b/x/ibc/mock/bank/internal/types/codec.go @@ -5,8 +5,10 @@ import ( ) func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(Packet{}, "ibcmockbank/Packet", nil) cdc.RegisterConcrete(TransferPacketData{}, "ibcmockbank/TransferPacketData", nil) cdc.RegisterConcrete(MsgTransfer{}, "ibcmockbank/MsgTransfer", nil) + cdc.RegisterConcrete(MsgSendTransferPacket{}, "ibcmockbank/MsgSendTransferPacket", nil) } var MouduleCdc = codec.New() diff --git a/x/ibc/mock/bank/internal/types/errors.go b/x/ibc/mock/bank/internal/types/errors.go index d7a09ec89f12..52582daccfe0 100644 --- a/x/ibc/mock/bank/internal/types/errors.go +++ b/x/ibc/mock/bank/internal/types/errors.go @@ -6,9 +6,12 @@ import ( // ibcmockbank errors reserve 100 ~ 199. const ( - CodeInvalidAmount sdk.CodeType = 101 - CodeInvalidAddress sdk.CodeType = 102 - CodeInvalidReceiver sdk.CodeType = 103 - CodeErrSendPacket sdk.CodeType = 104 - CodeErrReceivePacket sdk.CodeType = 105 + CodeIncorrectDenom sdk.CodeType = 101 + CodeInvalidAmount sdk.CodeType = 102 + CodeInvalidAddress sdk.CodeType = 103 + CodeInvalidReceiver sdk.CodeType = 104 + CodeErrSendPacket sdk.CodeType = 105 + CodeErrReceivePacket sdk.CodeType = 106 + CodeProofMissing sdk.CodeType = 107 + CodeInvalidPacketData sdk.CodeType = 108 ) diff --git a/x/ibc/mock/bank/internal/types/msgs.go b/x/ibc/mock/bank/internal/types/msgs.go index 76dea3440222..fc5392c733a9 100644 --- a/x/ibc/mock/bank/internal/types/msgs.go +++ b/x/ibc/mock/bank/internal/types/msgs.go @@ -2,32 +2,41 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + ics04 "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +const ( + TypeMsgTransfer = "transfer" + TypeMsgSendTransferPacket = "send-transfer-packet" +) + type MsgTransfer struct { - SrcPort string - SrcChannel string - Amount sdk.Coin - Sender sdk.AccAddress - Receiver string - Source bool - Timeout uint64 - Proof ics23.Proof - ProofHeight uint64 -} - -func NewMsgTransfer(srcPort, srcChannel string, amount sdk.Coin, sender sdk.AccAddress, receiver string, source bool, timeout uint64, proof ics23.Proof, proofHeight uint64) MsgTransfer { + SrcPort string `json:"src_port" yaml:"src_port"` + SrcChannel string `json:"src_channel" yaml:"src_channel"` + Denomination string `json:"denomination" yaml:"denomination"` + Amount sdk.Int `json:"amount" yaml:"amount"` + Sender sdk.AccAddress `json:"sender" yaml:"sender"` + Receiver string `json:"receiver" yaml:"receiver"` + Source bool `json:"source" yaml:"source"` +} +type MsgSendTransferPacket struct { + Packet ics04.PacketI `json:"packet" yaml:"packet"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Proofs []ics23.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +func NewMsgTransfer(srcPort, srcChannel string, denom string, amount sdk.Int, sender sdk.AccAddress, receiver string, source bool) MsgTransfer { return MsgTransfer{ - SrcPort: srcPort, - SrcChannel: srcChannel, - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: source, - Timeout: timeout, - Proof: proof, - ProofHeight: proofHeight, + SrcPort: srcPort, + SrcChannel: srcChannel, + Denomination: denom, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, } } @@ -36,11 +45,11 @@ func (MsgTransfer) Route() string { } func (MsgTransfer) Type() string { - return "transfer" + return TypeMsgTransfer } func (msg MsgTransfer) ValidateBasic() sdk.Error { - if !msg.Amount.IsValid() { + if !msg.Amount.IsPositive() { return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAmount, "invalid amount") } @@ -58,3 +67,41 @@ func (msg MsgTransfer) GetSignBytes() []byte { func (msg MsgTransfer) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } + +func NewMsgSendTransferPacket(packet ics04.PacketI, channelID string, proofs []ics23.Proof, height uint64, signer sdk.AccAddress) MsgSendTransferPacket { + return MsgSendTransferPacket{ + Packet: packet, + ChannelID: channelID, + Proofs: proofs, + Height: height, + Signer: signer, + } +} + +func (MsgSendTransferPacket) Route() string { + return RouterKey +} + +func (MsgSendTransferPacket) Type() string { + return TypeMsgSendTransferPacket +} + +func (msg MsgSendTransferPacket) ValidateBasic() sdk.Error { + if msg.Proofs == nil { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeProofMissing, "proof missing") + } + + if msg.Signer.Empty() { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAddress, "invalid signer") + } + + return nil +} + +func (msg MsgSendTransferPacket) GetSignBytes() []byte { + return sdk.MustSortJSON(MouduleCdc.MustMarshalJSON(msg)) +} + +func (msg MsgSendTransferPacket) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/mock/bank/internal/types/packet.go b/x/ibc/mock/bank/internal/types/packet.go index 994e64aca621..c1b8fdbb9e6b 100644 --- a/x/ibc/mock/bank/internal/types/packet.go +++ b/x/ibc/mock/bank/internal/types/packet.go @@ -4,44 +4,119 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ) +var _ exported.PacketI = Packet{} + +// Packet defines a type that carries data across different chains through IBC +type Packet struct { + sequence uint64 // number corresponds to the order of sends and receives, where a packet with an earlier sequence number must be sent and received before a packet with a later sequence number. + timeout uint64 // indicates a consensus height on the destination chain after which the packet will no longer be processed, and will instead count as having timed-out. + sourcePort string // identifies the port on the sending chain. + sourceChannel string // identifies the channel end on the sending chain. + destinationPort string // identifies the port on the receiving chain. + destinationChannel string // identifies the channel end on the receiving chain. + data []byte // opaque value which can be defined by the application logic of the associated modules. +} + +// newPacket creates a new Packet instance +func NewPacket( + sequence, timeout uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, data []byte, +) Packet { + return Packet{ + sequence, + timeout, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + data, + } +} + +// Sequence implements PacketI interface +func (p Packet) Sequence() uint64 { return p.sequence } + +// TimeoutHeight implements PacketI interface +func (p Packet) TimeoutHeight() uint64 { return p.timeout } + +// SourcePort implements PacketI interface +func (p Packet) SourcePort() string { return p.sourcePort } + +// SourceChannel implements PacketI interface +func (p Packet) SourceChannel() string { return p.sourceChannel } + +// DestPort implements PacketI interface +func (p Packet) DestPort() string { return p.destinationPort } + +// DestChannel implements PacketI interface +func (p Packet) DestChannel() string { return p.destinationChannel } + +// Data implements PacketI interface +func (p Packet) Data() []byte { return p.data } + +func (p Packet) MarshalJSON() ([]byte, error) { + return MouduleCdc.MarshalJSON(p) +} + +func (p *Packet) UnmarshalJSON(bz []byte) (err error) { + return MouduleCdc.UnmarshalJSON(bz, p) +} + +// TransferPacketData defines a struct for the packet payload type TransferPacketData struct { - Amount sdk.Coin - Sender sdk.AccAddress - Receiver string - Source bool + Denomination string `json:"denomination" yaml:"denomination"` + Amount sdk.Int `json:"amount" yaml:"amount"` + Sender sdk.AccAddress `json:"sender" yaml:"sender"` + Receiver string `json:"receiver" yaml:"receiver"` + Source bool `json:"source" yaml:"source"` } -func (packet TransferPacketData) MarshalAmino() ([]byte, error) { - return MouduleCdc.MarshalBinaryBare(packet) +func (tpd TransferPacketData) MarshalAmino() ([]byte, error) { + return MouduleCdc.MarshalBinaryBare(tpd) } -func (packet *TransferPacketData) UnmarshalAmino(bz []byte) (err error) { - return MouduleCdc.UnmarshalBinaryBare(bz, packet) +func (tpd *TransferPacketData) UnmarshalAmino(bz []byte) (err error) { + return MouduleCdc.UnmarshalBinaryBare(bz, tpd) } -func (packet TransferPacketData) Marshal() []byte { - return MouduleCdc.MustMarshalBinaryBare(packet) +func (tpd TransferPacketData) Marshal() []byte { + return MouduleCdc.MustMarshalBinaryBare(tpd) } -func (packet TransferPacketData) MarshalJSON() ([]byte, error) { - return MouduleCdc.MarshalJSON(packet) +func (tpd TransferPacketData) MarshalJSON() ([]byte, error) { + return MouduleCdc.MarshalJSON(tpd) } -func (packet *TransferPacketData) UnmarshalJSON(bz []byte) (err error) { - return MouduleCdc.UnmarshalJSON(bz, packet) +func (tpd *TransferPacketData) UnmarshalJSON(bz []byte) (err error) { + return MouduleCdc.UnmarshalJSON(bz, tpd) } -func (packet TransferPacketData) String() string { +func (tpd TransferPacketData) String() string { return fmt.Sprintf(`TransferPacketData: + Denomination %s Amount: %s Sender: %s Receiver: %s Source: %v`, - packet.Amount.String(), - packet.Sender.String(), - packet.Receiver, - packet.Source, + tpd.Denomination, + tpd.Amount.String(), + tpd.Sender.String(), + tpd.Receiver, + tpd.Source, ) } + +func (tpd TransferPacketData) Validate() error { + if !tpd.Amount.IsPositive() { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAmount, "invalid amount") + } + + if tpd.Sender.Empty() || len(tpd.Receiver) == 0 { + return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeInvalidAddress, "invalid address") + } + + return nil +} From 3052ed5656889c29f05a91cec31001ef8fb8dcee Mon Sep 17 00:00:00 2001 From: secret Date: Fri, 18 Oct 2019 14:44:36 +0800 Subject: [PATCH 10/12] add denom prefix when source is true --- x/ibc/mock/bank/internal/keeper/keeper.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index 46f950a20ea1..fd653bd1992f 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -51,6 +51,12 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, denom str return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), ics04.CodeSequenceNotFound, "failed to retrieve sequence") } + if source { + // build the receiving denomination prefix + prefix := fmt.Sprintf("%s/%s", dstPort, dstChan) + denom = prefix + denom + } + return k.createOutgoingPacket(ctx, sequence, srcPort, srcChan, dstPort, dstChan, denom, amount, sender, receiver, source) } From 8daa378af9bad5113e7cef1e134d9233dbcb2a88 Mon Sep 17 00:00:00 2001 From: chengwenxi Date: Mon, 21 Oct 2019 00:17:34 +0800 Subject: [PATCH 11/12] refactor code --- x/ibc/04-channel/types/events.go | 1 + x/ibc/client/cli/cli.go | 2 + x/ibc/mock/bank/alias.go | 11 +-- x/ibc/mock/bank/client/cli/tx.go | 67 +++++++++++++++++-- x/ibc/mock/bank/handler.go | 16 ++--- x/ibc/mock/bank/internal/keeper/keeper.go | 39 ++++++----- x/ibc/mock/bank/internal/types/codec.go | 8 ++- .../bank/internal/types/expected_keepers.go | 23 +++++-- x/ibc/mock/bank/internal/types/msgs.go | 38 +++++------ x/ibc/mock/bank/module.go | 8 ++- 10 files changed, 150 insertions(+), 63 deletions(-) diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go index 7b81f1033285..6bebb576887e 100644 --- a/x/ibc/04-channel/types/events.go +++ b/x/ibc/04-channel/types/events.go @@ -12,6 +12,7 @@ const ( AttributeKeyReceiverPort = "receiver_port" AttributeKeyChannelID = "channel_id" AttributeKeySequence = "sequence" + AttributeKeyPacket = "Packet" ) // IBC channel events vars diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 4e25e3ce508f..e6163dfc7d57 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + mockbank "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -23,6 +24,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcTxCmd.AddCommand( ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), + mockbank.GetTxCmd(cdc), ) return ibcTxCmd } diff --git a/x/ibc/mock/bank/alias.go b/x/ibc/mock/bank/alias.go index 31d5145a011b..230489e7099c 100644 --- a/x/ibc/mock/bank/alias.go +++ b/x/ibc/mock/bank/alias.go @@ -8,20 +8,23 @@ import ( // nolint type ( MsgTransfer = types.MsgTransfer - MsgSendTransferPacket = types.MsgSendTransferPacket + MsgRecvTransferPacket = types.MsgRecvTransferPacket Keeper = keeper.Keeper ) -// nolint -var ( +const ( ModuleName = types.ModuleName StoreKey = types.StoreKey TStoreKey = types.TStoreKey QuerierRoute = types.QuerierRoute RouterKey = types.RouterKey +) +// nolint +var ( RegisterCdc = types.RegisterCodec + NewKeeper = keeper.NewKeeper NewMsgTransfer = types.NewMsgTransfer - NewMsgSendTransferPacket = types.NewMsgSendTransferPacket + NewMsgRecvTransferPacket = types.NewMsgRecvTransferPacket ) diff --git a/x/ibc/mock/bank/client/cli/tx.go b/x/ibc/mock/bank/client/cli/tx.go index b7f29247ce81..a7d96935a0ff 100644 --- a/x/ibc/mock/bank/client/cli/tx.go +++ b/x/ibc/mock/bank/client/cli/tx.go @@ -2,6 +2,9 @@ package cli import ( "fmt" + "io/ioutil" + "os" + "strconv" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -10,7 +13,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - mockbank "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank" + ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/mock/bank/internal/types" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -22,13 +26,14 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { // RunE: client.ValidateCmd, } txCmd.AddCommand( - TransferTxCmd(cdc), + GetTransferTxCmd(cdc), + GetMsgRecvPacketCmd(cdc), ) return txCmd } -func TransferTxCmd(cdc *codec.Codec) *cobra.Command { +func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "transfer --src-port --src-channel --denom --amount --receiver --source ", Short: "Transfer tokens across chains through IBC", @@ -48,7 +53,7 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { return fmt.Errorf("invalid amount") } - msg := mockbank.NewMsgTransfer(srcPort, srcChan, denom, amount, sender, receiver, source) + msg := types.NewMsgTransfer(srcPort, srcChan, denom, amount, sender, receiver, source) if err := msg.ValidateBasic(); err != nil { return err } @@ -57,6 +62,8 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { }, } + cmd.Flags().AddFlagSet(FsTransfer) + cmd.MarkFlagRequired(FlagSrcPort) cmd.MarkFlagRequired(FlagSrcChannel) cmd.MarkFlagRequired(FlagDenom) @@ -67,3 +74,55 @@ func TransferTxCmd(cdc *codec.Codec) *cobra.Command { return cmd } + +// GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction +func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "recv-packet [/path/to/packet-data.json] [/path/to/proof.json] [height]", + Short: "Creates and sends a SendPacket message", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + var packet types.Packet + if err := cdc.UnmarshalJSON([]byte(args[0]), &packet); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...\n") + contents, err := ioutil.ReadFile(args[0]) + if err != nil { + return fmt.Errorf("error opening packet file: %v", err) + } + if err := packet.UnmarshalJSON(contents); err != nil { + return fmt.Errorf("error unmarshalling packet file: %v", err) + } + } + + var proof ics23.Proof + if err := cdc.UnmarshalJSON([]byte(args[1]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...\n") + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proofs file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proofs file: %v", err) + } + } + + height, err := strconv.ParseUint(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error height: %v", err) + } + + msg := types.NewMsgRecvTransferPacket(packet, []ics23.Proof{proof}, height, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd = client.PostCommands(cmd)[0] + return cmd +} diff --git a/x/ibc/mock/bank/handler.go b/x/ibc/mock/bank/handler.go index d145d2357eb6..efe2bf9f5f8b 100644 --- a/x/ibc/mock/bank/handler.go +++ b/x/ibc/mock/bank/handler.go @@ -10,8 +10,8 @@ func NewHandler(k Keeper) sdk.Handler { switch msg := msg.(type) { case MsgTransfer: return handleMsgTransfer(ctx, k, msg) - case MsgSendTransferPacket: - return handleMsgSendTransferPacket(ctx, k, msg) + case MsgRecvTransferPacket: + return handleMsgRecvTransferPacket(ctx, k, msg) default: return sdk.ErrUnknownRequest("failed to parse message").Result() } @@ -24,23 +24,17 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Resu return err.Result() } - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - ics04.EventTypeSendPacket, - sdk.NewAttribute(ics04.AttributeKeySenderPort, msg.SrcPort), - sdk.NewAttribute(ics04.AttributeKeyChannelID, msg.SrcChannel), - ), + ctx.EventManager().EmitEvent( sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, ics04.AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), - ), - }) + )) return sdk.Result{Events: ctx.EventManager().Events()} } -func handleMsgSendTransferPacket(ctx sdk.Context, k Keeper, msg MsgSendTransferPacket) (res sdk.Result) { +func handleMsgRecvTransferPacket(ctx sdk.Context, k Keeper, msg MsgRecvTransferPacket) (res sdk.Result) { err := k.ReceiveTransfer(ctx, msg.Packet, msg.Proofs[0], msg.Height) if err != nil { return err.Result() diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index fd653bd1992f..2490c607349a 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ics04 "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -19,25 +18,25 @@ const ( ) type Keeper struct { - cdc *codec.Codec - key sdk.StoreKey - ibck ibc.Keeper - bk types.BankKeeper + cdc *codec.Codec + key sdk.StoreKey + ck types.ChannelKeeper + bk types.BankKeeper } -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ibck ibc.Keeper, bk types.BankKeeper) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ck types.ChannelKeeper, bk types.BankKeeper) Keeper { return Keeper{ - cdc: cdc, - key: key, - ibck: ibck, - bk: bk, + cdc: cdc, + key: key, + ck: ck, + bk: bk, } } // SendTransfer handles transfer sending logic func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, denom string, amount sdk.Int, sender sdk.AccAddress, receiver string, source bool) sdk.Error { // get the port and channel of the counterparty - channel, ok := k.ibck.ChannelKeeper.GetChannel(ctx, srcPort, srcChan) + channel, ok := k.ck.GetChannel(ctx, srcPort, srcChan) if !ok { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), ics04.CodeChannelNotFound, "failed to get channel") } @@ -46,7 +45,7 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, denom str dstChan := channel.Counterparty.ChannelID // get the next sequence - sequence, ok := k.ibck.ChannelKeeper.GetNextSequenceSend(ctx, srcPort, srcChan) + sequence, ok := k.ck.GetNextSequenceSend(ctx, srcPort, srcChan) if !ok { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), ics04.CodeSequenceNotFound, "failed to retrieve sequence") } @@ -62,7 +61,7 @@ func (k Keeper) SendTransfer(ctx sdk.Context, srcPort, srcChan string, denom str // ReceiveTransfer handles transfer receiving logic func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet exported.PacketI, proof ics23.Proof, height uint64) sdk.Error { - _, err := k.ibck.ChannelKeeper.RecvPacket(ctx, packet, proof, height, nil) + _, err := k.ck.RecvPacket(ctx, packet, proof, height, nil) if err != nil { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrReceivePacket, "failed to receive packet") } @@ -75,7 +74,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet exported.PacketI, proof receiverAddr, err := sdk.AccAddressFromBech32(data.Receiver) if err != nil { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidReceiver, "invalid receiver address") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidReceiver, "invalid receiver address") } if data.Source { @@ -138,7 +137,7 @@ func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcCh sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } - err := k.bk.BurnCoins(ctx, sender, sdk.Coins{sdk.NewCoin(denom, amount)}) + _, err := k.bk.SubtractCoins(ctx, sender, sdk.Coins{sdk.NewCoin(denom, amount)}) if err != nil { return err } @@ -160,11 +159,19 @@ func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcCh packet := types.NewPacket(seq, uint64(ctx.BlockHeight())+DefaultPacketTimeout, srcPort, srcChan, dstPort, dstChan, packetDataBz) - err = k.ibck.ChannelKeeper.SendPacket(ctx, packet) + err = k.ck.SendPacket(ctx, packet) if err != nil { return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeErrSendPacket, "failed to send packet") } + packetJson, _ := packet.MarshalJSON() + ctx.EventManager().EmitEvent(sdk.NewEvent( + ics04.EventTypeSendPacket, + sdk.NewAttribute(ics04.AttributeKeySenderPort, srcPort), + sdk.NewAttribute(ics04.AttributeKeyChannelID, srcChan), + sdk.NewAttribute(ics04.AttributeKeyPacket, string(packetJson)), + )) + return nil } diff --git a/x/ibc/mock/bank/internal/types/codec.go b/x/ibc/mock/bank/internal/types/codec.go index 84ccb87b88aa..e0762be3f3d2 100644 --- a/x/ibc/mock/bank/internal/types/codec.go +++ b/x/ibc/mock/bank/internal/types/codec.go @@ -2,17 +2,23 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/merkle" ) func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Packet{}, "ibcmockbank/Packet", nil) cdc.RegisterConcrete(TransferPacketData{}, "ibcmockbank/TransferPacketData", nil) cdc.RegisterConcrete(MsgTransfer{}, "ibcmockbank/MsgTransfer", nil) - cdc.RegisterConcrete(MsgSendTransferPacket{}, "ibcmockbank/MsgSendTransferPacket", nil) + cdc.RegisterConcrete(MsgRecvTransferPacket{}, "ibcmockbank/MsgRecvTransferPacket", nil) } var MouduleCdc = codec.New() func init() { RegisterCodec(MouduleCdc) + channel.RegisterCodec(MouduleCdc) + commitment.RegisterCodec(MouduleCdc) + merkle.RegisterCodec(MouduleCdc) } diff --git a/x/ibc/mock/bank/internal/types/expected_keepers.go b/x/ibc/mock/bank/internal/types/expected_keepers.go index 69438e82562b..45156d2675b5 100644 --- a/x/ibc/mock/bank/internal/types/expected_keepers.go +++ b/x/ibc/mock/bank/internal/types/expected_keepers.go @@ -2,18 +2,31 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ics23 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) type BankKeeper interface { AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) - SetTotalSupply(ctx sdk.Context, totalSupply sdk.Coin) + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + + SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) +} - GetTotalSupply(ctx sdk.Context, denom string) (coin sdk.Coin, found bool) +type ChannelKeeper interface { + GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) - IncreaseTotalSupply(ctx sdk.Context, amt sdk.Coin) sdk.Error + GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) - BurnCoins(ctx sdk.Context, fromAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + RecvPacket( + ctx sdk.Context, + packet exported.PacketI, + proof ics23.Proof, + proofHeight uint64, + acknowledgement []byte, + ) (exported.PacketI, error) - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendPacket(ctx sdk.Context, packet exported.PacketI) error } diff --git a/x/ibc/mock/bank/internal/types/msgs.go b/x/ibc/mock/bank/internal/types/msgs.go index fc5392c733a9..ad87c838c1b4 100644 --- a/x/ibc/mock/bank/internal/types/msgs.go +++ b/x/ibc/mock/bank/internal/types/msgs.go @@ -8,7 +8,7 @@ import ( const ( TypeMsgTransfer = "transfer" - TypeMsgSendTransferPacket = "send-transfer-packet" + TypeMsgRecvTransferPacket = "recv-transfer-packet" ) type MsgTransfer struct { @@ -20,12 +20,11 @@ type MsgTransfer struct { Receiver string `json:"receiver" yaml:"receiver"` Source bool `json:"source" yaml:"source"` } -type MsgSendTransferPacket struct { - Packet ics04.PacketI `json:"packet" yaml:"packet"` - ChannelID string `json:"channel_id" yaml:"channel_id"` - Proofs []ics23.Proof `json:"proofs" yaml:"proofs"` - Height uint64 `json:"height" yaml:"height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` +type MsgRecvTransferPacket struct { + Packet ics04.PacketI `json:"packet" yaml:"packet"` + Proofs []ics23.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` } func NewMsgTransfer(srcPort, srcChannel string, denom string, amount sdk.Int, sender sdk.AccAddress, receiver string, source bool) MsgTransfer { @@ -68,25 +67,24 @@ func (msg MsgTransfer) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } -func NewMsgSendTransferPacket(packet ics04.PacketI, channelID string, proofs []ics23.Proof, height uint64, signer sdk.AccAddress) MsgSendTransferPacket { - return MsgSendTransferPacket{ - Packet: packet, - ChannelID: channelID, - Proofs: proofs, - Height: height, - Signer: signer, +func NewMsgRecvTransferPacket(packet ics04.PacketI, proofs []ics23.Proof, height uint64, signer sdk.AccAddress) MsgRecvTransferPacket { + return MsgRecvTransferPacket{ + Packet: packet, + Proofs: proofs, + Height: height, + Signer: signer, } } -func (MsgSendTransferPacket) Route() string { +func (MsgRecvTransferPacket) Route() string { return RouterKey } -func (MsgSendTransferPacket) Type() string { - return TypeMsgSendTransferPacket +func (MsgRecvTransferPacket) Type() string { + return TypeMsgRecvTransferPacket } -func (msg MsgSendTransferPacket) ValidateBasic() sdk.Error { +func (msg MsgRecvTransferPacket) ValidateBasic() sdk.Error { if msg.Proofs == nil { return sdk.NewError(sdk.CodespaceType(DefaultCodespace), CodeProofMissing, "proof missing") } @@ -98,10 +96,10 @@ func (msg MsgSendTransferPacket) ValidateBasic() sdk.Error { return nil } -func (msg MsgSendTransferPacket) GetSignBytes() []byte { +func (msg MsgRecvTransferPacket) GetSignBytes() []byte { return sdk.MustSortJSON(MouduleCdc.MustMarshalJSON(msg)) } -func (msg MsgSendTransferPacket) GetSigners() []sdk.AccAddress { +func (msg MsgRecvTransferPacket) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } diff --git a/x/ibc/mock/bank/module.go b/x/ibc/mock/bank/module.go index 1369abe1ac25..e033d1de5666 100644 --- a/x/ibc/mock/bank/module.go +++ b/x/ibc/mock/bank/module.go @@ -60,8 +60,7 @@ type AppModule struct { func NewAppModule(k Keeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, - - k: k, + k: k, } } @@ -104,3 +103,8 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } + +// GetTxCmd returns the root tx command for the ibc-channel module. +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(cdc) +} From caede8e6288caba394e77706a8ad19e288b12afc Mon Sep 17 00:00:00 2001 From: chengwenxi Date: Mon, 21 Oct 2019 00:52:24 +0800 Subject: [PATCH 12/12] error return --- x/ibc/04-channel/types/events.go | 2 +- x/ibc/mock/bank/internal/keeper/keeper.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go index 6bebb576887e..b768c60798ab 100644 --- a/x/ibc/04-channel/types/events.go +++ b/x/ibc/04-channel/types/events.go @@ -12,7 +12,7 @@ const ( AttributeKeyReceiverPort = "receiver_port" AttributeKeyChannelID = "channel_id" AttributeKeySequence = "sequence" - AttributeKeyPacket = "Packet" + AttributeKeyPacket = "packet" ) // IBC channel events vars diff --git a/x/ibc/mock/bank/internal/keeper/keeper.go b/x/ibc/mock/bank/internal/keeper/keeper.go index 2490c607349a..ceb4ae71fbae 100644 --- a/x/ibc/mock/bank/internal/keeper/keeper.go +++ b/x/ibc/mock/bank/internal/keeper/keeper.go @@ -83,7 +83,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet exported.PacketI, proof // check the denom prefix prefix := fmt.Sprintf("%s/%s", packet.DestPort(), packet.DestChannel()) if !strings.HasPrefix(data.Denomination, prefix) { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } _, err := k.bk.AddCoins(ctx, receiverAddr, sdk.Coins{sdk.NewCoin(data.Denomination, data.Amount)}) @@ -97,7 +97,7 @@ func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet exported.PacketI, proof // check the denom prefix prefix := fmt.Sprintf("%s/%s", packet.SourcePort(), packet.SourceChannel()) if !strings.HasPrefix(data.Denomination, prefix) { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } escrowAddress := k.GetEscrowAddress(packet.DestChannel()) @@ -120,7 +120,7 @@ func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcCh // check the denom prefix prefix := fmt.Sprintf("%s/%s", dstPort, dstChan) if !strings.HasPrefix(denom, prefix) { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } err := k.bk.SendCoins(ctx, sender, escrowAddress, sdk.Coins{sdk.NewCoin(denom[len(prefix):], amount)}) @@ -134,7 +134,7 @@ func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcCh // check the denom prefix prefix := fmt.Sprintf("%s/%s", srcPort, srcChan) if !strings.HasPrefix(denom, prefix) { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeIncorrectDenom, "incorrect denomination") } _, err := k.bk.SubtractCoins(ctx, sender, sdk.Coins{sdk.NewCoin(denom, amount)}) @@ -154,7 +154,7 @@ func (k Keeper) createOutgoingPacket(ctx sdk.Context, seq uint64, srcPort, srcCh packetDataBz, err := packetData.MarshalJSON() if err != nil { - sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") } packet := types.NewPacket(seq, uint64(ctx.BlockHeight())+DefaultPacketTimeout, srcPort, srcChan, dstPort, dstChan, packetDataBz)