Skip to content

Commit

Permalink
ICS20 implementation (#5204)
Browse files Browse the repository at this point in the history
* add ibc bank mock

* modify handler

* import channel

* add receiving logic

* add cli proof handling

* modify cli

* modify receiver type

* modify errcode

* optimize codes

* add denom prefix when source is true

* refactor code

* error return
  • Loading branch information
chengwenxi authored and fedekunze committed Oct 25, 2019
1 parent 09adf43 commit 0363390
Show file tree
Hide file tree
Showing 14 changed files with 844 additions and 0 deletions.
1 change: 1 addition & 0 deletions x/ibc/04-channel/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
AttributeKeyReceiverPort = "receiver_port"
AttributeKeyChannelID = "channel_id"
AttributeKeySequence = "sequence"
AttributeKeyPacket = "packet"
)

// IBC channel events vars
Expand Down
2 changes: 2 additions & 0 deletions x/ibc/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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
}
Expand Down
30 changes: 30 additions & 0 deletions x/ibc/mock/bank/alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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
MsgRecvTransferPacket = types.MsgRecvTransferPacket
Keeper = keeper.Keeper
)

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
NewMsgRecvTransferPacket = types.NewMsgRecvTransferPacket
)
27 changes: 27 additions & 0 deletions x/ibc/mock/bank/client/cli/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cli

import (
flag "github.com/spf13/pflag"
)

const (
FlagSrcPort = "src-port"
FlagSrcChannel = "src-channel"
FlagDenom = "denom"
FlagAmount = "amount"
FlagReceiver = "receiver"
FlagSource = "source"
)

var (
FsTransfer = flag.NewFlagSet("", flag.ContinueOnError)
)

func init() {
FsTransfer.String(FlagSrcPort, "", "the source port ID")
FsTransfer.String(FlagSrcChannel, "", "the source channel ID")
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 sending chain is the source chain of the token")
}
128 changes: 128 additions & 0 deletions x/ibc/mock/bank/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cli

import (
"fmt"
"io/ioutil"
"os"
"strconv"

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

func GetTxCmd(cdc *codec.Codec) *cobra.Command {
txCmd := &cobra.Command{
Use: "ibcmockbank",
Short: "IBC mockbank module transaction subcommands",
// RunE: client.ValidateCmd,
}
txCmd.AddCommand(
GetTransferTxCmd(cdc),
GetMsgRecvPacketCmd(cdc),
)

return txCmd
}

func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "transfer --src-port <src port> --src-channel <src channel> --denom <denomination> --amount <amount> --receiver <receiver> --source <source>",
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)
denom := viper.GetString(FlagDenom)
srcPort := viper.GetString(FlagSrcPort)
srcChan := viper.GetString(FlagSrcChannel)
source := viper.GetBool(FlagSource)

amount, ok := sdk.NewIntFromString(viper.GetString(FlagAmount))
if !ok {
return fmt.Errorf("invalid amount")
}

msg := types.NewMsgTransfer(srcPort, srcChan, denom, amount, sender, receiver, source)
if err := msg.ValidateBasic(); err != nil {
return err
}

return utils.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg})
},
}

cmd.Flags().AddFlagSet(FsTransfer)

cmd.MarkFlagRequired(FlagSrcPort)
cmd.MarkFlagRequired(FlagSrcChannel)
cmd.MarkFlagRequired(FlagDenom)
cmd.MarkFlagRequired(FlagAmount)
cmd.MarkFlagRequired(FlagReceiver)

cmd = client.PostCommands(cmd)[0]

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
}
44 changes: 44 additions & 0 deletions x/ibc/mock/bank/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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 {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case MsgTransfer:
return handleMsgTransfer(ctx, k, msg)
case MsgRecvTransferPacket:
return handleMsgRecvTransferPacket(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.SendTransfer(ctx, msg.SrcPort, msg.SrcChannel, msg.Denomination, msg.Amount, msg.Sender, msg.Receiver, msg.Source)
if err != nil {
return err.Result()
}

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

return sdk.Result{Events: ctx.EventManager().Events()}
}
Loading

0 comments on commit 0363390

Please sign in to comment.