Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICS20 implementation #5204

Merged
merged 17 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any required flags need to be converted to args. Something like:

transfer [src-port] [src-channel] [denom] [amount] [receiver] [source]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also denom and amount should be one arg (we can parse them out) and [receiver] should something like [to-addr]. Also what is the purpose of source?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also denom and amount should be one arg (we can parse them out) and [receiver] should something like [to-addr]. Also what is the purpose of source?

The source is used to mark whether the sending chain is the source of the asset in ICS 20. If source is true, will escrow tokens on the sending chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a better way to do that is on the chain instead of specified in msg.

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]",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a query that returns the data required for this command? Should be able to be constructed like:

recv-packet $(gaiacli q ibc packet-data) $(gaiacli q ibc channel packet-proof)

Also ideally the proof has the height returned with it so that would remove the need for the 3rd arg.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's seems that we should only store the packet hash. There is more than one proof that needs to be queried, should we add a common command to query the proof by the stored key or add different commands to query the connection/channel/packet_hash proof?

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