-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
ICS20 implementation #5204
Changes from all commits
d583964
e0f44bc
79ae5da
a745374
f06b2ec
87448ca
d353e16
46ad324
3531e3e
46c691c
a26369b
3052ed5
ef6f72e
8daa378
caede8e
22bc78f
67f5427
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
) |
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") | ||
} |
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]", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
Also ideally the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
} |
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()} | ||
} |
There was a problem hiding this comment.
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:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also
denom
andamount
should be one arg (we can parse them out) and[receiver]
should something like[to-addr]
. Also what is the purpose of source?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
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.