From 11641ea581a3334b46ec5d7ec3ebd37543124495 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 24 Mar 2021 18:19:37 -0400 Subject: [PATCH] cli: ux cleanup for tx commands (#467) --- README.md | 6 +- cmd/tx.go | 162 +++++++++++++++++++++++++------------------------ cmd/version.go | 7 ++- cmd/xfer.go | 40 ++++++------ dev-env | 4 +- 5 files changed, 113 insertions(+), 106 deletions(-) diff --git a/README.md b/README.md index c0bf9042c..5cd1520ab 100644 --- a/README.md +++ b/README.md @@ -157,14 +157,16 @@ $ rly q bal ibc-1 # Then send some tokens between the chains $ rly tx transfer ibc-0 ibc-1 1000000samoleans $(rly chains address ibc-1) $ rly tx relay demo -d +$ rly tx acks demo -d # See that the transfer has completed $ rly q bal ibc-0 $ rly q bal ibc-1 # Send the tokens back to the account on ibc-0 -$ rly tx xfer ibc-1 ibc-0 1000000ibc/27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C $(rly ch addr ibc-0) -$ rly tx rly demo -d +$ rly tx transfer ibc-1 ibc-0 1000000ibc/27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C $(rly chains addr ibc-0) +$ rly tx relay demo -d +$ rly tx acks demo -d # See that the return trip has completed $ rly q bal ibc-0 diff --git a/cmd/tx.go b/cmd/tx.go index a469b7884..02d0b57e2 100644 --- a/cmd/tx.go +++ b/cmd/tx.go @@ -1,19 +1,3 @@ -/* -Package cmd includes relayer commands -Copyright © 2020 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( @@ -31,16 +15,18 @@ import ( "github.com/spf13/cobra" ) -// transactionCmd represents the tx command +// transactionCmd returns a parent transaction command handler, where all child +// commands can submit transactions on IBC-connected networks. func transactionCmd() *cobra.Command { cmd := &cobra.Command{ Use: "transact", Aliases: []string{"tx"}, - Short: "IBC Transaction Commands", - Long: strings.TrimSpace(`Commands to create IBC transactions on configured chains. - Most of these commands take a '[path]' argument. Make sure: - 1. Chains are properly configured to relay over by using the 'rly chains list' command - 2. Path is properly configured to relay over by using the 'rly paths list' command`), + Short: "IBC transaction commands", + Long: strings.TrimSpace(`Commands to create IBC transactions on pre-configured chains. +Most of these commands take a [path] argument. Make sure: + 1. Chains are properly configured to relay over by using the 'rly chains list' command + 2. Path is properly configured to relay over by using the 'rly paths list' command`, + ), } cmd.AddCommand( @@ -65,15 +51,12 @@ func transactionCmd() *cobra.Command { func createClientsCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "clients [path-name]", - Aliases: []string{"clnts"}, - Short: "create a clients between two configured chains with a configured path", + Use: "clients [path-name]", + Short: "create a clients between two configured chains with a configured path", Long: "Creates a working ibc client for chain configured on each end of the" + " path by querying headers from each chain and then sending the corresponding create-client messages", - Args: cobra.ExactArgs(1), - Example: strings.TrimSpace(fmt.Sprintf(` -$ %s transact clients demo-path -$ %s tx clnts demo-path`, appName, appName)), + Args: cobra.ExactArgs(1), + Example: strings.TrimSpace(fmt.Sprintf(`$ %s transact clients demo-path`, appName)), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -98,21 +81,19 @@ $ %s tx clnts demo-path`, appName, appName)), return err }, } + return cmd } func updateClientsCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "update-clients [path-name]", - Aliases: []string{"update", "uc"}, - Short: "update a clients between two configured chains with a configured path", - Long: "Updates a working ibc client for chain configured on each end of the " + - "path by querying headers from each chain and then sending the corresponding update-client messages", - Args: cobra.ExactArgs(1), - Example: strings.TrimSpace(fmt.Sprintf(` -$ %s transact update-clients demo-path -$ %s tx update demo-path -$ %s tx uc demo-path`, appName, appName, appName)), + Use: "update-clients [path-name]", + Short: "update IBC clients between two configured chains with a configured path", + Long: `Updates IBC client for chain configured on each end of the supplied path. +Clients are updated by querying headers from each chain and then sending the +corresponding update-client messages.`, + Args: cobra.ExactArgs(1), + Example: strings.TrimSpace(fmt.Sprintf(`$ %s transact update-clients demo-path`, appName)), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -130,15 +111,15 @@ $ %s tx uc demo-path`, appName, appName, appName)), return c[src].UpdateClients(c[dst]) }, } + return cmd } func upgradeClientsCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "upgrade-clients [path-name] [chain-id]", - Aliases: []string{"upgrade"}, - Short: "upgrade a client on the provided chain-id", - Args: cobra.ExactArgs(2), + Use: "upgrade-clients [path-name] [chain-id]", + Short: "upgrades IBC clients between two configured chains with a configured path and chain-id", + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -159,6 +140,7 @@ func upgradeClientsCmd() *cobra.Command { } targetChainID := args[1] + // send the upgrade message on the targetChainID if src == targetChainID { return c[src].UpgradeClients(c[dst], height) @@ -167,21 +149,24 @@ func upgradeClientsCmd() *cobra.Command { return c[dst].UpgradeClients(c[src], height) }, } + return heightFlag(cmd) } func createConnectionCmd() *cobra.Command { cmd := &cobra.Command{ Use: "connection [path-name]", - Aliases: []string{"conn", "con"}, + Aliases: []string{"conn"}, Short: "create a connection between two configured chains with a configured path", - Long: strings.TrimSpace(`This command is meant to be used to repair or create - a connection between two chains with a configured path in the config file`), + Long: strings.TrimSpace(`Create or repair a connection between two IBC-connected networks +along a specific path.`, + ), Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact connection demo-path -$ %s tx conn demo-path --timeout 5s -$ %s tx con demo-path -o 3s`, appName, appName, appName)), +$ %s tx conn demo-path --timeout 5s`, + appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -233,16 +218,16 @@ $ %s tx con demo-path -o 3s`, appName, appName, appName)), func closeChannelCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "channel-close [path-name]", - Aliases: []string{"chan-cl", "close", "cl"}, - Short: "close a channel between two configured chains with a configured path", - Long: "This command is meant to close a channel", - Args: cobra.ExactArgs(1), + Use: "channel-close [path-name]", + Short: "close a channel between two configured chains with a configured path", + Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact channel-close demo-path -$ %s tx chan-cl demo-path --timeout 5s -$ %s tx cl demo-path -$ %s tx close demo-path -o 3s`, appName, appName, appName, appName)), +$ %s tx channel-close demo-path --timeout 5s +$ %s tx channel-close demo-path +$ %s tx channel-close demo-path -o 3s`, + appName, appName, appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -272,16 +257,18 @@ $ %s tx close demo-path -o 3s`, appName, appName, appName, appName)), func linkCmd() *cobra.Command { cmd := &cobra.Command{ Use: "link [path-name]", - Aliases: []string{"full-path", "connect", "path", "pth", "channel"}, + Aliases: []string{"connect"}, Short: "create clients, connection, and channel between two configured chains with a configured path", - Args: cobra.ExactArgs(1), + Long: strings.TrimSpace(`Create an IBC client between two IBC-enabled networks, in addition +to creating a connection and a channel between the two networks on a configured path.`, + ), + Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact link demo-path -$ %s tx full-path demo-path --timeout 5s -$ %s tx connect demo-path -$ %s tx path demo-path -o 3s -$ %s tx channel demo-path -$ %s tx pth demo-path`, appName, appName, appName, appName, appName, appName)), +$ %s tx link demo-path +$ %s tx connect demo-path`, + appName, appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -345,36 +332,43 @@ $ %s tx pth demo-path`, appName, appName, appName, appName, appName, appName)), func linkThenStartCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "link-then-start [path-name]", - Short: "wait for a link to come up, then start relaying packets", - Args: cobra.ExactArgs(1), + Use: "link-then-start [path-name]", + Aliases: []string{"connect-then-start"}, + Short: "a shorthand command to execute 'link' followed by 'start'", + Long: strings.TrimSpace(`Create IBC clients, connection, and channel between two configured IBC +networks with a configured path and then start the relayer on that path.`, + ), + Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact link-then-start demo-path $ %s tx link-then-start demo-path --timeout 5s`, appName, appName)), RunE: func(cmd *cobra.Command, args []string) error { lCmd := linkCmd() + for err := lCmd.RunE(cmd, args); err != nil; err = lCmd.RunE(cmd, args) { fmt.Printf("retrying link: %s\n", err) time.Sleep(1 * time.Second) } + sCmd := startCmd() return sCmd.RunE(cmd, args) }, } + return strategyFlag(retryFlag(timeoutFlag(cmd))) } func relayMsgsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "relay-packets [path-name]", - Aliases: []string{"rly", "pkts", "relay"}, - Short: "relay any packets that remain to be relayed on a given path, in both directions", + Aliases: []string{"relay"}, + Short: "relay any remaining non-relayed packets on a given path, in both directions", Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact relay-packets demo-path -$ %s tx rly demo-path -l 3 -$ %s tx pkts demo-path -s 5 -$ %s tx relay demo-path`, appName, appName, appName, appName)), +$ %s tx relay demo-path`, + appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -410,11 +404,13 @@ func relayAcksCmd() *cobra.Command { cmd := &cobra.Command{ Use: "relay-acknowledgements [path-name]", Aliases: []string{"acks"}, - Short: "relay any acknowledgements that remain to be relayed on a given path, in both directions", + Short: "relay any remaining non-relayed acknowledgements on a given path, in both directions", Args: cobra.ExactArgs(1), Example: strings.TrimSpace(fmt.Sprintf(` $ %s transact relay-acknowledgements demo-path -$ %s tx acks demo-path -l 3 -s 6`, appName, appName)), +$ %s tx acks demo-path -l 3 -s 6`, + appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) if err != nil { @@ -450,9 +446,12 @@ $ %s tx acks demo-path -l 3 -s 6`, appName, appName)), func upgradeChainCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "upgrade-chain [path-name] [chain-id] [new-unbonding-period] [deposit] [path/to/upgradePlan.json]", - Short: "upgrade a chain by providing the chain-id of the chain being upgraded, the new unbonding period," + - "the proposal deposit and the json file of the upgrade plan without the upgrade client state", + Use: "upgrade-chain [path-name] [chain-id] [new-unbonding-period] [deposit] [path/to/upgradePlan.json]", + Short: "upgrade an IBC-enabled network with a given upgrade plan", + Long: strings.TrimSpace(`Upgrade an IBC-enabled network by providing the chain-id of the +network being upgraded, the new unbonding period, the proposal deposit and the JSN file of the +upgrade plan without the upgrade client state.`, + ), Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { c, src, dst, err := config.ChainsFromPath(args[0]) @@ -505,15 +504,18 @@ func upgradeChainCmd() *cobra.Command { return c[dst].UpgradeChain(c[src], plan, deposit, unbondingPeriod) }, } + return cmd } -// Returns an error if a configured key for a given chain doesn't exist -func ensureKeysExist(chains map[string]*relayer.Chain) (err error) { +// ensureKeysExist returns an error if a configured key for a given chain does +// not exist. +func ensureKeysExist(chains map[string]*relayer.Chain) error { for _, v := range chains { - if _, err = v.GetAddress(); err != nil { - return + if _, err := v.GetAddress(); err != nil { + return err } } + return nil } diff --git a/cmd/version.go b/cmd/version.go index 45e3d3679..5f8016028 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -30,10 +30,12 @@ func getVersionCmd() *cobra.Command { versionCmd := &cobra.Command{ Use: "version", Aliases: []string{"v"}, - Short: "Print relayer version info", + Short: "Print the relayer version info", Example: strings.TrimSpace(fmt.Sprintf(` $ %s version --json -$ %s v`, appName, appName)), +$ %s v`, + appName, appName, + )), RunE: func(cmd *cobra.Command, args []string) error { jsn, err := cmd.Flags().GetBool(flagJSON) if err != nil { @@ -58,5 +60,6 @@ $ %s v`, appName, appName)), return err }, } + return jsonFlag(versionCmd) } diff --git a/cmd/xfer.go b/cmd/xfer.go index e268b323d..e6f87cc4b 100644 --- a/cmd/xfer.go +++ b/cmd/xfer.go @@ -5,9 +5,8 @@ import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/cosmos/relayer/relayer" + "github.com/spf13/cobra" ) type stringStringer struct { @@ -18,23 +17,19 @@ func (ss stringStringer) String() string { return ss.str } -// NOTE: These commands are registered over in cmd/raw.go - func xfersend() *cobra.Command { cmd := &cobra.Command{ - Use: "transfer [src-chain-id] [dst-chain-id] [amount] [dst-addr]", - Short: "Initiate a transfer from one chain to another", - Aliases: []string{"xfer", "txf", "send"}, - Long: "Sends the first step to transfer tokens in an IBC transfer." + - " The created packet must be relayed to another chain", + Use: "transfer [src-chain-id] [dst-chain-id] [amount] [dst-addr]", + Short: "initiate a transfer from one network to another", + Long: `Initiate a token transfer via IBC between two networks. The created packet +must be relayed to the destination chain.`, Args: cobra.ExactArgs(4), Example: strings.TrimSpace(fmt.Sprintf(` -$ %s transact transfer ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo-path -$ %s tx xfer ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo -y 2 -c 10 -$ %s tx xfer ibc-0 ibc-1 100000stake raw:non-bech32-address --path demo -$ %s tx txf ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo +$ %s tx transfer ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo-path +$ %s tx transfer ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo -y 2 -c 10 +$ %s tx transfer ibc-0 ibc-1 100000stake raw:non-bech32-address --path demo $ %s tx raw send ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk --path demo -c 5 -`, appName, appName, appName, appName, appName)), +`, appName, appName, appName, appName)), RunE: func(cmd *cobra.Command, args []string) error { src, dst := args[0], args[1] c, err := config.Chains.Gets(src, dst) @@ -86,12 +81,14 @@ $ %s tx raw send ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9 rawDstAddr := strings.TrimPrefix(args[3], "raw:") var dstAddr fmt.Stringer if rawDstAddr == args[3] { - // Not "raw:", treat the dstAddr as bech32. + // not "raw:", so we treat the dstAddr as bech32 done := c[dst].UseSDKContext() + dstAddr, err = sdk.AccAddressFromBech32(args[3]) if err != nil { return err } + done() } else { // Don't parse the rest of the dstAddr... it's raw. @@ -101,31 +98,34 @@ $ %s tx raw send ibc-0 ibc-1 100000stake cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9 return c[src].SendTransferMsg(c[dst], amount, dstAddr.String(), toHeightOffset, toTimeOffset) }, } + return timeoutFlags(pathFlag(cmd)) } func setPathsFromArgs(src, dst *relayer.Chain, name string) (*relayer.Path, error) { - // Find any configured paths between the chains + // find any configured paths between the chains paths, err := config.Paths.PathsFromChains(src.ChainID, dst.ChainID) if err != nil { return nil, err } - // Given the number of args and the number of paths, - // work on the appropriate path + // Given the number of args and the number of paths, work on the appropriate + // path. var path *relayer.Path switch { case name != "" && len(paths) > 1: if path, err = paths.Get(name); err != nil { return path, err } + case name != "" && len(paths) == 1: if path, err = paths.Get(name); err != nil { return path, err } + case name == "" && len(paths) > 1: - return nil, fmt.Errorf("more than one path between %s and %s exists, pass in path name", - src.ChainID, dst.ChainID) + return nil, fmt.Errorf("more than one path between %s and %s exists, pass in path name", src.ChainID, dst.ChainID) + case name == "" && len(paths) == 1: for _, v := range paths { path = v diff --git a/dev-env b/dev-env index 1c0cf3438..019b55fd1 100755 --- a/dev-env +++ b/dev-env @@ -20,10 +20,10 @@ bash scripts/two-chainz "skip" echo "waiting for blocks..." sleep 3 -rly tx full-path demo -d -o 3s +rly tx link demo -d -o 3s rly tx txf ibc-0 ibc-1 100000samoleans $(rly ch addr ibc-1) rly tx txf ibc-1 ibc-0 100000samoleans $(rly ch addr ibc-0) sleep 1 -rly tx rly demo -d +rly tx relay demo -d sleep 1 rly tx acks demo -d