diff --git a/.pending/breaking/sdk/4488-client-s-tx-res b/.pending/breaking/sdk/4488-client-s-tx-res new file mode 100644 index 000000000..03b815c30 --- /dev/null +++ b/.pending/breaking/sdk/4488-client-s-tx-res @@ -0,0 +1,2 @@ +#4488 Decouple client tx, REST, and ultil packages from auth. These packages have +been restructured and retrofitted into the `x/auth` module. diff --git a/client/alias.go b/client/alias.go index 5ce2ab057..04aa203bd 100644 --- a/client/alias.go +++ b/client/alias.go @@ -18,10 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/lcd" - "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/client/rpc" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/client/utils" ) const ( @@ -94,7 +91,6 @@ var ( NewInMemoryKeyBase = keys.NewInMemoryKeyBase NewRestServer = lcd.NewRestServer ServeCommand = lcd.ServeCommand - WriteGenerateStdTxResponse = rest.WriteGenerateStdTxResponse BlockCommand = rpc.BlockCommand GetChainHeight = rpc.GetChainHeight BlockRequestHandlerFn = rpc.BlockRequestHandlerFn @@ -109,27 +105,6 @@ var ( GetValidators = rpc.GetValidators ValidatorSetRequestHandlerFn = rpc.ValidatorSetRequestHandlerFn LatestValidatorSetRequestHandlerFn = rpc.LatestValidatorSetRequestHandlerFn - BroadcastTxRequest = tx.BroadcastTxRequest - GetBroadcastCommand = tx.GetBroadcastCommand - EncodeTxRequestHandlerFn = tx.EncodeTxRequestHandlerFn - GetEncodeCommand = tx.GetEncodeCommand - SearchTxCmd = tx.SearchTxCmd - QueryTxCmd = tx.QueryTxCmd - QueryTxsByTagsRequestHandlerFn = tx.QueryTxsByTagsRequestHandlerFn - QueryTxRequestHandlerFn = tx.QueryTxRequestHandlerFn - RegisterTxRoutes = tx.RegisterTxRoutes - SearchTxs = tx.SearchTxs - ValidateTxResult = tx.ValidateTxResult - GenerateOrBroadcastMsgs = utils.GenerateOrBroadcastMsgs - CompleteAndBroadcastTxCLI = utils.CompleteAndBroadcastTxCLI - EnrichWithGas = utils.EnrichWithGas - CalculateGas = utils.CalculateGas - PrintUnsignedStdTx = utils.PrintUnsignedStdTx - SignStdTx = utils.SignStdTx - SignStdTxWithSignerAddress = utils.SignStdTxWithSignerAddress - ReadStdTxFromFile = utils.ReadStdTxFromFile - GetTxEncoder = utils.GetTxEncoder - PrepareTxBuilder = utils.PrepareTxBuilder BufferStdin = input.BufferStdin OverrideStdin = input.OverrideStdin GetPassword = input.GetPassword @@ -153,7 +128,4 @@ type ( RestServer = lcd.RestServer ValidatorOutput = rpc.ValidatorOutput ResultValidatorsOutput = rpc.ResultValidatorsOutput - BroadcastReq = tx.BroadcastReq - EncodeResp = tx.EncodeResp - GasEstimateResponse = utils.GasEstimateResponse ) diff --git a/client/cmd.go b/client/cmd.go new file mode 100644 index 000000000..afddf20fe --- /dev/null +++ b/client/cmd.go @@ -0,0 +1,38 @@ +package client + +import ( + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +// ValidateCmd returns unknown command error or Help display if help flag set +func ValidateCmd(cmd *cobra.Command, args []string) error { + var cmds []string + var help bool + + // construct array of commands and search for help flag + for _, arg := range args { + if arg == "--help" || arg == "-h" { + help = true + } else if len(arg) > 0 && !(arg[0] == '-') { + cmds = append(cmds, arg) + } + } + + if !help && len(cmds) > 0 { + err := fmt.Sprintf("unknown command \"%s\" for \"%s\"", cmds[0], cmd.CalledAs()) + + // build suggestions for unknown argument + if suggestions := cmd.SuggestionsFor(cmds[0]); len(suggestions) > 0 { + err += "\n\nDid you mean this?\n" + for _, s := range suggestions { + err += fmt.Sprintf("\t%v\n", s) + } + } + return errors.New(err) + } + + return cmd.Help() +} diff --git a/client/cmd_test.go b/client/cmd_test.go new file mode 100644 index 000000000..3ca286f64 --- /dev/null +++ b/client/cmd_test.go @@ -0,0 +1,50 @@ +package client_test + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client" +) + +func TestValidateCmd(t *testing.T) { + // setup root and subcommands + rootCmd := &cobra.Command{ + Use: "root", + } + queryCmd := &cobra.Command{ + Use: "query", + } + rootCmd.AddCommand(queryCmd) + + // command being tested + distCmd := &cobra.Command{ + Use: "distr", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + queryCmd.AddCommand(distCmd) + + commissionCmd := &cobra.Command{ + Use: "commission", + } + distCmd.AddCommand(commissionCmd) + + tests := []struct { + reason string + args []string + wantErr bool + }{ + {"misspelled command", []string{"comission"}, true}, + {"no command provided", []string{}, false}, + {"help flag", []string{"comission", "--help"}, false}, + {"shorthand help flag", []string{"comission", "-h"}, false}, + } + + for _, tt := range tests { + err := client.ValidateCmd(distCmd, tt.args) + require.Equal(t, tt.wantErr, err != nil, tt.reason) + } +} diff --git a/client/rest/errors.go b/client/rest/errors.go deleted file mode 100644 index a3ac8fb29..000000000 --- a/client/rest/errors.go +++ /dev/null @@ -1,5 +0,0 @@ -package rest - -import "errors" - -var errInvalidGasAdjustment = errors.New("invalid gas adjustment") diff --git a/client/routes.go b/client/routes.go index d8c07b67b..ded91ca89 100644 --- a/client/routes.go +++ b/client/routes.go @@ -9,5 +9,4 @@ import ( // Register routes func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { RegisterRPCRoutes(cliCtx, r) - RegisterTxRoutes(cliCtx, r) } diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go deleted file mode 100644 index 20654c59d..000000000 --- a/client/tx/broadcast.go +++ /dev/null @@ -1,95 +0,0 @@ -package tx - -import ( - "net/http" - "strings" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth" - - "io/ioutil" - - "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/utils" - "github.com/cosmos/cosmos-sdk/codec" -) - -// BroadcastReq defines a tx broadcasting request. -type BroadcastReq struct { - Tx auth.StdTx `json:"tx"` - Mode string `json:"mode"` -} - -// BroadcastTxRequest implements a tx broadcasting handler that is responsible -// for broadcasting a valid and signed tx to a full node. The tx can be -// broadcasted via a sync|async|block mechanism. -func BroadcastTxRequest(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req BroadcastReq - - body, err := ioutil.ReadAll(r.Body) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - err = cliCtx.Codec.UnmarshalJSON(body, &req) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(req.Tx) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - cliCtx = cliCtx.WithBroadcastMode(req.Mode) - - res, err := cliCtx.BroadcastTx(txBytes) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - rest.PostProcessResponse(w, cliCtx, res) - } -} - -// GetBroadcastCommand returns the tx broadcast command. -func GetBroadcastCommand(cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "broadcast [file_path]", - Short: "Broadcast transactions generated offline", - Long: strings.TrimSpace(`Broadcast transactions created with the --generate-only -flag and signed with the sign command. Read a transaction from [file_path] and -broadcast it to a node. If you supply a dash (-) argument in place of an input -filename, the command reads from standard input. - -$ tx broadcast ./mytxn.json -`), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) (err error) { - cliCtx := context.NewCLIContext().WithCodec(cdc) - stdTx, err := utils.ReadStdTxFromFile(cliCtx.Codec, args[0]) - if err != nil { - return - } - - txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(stdTx) - if err != nil { - return - } - - res, err := cliCtx.BroadcastTx(txBytes) - cliCtx.PrintOutput(res) // nolint:errcheck - return err - }, - } - - return flags.PostCommands(cmd)[0] -} diff --git a/client/tx/query.go b/client/tx/query.go deleted file mode 100644 index 931808f08..000000000 --- a/client/tx/query.go +++ /dev/null @@ -1,213 +0,0 @@ -package tx - -import ( - "fmt" - "net/http" - "strings" - - "github.com/gorilla/mux" - "github.com/spf13/cobra" - "github.com/tendermint/tendermint/types" - - "github.com/spf13/viper" - - "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/types/rest" -) - -const ( - flagTags = "tags" - flagPage = "page" - flagLimit = "limit" -) - -// ---------------------------------------------------------------------------- -// CLI -// ---------------------------------------------------------------------------- - -// SearchTxCmd returns a command to search through tagged transactions. -func SearchTxCmd(cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "txs", - Short: "Search for paginated transactions that match a set of tags", - Long: strings.TrimSpace(` -Search for transactions that match the exact given tags where results are paginated. - -Example: -$ query txs --tags ':&:' --page 1 --limit 30 -`), - RunE: func(cmd *cobra.Command, args []string) error { - tagsStr := viper.GetString(flagTags) - tagsStr = strings.Trim(tagsStr, "'") - - var tags []string - if strings.Contains(tagsStr, "&") { - tags = strings.Split(tagsStr, "&") - } else { - tags = append(tags, tagsStr) - } - - var tmTags []string - for _, tag := range tags { - if !strings.Contains(tag, ":") { - return fmt.Errorf("%s should be of the format :", tagsStr) - } else if strings.Count(tag, ":") > 1 { - return fmt.Errorf("%s should only contain one : pair", tagsStr) - } - - keyValue := strings.Split(tag, ":") - if keyValue[0] == types.TxHeightKey { - tag = fmt.Sprintf("%s=%s", keyValue[0], keyValue[1]) - } else { - tag = fmt.Sprintf("%s='%s'", keyValue[0], keyValue[1]) - } - tmTags = append(tmTags, tag) - } - - page := viper.GetInt(flagPage) - limit := viper.GetInt(flagLimit) - - cliCtx := context.NewCLIContext().WithCodec(cdc) - txs, err := SearchTxs(cliCtx, tmTags, page, limit) - if err != nil { - return err - } - - var output []byte - if cliCtx.Indent { - output, err = cdc.MarshalJSONIndent(txs, "", " ") - } else { - output, err = cdc.MarshalJSON(txs) - } - - if err != nil { - return err - } - - fmt.Println(string(output)) - return nil - }, - } - - cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") - viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) - cmd.Flags().Bool(flags.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") - viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) - - cmd.Flags().String(flagTags, "", "tag:value list of tags that must match") - cmd.Flags().Uint32(flagPage, rest.DefaultPage, "Query a specific page of paginated results") - cmd.Flags().Uint32(flagLimit, rest.DefaultLimit, "Query number of transactions results per page returned") - cmd.MarkFlagRequired(flagTags) - - return cmd -} - -// QueryTxCmd implements the default command for a tx query. -func QueryTxCmd(cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "tx [hash]", - Short: "Find a transaction by hash in a committed block.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - cliCtx := context.NewCLIContext().WithCodec(cdc) - - output, err := queryTx(cliCtx, args[0]) - if err != nil { - return err - } - - if output.Empty() { - return fmt.Errorf("No transaction found with hash %s", args[0]) - } - - return cliCtx.PrintOutput(output) - }, - } - - cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") - viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) - cmd.Flags().Bool(flags.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") - viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) - - return cmd -} - -// ---------------------------------------------------------------------------- -// REST -// ---------------------------------------------------------------------------- - -// QueryTxsByTagsRequestHandlerFn implements a REST handler that searches for -// transactions by tags. -func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var ( - tags []string - txs []sdk.TxResponse - page, limit int - ) - - err := r.ParseForm() - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, - sdk.AppendMsgToErr("could not parse query parameters", err.Error())) - return - } - - cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) - if !ok { - return - } - - if len(r.Form) == 0 { - rest.PostProcessResponse(w, cliCtx, txs) - return - } - - tags, page, limit, err = rest.ParseHTTPArgs(r) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - searchResult, err := SearchTxs(cliCtx, tags, page, limit) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - rest.PostProcessResponse(w, cliCtx, searchResult) - } -} - -// QueryTxRequestHandlerFn implements a REST handler that queries a transaction -// by hash in a committed block. -func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - hashHexStr := vars["hash"] - - cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) - if !ok { - return - } - - output, err := queryTx(cliCtx, hashHexStr) - if err != nil { - if strings.Contains(err.Error(), hashHexStr) { - rest.WriteErrorResponse(w, http.StatusNotFound, err.Error()) - return - } - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if output.Empty() { - rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr)) - } - - rest.PostProcessResponse(w, cliCtx, output) - } -} diff --git a/client/tx/root.go b/client/tx/root.go deleted file mode 100644 index 446902b53..000000000 --- a/client/tx/root.go +++ /dev/null @@ -1,15 +0,0 @@ -package tx - -import ( - "github.com/gorilla/mux" - - "github.com/cosmos/cosmos-sdk/client/context" -) - -// register REST routes -func RegisterTxRoutes(cliCtx context.CLIContext, r *mux.Router) { - r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc("/txs", QueryTxsByTagsRequestHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc("/txs", BroadcastTxRequest(cliCtx)).Methods("POST") - r.HandleFunc("/txs/encode", EncodeTxRequestHandlerFn(cliCtx)).Methods("POST") -} diff --git a/client/utils/errors.go b/client/utils/errors.go deleted file mode 100644 index 58d925692..000000000 --- a/client/utils/errors.go +++ /dev/null @@ -1,5 +0,0 @@ -package utils - -import "errors" - -var errInvalidSigner = errors.New("tx intended signer does not match the given signer") diff --git a/x/auth/client/cli/broadcast.go b/x/auth/client/cli/broadcast.go new file mode 100644 index 000000000..a445c88a0 --- /dev/null +++ b/x/auth/client/cli/broadcast.go @@ -0,0 +1,47 @@ +package cli + +import ( + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" +) + +// GetBroadcastCommand returns the tx broadcast command. +func GetBroadcastCommand(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "broadcast [file_path]", + Short: "Broadcast transactions generated offline", + Long: strings.TrimSpace(`Broadcast transactions created with the --generate-only +flag and signed with the sign command. Read a transaction from [file_path] and +broadcast it to a node. If you supply a dash (-) argument in place of an input +filename, the command reads from standard input. + +$ tx broadcast ./mytxn.json +`), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + cliCtx := context.NewCLIContext().WithCodec(cdc) + stdTx, err := utils.ReadStdTxFromFile(cliCtx.Codec, args[0]) + if err != nil { + return + } + + txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(stdTx) + if err != nil { + return + } + + res, err := cliCtx.BroadcastTx(txBytes) + cliCtx.PrintOutput(res) // nolint:errcheck + + return err + }, + } + + return flags.PostCommands(cmd)[0] +} diff --git a/client/tx/encode.go b/x/auth/client/cli/encode.go similarity index 53% rename from client/tx/encode.go rename to x/auth/client/cli/encode.go index 74e3abbda..508a8eae8 100644 --- a/client/tx/encode.go +++ b/x/auth/client/cli/encode.go @@ -1,64 +1,16 @@ -package tx +package cli import ( "encoding/base64" - "io/ioutil" - "net/http" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" ) -type ( - // EncodeReq defines a tx encoding request. - // Use auth.StdTx directly - - // EncodeResp defines a tx encoding response. - EncodeResp struct { - Tx string `json:"tx"` - } -) - -// EncodeTxRequestHandlerFn returns the encode tx REST handler. In particular, -// it takes a json-formatted transaction, encodes it to the Amino wire protocol, -// and responds with base64-encoded bytes. -func EncodeTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req auth.StdTx - - body, err := ioutil.ReadAll(r.Body) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - err = cliCtx.Codec.UnmarshalJSON(body, &req) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - // re-encode it via the Amino wire protocol - txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(req) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - // base64 encode the encoded tx bytes - txBytesBase64 := base64.StdEncoding.EncodeToString(txBytes) - - response := EncodeResp{Tx: txBytesBase64} - rest.PostProcessResponse(w, cliCtx, response) - } -} - // txEncodeRespStr implements a simple Stringer wrapper for a encoded tx. type txEncodeRespStr string diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index 0227e30d1..f5da295f1 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -1,14 +1,28 @@ package cli import ( - "github.com/spf13/cobra" + "fmt" + "strings" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "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/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth/types" + + tmtypes "github.com/tendermint/tendermint/types" +) + +const ( + flagTags = "tags" + flagPage = "page" + flagLimit = "limit" ) // GetTxCmd returns the transaction commands for this module @@ -18,15 +32,16 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the auth module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } + cmd.AddCommand(GetAccountCmd(cdc)) + return cmd } // GetAccountCmd returns a query account that will display the state of the // account at a given address. -// nolint: unparam func GetAccountCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "account [address]", @@ -53,5 +68,114 @@ func GetAccountCmd(cdc *codec.Codec) *cobra.Command { return cliCtx.PrintOutput(acc) }, } + return flags.GetCommands(cmd)[0] } + +// QueryTxsByTagsCmd returns a command to search through tagged transactions. +func QueryTxsByTagsCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "txs", + Short: "Query for paginated transactions that match a set of tags", + Long: strings.TrimSpace(` +Search for transactions that match the exact given tags where results are paginated. + +Example: +$ query txs --tags ':&:' --page 1 --limit 30 +`), + RunE: func(cmd *cobra.Command, args []string) error { + tagsStr := viper.GetString(flagTags) + tagsStr = strings.Trim(tagsStr, "'") + + var tags []string + if strings.Contains(tagsStr, "&") { + tags = strings.Split(tagsStr, "&") + } else { + tags = append(tags, tagsStr) + } + + var tmTags []string + for _, tag := range tags { + if !strings.Contains(tag, ":") { + return fmt.Errorf("%s should be of the format :", tagsStr) + } else if strings.Count(tag, ":") > 1 { + return fmt.Errorf("%s should only contain one : pair", tagsStr) + } + + keyValue := strings.Split(tag, ":") + if keyValue[0] == tmtypes.TxHeightKey { + tag = fmt.Sprintf("%s=%s", keyValue[0], keyValue[1]) + } else { + tag = fmt.Sprintf("%s='%s'", keyValue[0], keyValue[1]) + } + + tmTags = append(tmTags, tag) + } + + page := viper.GetInt(flagPage) + limit := viper.GetInt(flagLimit) + + cliCtx := context.NewCLIContext().WithCodec(cdc) + txs, err := utils.QueryTxsByTags(cliCtx, tmTags, page, limit) + if err != nil { + return err + } + + var output []byte + if cliCtx.Indent { + output, err = cdc.MarshalJSONIndent(txs, "", " ") + } else { + output, err = cdc.MarshalJSON(txs) + } + + if err != nil { + return err + } + + fmt.Println(string(output)) + return nil + }, + } + + cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") + viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) + cmd.Flags().Bool(flags.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") + viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) + + cmd.Flags().String(flagTags, "", "tag:value list of tags that must match") + cmd.Flags().Uint32(flagPage, rest.DefaultPage, "Query a specific page of paginated results") + cmd.Flags().Uint32(flagLimit, rest.DefaultLimit, "Query number of transactions results per page returned") + cmd.MarkFlagRequired(flagTags) + + return cmd +} + +// QueryTxCmd implements the default command for a tx query. +func QueryTxCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "tx [hash]", + Short: "Query for a transaction by hash in a committed block", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + output, err := utils.QueryTx(cliCtx, args[0]) + if err != nil { + return err + } + + if output.Empty() { + return fmt.Errorf("No transaction found with hash %s", args[0]) + } + + return cliCtx.PrintOutput(output) + }, + } + + cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") + viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)) + cmd.Flags().Bool(flags.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") + viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) + + return cmd +} diff --git a/x/auth/client/cli/tx.go b/x/auth/client/cli/tx.go index 83b6d4606..7ee246c38 100644 --- a/x/auth/client/cli/tx.go +++ b/x/auth/client/cli/tx.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client/utils" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -15,7 +15,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Auth transaction subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } txCmd.AddCommand( GetMultiSignCommand(cdc), diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index c1a88a6a0..34c5630da 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -15,10 +15,10 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" crkeys "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth/types" ) diff --git a/x/auth/client/cli/tx_sign.go b/x/auth/client/cli/tx_sign.go index f7be33501..f18cc4de7 100644 --- a/x/auth/client/cli/tx_sign.go +++ b/x/auth/client/cli/tx_sign.go @@ -11,9 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth/types" ) diff --git a/x/auth/client/rest/broadcast.go b/x/auth/client/rest/broadcast.go new file mode 100644 index 000000000..0a625d440 --- /dev/null +++ b/x/auth/client/rest/broadcast.go @@ -0,0 +1,53 @@ +package rest + +import ( + "io/ioutil" + "net/http" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// BroadcastReq defines a tx broadcasting request. +type BroadcastReq struct { + Tx types.StdTx `json:"tx"` + Mode string `json:"mode"` +} + +// BroadcastTxRequest implements a tx broadcasting handler that is responsible +// for broadcasting a valid and signed tx to a full node. The tx can be +// broadcasted via a sync|async|block mechanism. +func BroadcastTxRequest(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req BroadcastReq + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + err = cliCtx.Codec.UnmarshalJSON(body, &req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(req.Tx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithBroadcastMode(req.Mode) + + res, err := cliCtx.BroadcastTx(txBytes) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + rest.PostProcessResponse(w, cliCtx, res) + } +} diff --git a/x/auth/client/rest/encode.go b/x/auth/client/rest/encode.go new file mode 100644 index 000000000..36e546902 --- /dev/null +++ b/x/auth/client/rest/encode.go @@ -0,0 +1,50 @@ +package rest + +import ( + "encoding/base64" + "io/ioutil" + "net/http" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// EncodeResp defines a tx encoding response. +type EncodeResp struct { + Tx string `json:"tx"` +} + +// EncodeTxRequestHandlerFn returns the encode tx REST handler. In particular, +// it takes a json-formatted transaction, encodes it to the Amino wire protocol, +// and responds with base64-encoded bytes. +func EncodeTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.StdTx + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + err = cliCtx.Codec.UnmarshalJSON(body, &req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // re-encode it via the Amino wire protocol + txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + // base64 encode the encoded tx bytes + txBytesBase64 := base64.StdEncoding.EncodeToString(txBytes) + + response := EncodeResp{Tx: txBytesBase64} + rest.PostProcessResponse(w, cliCtx, response) + } +} diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 4cc23d63e..a6900969c 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -1,14 +1,16 @@ package rest import ( + "fmt" "net/http" + "strings" "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -19,19 +21,6 @@ type AccountWithHeight struct { Height int64 `json:"height"` } -// register REST routes -func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string) { - r.HandleFunc( - "/auth/accounts/{address}", - QueryAccountRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx), - ).Methods("GET") - - r.HandleFunc( - "/bank/balances/{address}", - QueryBalancesRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx), - ).Methods("GET") -} - // query accountREST Handler func QueryAccountRequestHandlerFn( storeName string, decoder types.AccountDecoder, cliCtx context.CLIContext, @@ -118,3 +107,76 @@ func QueryBalancesRequestHandlerFn( rest.PostProcessResponse(w, cliCtx, account.GetCoins()) } } + +// QueryTxsByTagsRequestHandlerFn implements a REST handler that searches for +// transactions by tags. +func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + tags []string + txs []sdk.TxResponse + page, limit int + ) + + err := r.ParseForm() + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, + sdk.AppendMsgToErr("could not parse query parameters", err.Error())) + return + } + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + if len(r.Form) == 0 { + rest.PostProcessResponse(w, cliCtx, txs) + return + } + + tags, page, limit, err = rest.ParseHTTPArgs(r) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, page, limit) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + rest.PostProcessResponse(w, cliCtx, searchResult) + } +} + +// QueryTxRequestHandlerFn implements a REST handler that queries a transaction +// by hash in a committed block. +func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + hashHexStr := vars["hash"] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + output, err := utils.QueryTx(cliCtx, hashHexStr) + if err != nil { + if strings.Contains(err.Error(), hashHexStr) { + rest.WriteErrorResponse(w, http.StatusNotFound, err.Error()) + return + } + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + if output.Empty() { + rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr)) + } + + rest.PostProcessResponse(w, cliCtx, output) + } +} diff --git a/x/auth/client/rest/rest.go b/x/auth/client/rest/rest.go new file mode 100644 index 000000000..707750fa3 --- /dev/null +++ b/x/auth/client/rest/rest.go @@ -0,0 +1,29 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" +) + +// RegisterRoutes registers the auth module REST routes. +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string) { + r.HandleFunc( + "/auth/accounts/{address}", + QueryAccountRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx), + ).Methods("GET") + + // TODO: Change path or mount under x/bank if possible + r.HandleFunc( + "/bank/balances/{address}", + QueryBalancesRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx), + ).Methods("GET") +} + +// RegisterTxRoutes registers all transaction routes on the provided router. +func RegisterTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/txs", QueryTxsByTagsRequestHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/txs", BroadcastTxRequest(cliCtx)).Methods("POST") + r.HandleFunc("/txs/encode", EncodeTxRequestHandlerFn(cliCtx)).Methods("POST") +} diff --git a/x/auth/client/utils/errors.go b/x/auth/client/utils/errors.go new file mode 100644 index 000000000..0a0fc7a0f --- /dev/null +++ b/x/auth/client/utils/errors.go @@ -0,0 +1,8 @@ +package utils + +import "errors" + +var ( + errInvalidSigner = errors.New("tx intended signer does not match the given signer") + errInvalidGasAdjustment = errors.New("invalid gas adjustment") +) diff --git a/client/tx/utils.go b/x/auth/client/utils/query.go similarity index 88% rename from client/tx/utils.go rename to x/auth/client/utils/query.go index b16412db3..b79465298 100644 --- a/client/tx/utils.go +++ b/x/auth/client/utils/query.go @@ -1,4 +1,4 @@ -package tx +package utils import ( "encoding/hex" @@ -11,13 +11,13 @@ import ( "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/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/types" ) -// SearchTxs performs a search for transactions for a given set of tags via +// QueryTxsByTags performs a search for transactions for a given set of tags via // Tendermint RPC. It returns a slice of Info object containing txs and metadata. // An error is returned if the query fails. -func SearchTxs(cliCtx context.CLIContext, tags []string, page, limit int) (*sdk.SearchTxsResult, error) { +func QueryTxsByTags(cliCtx context.CLIContext, tags []string, page, limit int) (*sdk.SearchTxsResult, error) { if len(tags) == 0 { return nil, errors.New("must declare at least one tag to search") } @@ -69,6 +69,43 @@ func SearchTxs(cliCtx context.CLIContext, tags []string, page, limit int) (*sdk. return &result, nil } +// QueryTx queries for a single transaction by a hash string in hex format. An +// error is returned if the transaction does not exist or cannot be queried. +func QueryTx(cliCtx context.CLIContext, hashHexStr string) (sdk.TxResponse, error) { + hash, err := hex.DecodeString(hashHexStr) + if err != nil { + return sdk.TxResponse{}, err + } + + node, err := cliCtx.GetNode() + if err != nil { + return sdk.TxResponse{}, err + } + + resTx, err := node.Tx(hash, !cliCtx.TrustNode) + if err != nil { + return sdk.TxResponse{}, err + } + + if !cliCtx.TrustNode { + if err = ValidateTxResult(cliCtx, resTx); err != nil { + return sdk.TxResponse{}, err + } + } + + resBlocks, err := getBlocksForTxResults(cliCtx, []*ctypes.ResultTx{resTx}) + if err != nil { + return sdk.TxResponse{}, err + } + + out, err := formatTxResult(cliCtx.Codec, resTx, resBlocks[resTx.Height]) + if err != nil { + return out, err + } + + return out, nil +} + // formatTxResults parses the indexed txs into a slice of TxResponse objects. func formatTxResults(cdc *codec.Codec, resTxs []*ctypes.ResultTx, resBlocks map[int64]*ctypes.ResultBlock) ([]sdk.TxResponse, error) { var err error @@ -130,7 +167,7 @@ func formatTxResult(cdc *codec.Codec, resTx *ctypes.ResultTx, resBlock *ctypes.R } func parseTx(cdc *codec.Codec, txBytes []byte) (sdk.Tx, error) { - var tx auth.StdTx + var tx types.StdTx err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) if err != nil { @@ -139,38 +176,3 @@ func parseTx(cdc *codec.Codec, txBytes []byte) (sdk.Tx, error) { return tx, nil } - -func queryTx(cliCtx context.CLIContext, hashHexStr string) (sdk.TxResponse, error) { - hash, err := hex.DecodeString(hashHexStr) - if err != nil { - return sdk.TxResponse{}, err - } - - node, err := cliCtx.GetNode() - if err != nil { - return sdk.TxResponse{}, err - } - - resTx, err := node.Tx(hash, !cliCtx.TrustNode) - if err != nil { - return sdk.TxResponse{}, err - } - - if !cliCtx.TrustNode { - if err = ValidateTxResult(cliCtx, resTx); err != nil { - return sdk.TxResponse{}, err - } - } - - resBlocks, err := getBlocksForTxResults(cliCtx, []*ctypes.ResultTx{resTx}) - if err != nil { - return sdk.TxResponse{}, err - } - - out, err := formatTxResult(cliCtx.Codec, resTx, resBlocks[resTx.Height]) - if err != nil { - return out, err - } - - return out, nil -} diff --git a/client/rest/rest.go b/x/auth/client/utils/rest.go similarity index 75% rename from client/rest/rest.go rename to x/auth/client/utils/rest.go index 12cb79018..c86933873 100644 --- a/client/rest/rest.go +++ b/x/auth/client/utils/rest.go @@ -1,4 +1,4 @@ -package rest +package utils import ( "log" @@ -6,15 +6,11 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/utils" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/types" ) -// ---------------------------------------------------------------------------- -// Building / Sending utilities - // WriteGenerateStdTxResponse writes response for the generate only mode. func WriteGenerateStdTxResponse(w http.ResponseWriter, cliCtx context.CLIContext, br rest.BaseReq, msgs []sdk.Msg) { gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, br.GasAdjustment, flags.DefaultGasAdjustment) @@ -28,8 +24,8 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cliCtx context.CLIContext return } - txBldr := auth.NewTxBuilder( - utils.GetTxEncoder(cliCtx.Codec), br.AccountNumber, br.Sequence, gas, gasAdj, + txBldr := types.NewTxBuilder( + GetTxEncoder(cliCtx.Codec), br.AccountNumber, br.Sequence, gas, gasAdj, br.Simulate, br.ChainID, br.Memo, br.Fees, br.GasPrices, ) @@ -39,7 +35,7 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cliCtx context.CLIContext return } - txBldr, err = utils.EnrichWithGas(txBldr, cliCtx, msgs) + txBldr, err = EnrichWithGas(txBldr, cliCtx, msgs) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return @@ -57,7 +53,7 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cliCtx context.CLIContext return } - output, err := cliCtx.Codec.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo)) + output, err := cliCtx.Codec.MarshalJSON(types.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo)) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return diff --git a/client/utils/utils.go b/x/auth/client/utils/tx.go similarity index 88% rename from client/utils/utils.go rename to x/auth/client/utils/tx.go index f55793e4c..7dcb43ec1 100644 --- a/client/utils/utils.go +++ b/x/auth/client/utils/tx.go @@ -7,7 +7,6 @@ import ( "os" "github.com/pkg/errors" - "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" @@ -60,7 +59,7 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon } gasEst := GasEstimateResponse{GasEstimate: txBldr.Gas()} - fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) + _, _ = fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) } if cliCtx.Simulate { @@ -83,12 +82,12 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon json = cliCtx.Codec.MustMarshalJSON(stdSignMsg) } - fmt.Fprintf(os.Stderr, "%s\n\n", json) + _, _ = fmt.Fprintf(os.Stderr, "%s\n\n", json) buf := input.BufferStdin() ok, err := input.GetConfirmation("confirm transaction before signing and broadcasting", buf) if err != nil || !ok { - fmt.Fprintf(os.Stderr, "%s\n", "cancelled transaction") + _, _ = fmt.Fprintf(os.Stderr, "%s\n", "cancelled transaction") return err } } @@ -120,26 +119,31 @@ func EnrichWithGas(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs [ if err != nil { return txBldr, err } + return txBldr.WithGas(adjusted), nil } // CalculateGas simulates the execution of a transaction and returns // both the estimate obtained by the query and the adjusted amount. -func CalculateGas(queryFunc func(string, []byte) ([]byte, int64, error), - cdc *codec.Codec, txBytes []byte, adjustment float64) (estimate, adjusted uint64, err error) { +func CalculateGas( + queryFunc func(string, []byte) ([]byte, int64, error), cdc *codec.Codec, + txBytes []byte, adjustment float64, +) (estimate, adjusted uint64, err error) { // run a simulation (via /app/simulate query) to // estimate gas and update TxBuilder accordingly rawRes, _, err := queryFunc("/app/simulate", txBytes) if err != nil { - return + return estimate, adjusted, err } + estimate, err = parseQueryResponse(cdc, rawRes) if err != nil { return } + adjusted = adjustGasEstimate(estimate, adjustment) - return + return estimate, adjusted, nil } // PrintUnsignedStdTx builds an unsigned StdTx and prints it to os.Stdout. @@ -225,17 +229,21 @@ func SignStdTxWithSignerAddress(txBldr authtypes.TxBuilder, cliCtx context.CLICo // Read and decode a StdTx from the given filename. Can pass "-" to read from stdin. func ReadStdTxFromFile(cdc *codec.Codec, filename string) (stdTx authtypes.StdTx, err error) { var bytes []byte + if filename == "-" { bytes, err = ioutil.ReadAll(os.Stdin) } else { bytes, err = ioutil.ReadFile(filename) } + if err != nil { return } + if err = cdc.UnmarshalJSON(bytes, &stdTx); err != nil { return } + return } @@ -263,7 +271,8 @@ func GetTxEncoder(cdc *codec.Codec) (encoder sdk.TxEncoder) { if encoder == nil { encoder = authtypes.DefaultTxEncoder(cdc) } - return + + return encoder } // nolint @@ -273,6 +282,7 @@ func simulateMsgs(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs [] if err != nil { return } + estimated, adjusted, err = CalculateGas(cliCtx.QueryWithData, cliCtx.Codec, txBytes, txBldr.GasAdjustment()) return } @@ -286,6 +296,7 @@ func parseQueryResponse(cdc *codec.Codec, rawRes []byte) (uint64, error) { if err := cdc.UnmarshalBinaryLengthPrefixed(rawRes, &simulationResult); err != nil { return 0, err } + return simulationResult.GasUsed, nil } @@ -316,6 +327,7 @@ func PrepareTxBuilder(txBldr authtypes.TxBuilder, cliCtx context.CLIContext) (au } txBldr = txBldr.WithSequence(accSeq) } + return txBldr, nil } @@ -330,7 +342,7 @@ func buildUnsignedStdTxOffline(txBldr authtypes.TxBuilder, cliCtx context.CLICon return stdTx, err } - fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas()) + _, _ = fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas()) } stdSignMsg, err := txBldr.BuildSignMsg(msgs) @@ -350,33 +362,3 @@ func isTxSigner(user sdk.AccAddress, signers []sdk.AccAddress) bool { return false } - -// ValidateCmd returns unknown command error or Help display if help flag set -func ValidateCmd(cmd *cobra.Command, args []string) error { - var cmds []string - var help bool - - // construct array of commands and search for help flag - for _, arg := range args { - if arg == "--help" || arg == "-h" { - help = true - } else if len(arg) > 0 && !(arg[0] == '-') { - cmds = append(cmds, arg) - } - } - - if !help && len(cmds) > 0 { - err := fmt.Sprintf("unknown command \"%s\" for \"%s\"", cmds[0], cmd.CalledAs()) - - // build suggestions for unknown argument - if suggestions := cmd.SuggestionsFor(cmds[0]); len(suggestions) > 0 { - err += "\n\nDid you mean this?\n" - for _, s := range suggestions { - err += fmt.Sprintf("\t%v\n", s) - } - } - return errors.New(err) - } - - return cmd.Help() -} diff --git a/client/utils/utils_test.go b/x/auth/client/utils/tx_test.go similarity index 79% rename from client/utils/utils_test.go rename to x/auth/client/utils/tx_test.go index b0cc27fa3..3ae79f7bd 100644 --- a/client/utils/utils_test.go +++ b/x/auth/client/utils/tx_test.go @@ -7,7 +7,6 @@ import ( "os" "testing" - "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" @@ -112,49 +111,6 @@ func TestReadStdTxFromFile(t *testing.T) { require.Equal(t, decodedTx.Memo, "foomemo") } -func TestValidateCmd(t *testing.T) { - // Setup root and subcommands - rootCmd := &cobra.Command{ - Use: "root", - } - queryCmd := &cobra.Command{ - Use: "query", - } - rootCmd.AddCommand(queryCmd) - - // Command being tested - distCmd := &cobra.Command{ - Use: "distr", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - queryCmd.AddCommand(distCmd) - - commissionCmd := &cobra.Command{ - Use: "commission", - } - distCmd.AddCommand(commissionCmd) - - tests := []struct { - reason string - args []string - wantErr bool - }{ - {"misspelled command", []string{"comission"}, true}, - {"no command provided", []string{}, false}, - {"help flag", []string{"comission", "--help"}, false}, - {"shorthand help flag", []string{"comission", "-h"}, false}, - } - - for _, tt := range tests { - err := ValidateCmd(distCmd, tt.args) - assert.Equal(t, tt.wantErr, err != nil, tt.reason) - } - -} - -// aux functions - func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) { msgs := []sdk.Msg{sdk.NewTestMsg(addr)} tx := authtypes.NewStdTx(msgs, authtypes.StdFee{}, []authtypes.StdSignature{}, "") diff --git a/x/bank/client/cli/tx.go b/x/bank/client/cli/tx.go index 6d2335256..9383341a9 100644 --- a/x/bank/client/cli/tx.go +++ b/x/bank/client/cli/tx.go @@ -5,18 +5,13 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" ) -const ( - flagTo = "to" - flagAmount = "amount" -) - // GetTxCmd returns the transaction commands for this module func GetTxCmd(cdc *codec.Codec) *cobra.Command { txCmd := &cobra.Command{ @@ -24,7 +19,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Bank transaction subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } txCmd.AddCommand( SendTxCmd(cdc), diff --git a/x/bank/client/rest/tx.go b/x/bank/client/rest/tx.go index 682cfcf00..9bc9bc345 100644 --- a/x/bank/client/rest/tx.go +++ b/x/bank/client/rest/tx.go @@ -6,10 +6,10 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" ) @@ -60,6 +60,6 @@ func SendRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } msg := types.NewMsgSend(fromAddr, toAddr, req.Amount) - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/crisis/client/cli/tx.go b/x/crisis/client/cli/tx.go index 4cd41c4f1..ab16b0bfe 100644 --- a/x/crisis/client/cli/tx.go +++ b/x/crisis/client/cli/tx.go @@ -6,10 +6,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/crisis/types" ) @@ -40,7 +40,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Crisis transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } txCmd.AddCommand(client.PostCommands( diff --git a/x/distribution/client/cli/query.go b/x/distribution/client/cli/query.go index f227e1159..36d12e57f 100644 --- a/x/distribution/client/cli/query.go +++ b/x/distribution/client/cli/query.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -24,7 +23,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the distribution module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } distQueryCmd.AddCommand(client.GetCommands( diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 98756eb82..4f99777bc 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -10,12 +10,12 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - auth "github.com/cosmos/cosmos-sdk/x/auth" - gov "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/distribution/client/common" "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -39,7 +39,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Distribution transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } distTxCmd.AddCommand(client.PostCommands( diff --git a/x/distribution/client/cli/tx_test.go b/x/distribution/client/cli/tx_test.go index 699646408..af09d5445 100644 --- a/x/distribution/client/cli/tx_test.go +++ b/x/distribution/client/cli/tx_test.go @@ -7,10 +7,10 @@ import ( "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" ) func createFakeTxBuilder() auth.TxBuilder { diff --git a/x/distribution/client/rest/rest.go b/x/distribution/client/rest/rest.go index d9ea00c47..3b09478ec 100644 --- a/x/distribution/client/rest/rest.go +++ b/x/distribution/client/rest/rest.go @@ -6,9 +6,9 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/gov" govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" @@ -48,6 +48,6 @@ func postProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/distribution/client/rest/tx.go b/x/distribution/client/rest/tx.go index 89abb08fc..7f1410b4d 100644 --- a/x/distribution/client/rest/tx.go +++ b/x/distribution/client/rest/tx.go @@ -6,7 +6,7 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/distribution/client/common" "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -77,7 +77,7 @@ func withdrawDelegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute str return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, msgs) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, msgs) } } @@ -112,7 +112,7 @@ func withdrawDelegationRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerF return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -142,7 +142,7 @@ func setDelegatorWithdrawalAddrHandlerFn(cliCtx context.CLIContext) http.Handler return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -173,7 +173,7 @@ func withdrawValidatorRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFu return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, msgs) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, msgs) } } diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index bb04bc2ff..545b0cecc 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -25,6 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -117,7 +118,7 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm return err } - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(client.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := client.NewCLIContext().WithCodec(cdc) // Set the generate-only flag here after the CLI context has @@ -140,14 +141,14 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm if info.GetType() == kbkeys.TypeOffline || info.GetType() == kbkeys.TypeMulti { fmt.Println("Offline key passed in. Use `tx sign` command to sign:") - return client.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}) + return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}) } // write the unsigned transaction to the buffer w := bytes.NewBuffer([]byte{}) cliCtx = cliCtx.WithOutput(w) - if err = client.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}); err != nil { + if err = utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}); err != nil { return err } @@ -158,7 +159,7 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm } // sign the transaction and write it to the output file - signedTx, err := client.SignStdTx(txBldr, cliCtx, name, stdTx, false, true) + signedTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, false, true) if err != nil { return err } diff --git a/x/gov/client/cli/query.go b/x/gov/client/cli/query.go index e6b3b7489..28b957e41 100644 --- a/x/gov/client/cli/query.go +++ b/x/gov/client/cli/query.go @@ -10,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -26,7 +25,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the governance module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } govQueryCmd.AddCommand(client.GetCommands( diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 144085688..b7ff43bd3 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -9,11 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" govutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -59,7 +59,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec, pcmds []*cobra.Command) *cobra. Short: "Governance transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } cmdSubmitProp := GetCmdSubmitProposal(cdc) diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index 297b21de9..212cc455b 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -8,9 +8,9 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -107,7 +107,7 @@ func postProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -144,7 +144,7 @@ func depositHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -187,7 +187,7 @@ func voteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/gov/client/utils/query.go b/x/gov/client/utils/query.go index 8675b9705..d1605b801 100644 --- a/x/gov/client/utils/query.go +++ b/x/gov/client/utils/query.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/tags" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -44,7 +44,7 @@ func QueryDepositsByTxQuery(cliCtx context.CLIContext, params types.QueryProposa // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. - searchResult, err := tx.SearchTxs(cliCtx, tags, defaultPage, defaultLimit) + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit) if err != nil { return nil, err } @@ -86,7 +86,7 @@ func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalPa // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. - searchResult, err := tx.SearchTxs(cliCtx, tags, defaultPage, defaultLimit) + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit) if err != nil { return nil, err } @@ -124,7 +124,7 @@ func QueryVoteByTxQuery(cliCtx context.CLIContext, params types.QueryVoteParams) // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. - searchResult, err := tx.SearchTxs(cliCtx, tags, defaultPage, defaultLimit) + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit) if err != nil { return nil, err } @@ -164,7 +164,7 @@ func QueryDepositByTxQuery(cliCtx context.CLIContext, params types.QueryDepositP // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. - searchResult, err := tx.SearchTxs(cliCtx, tags, defaultPage, defaultLimit) + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit) if err != nil { return nil, err } @@ -203,7 +203,7 @@ func QueryProposerByTxQuery(cliCtx context.CLIContext, proposalID uint64) (Propo // NOTE: SearchTxs is used to facilitate the txs query which does not currently // support configurable pagination. - searchResult, err := tx.SearchTxs(cliCtx, tags, defaultPage, defaultLimit) + searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit) if err != nil { return Proposer{}, err } diff --git a/x/ibc/client/cli/ibctx.go b/x/ibc/client/cli/ibctx.go index 0b706cbed..7716e2157 100644 --- a/x/ibc/client/cli/ibctx.go +++ b/x/ibc/client/cli/ibctx.go @@ -5,10 +5,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/spf13/cobra" diff --git a/x/ibc/client/cli/relay.go b/x/ibc/client/cli/relay.go index 071a91109..224d7e9c4 100644 --- a/x/ibc/client/cli/relay.go +++ b/x/ibc/client/cli/relay.go @@ -4,7 +4,7 @@ import ( "os" "time" - "github.com/cosmos/cosmos-sdk/client/utils" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client/context" diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 49d3e67b9..f9e363eab 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -4,9 +4,9 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/gorilla/mux" @@ -55,6 +55,6 @@ func TransferRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { packet := ibc.NewIBCPacket(from, to, req.Amount, req.BaseReq.ChainID, destChainID) msg := ibc.MsgIBCTransfer{IBCPacket: packet} - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/mint/client/cli/query.go b/x/mint/client/cli/query.go index b50e37096..335070636 100644 --- a/x/mint/client/cli/query.go +++ b/x/mint/client/cli/query.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mint/internal/types" @@ -20,7 +19,7 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the minting module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } mintingQueryCmd.AddCommand( diff --git a/x/params/client/cli/tx.go b/x/params/client/cli/tx.go index d974f02b9..a493e4628 100644 --- a/x/params/client/cli/tx.go +++ b/x/params/client/cli/tx.go @@ -7,11 +7,11 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/gov" paramscutils "github.com/cosmos/cosmos-sdk/x/params/client/utils" "github.com/cosmos/cosmos-sdk/x/params/types" diff --git a/x/params/client/rest/rest.go b/x/params/client/rest/rest.go index 3f84823fa..4d95932b1 100644 --- a/x/params/client/rest/rest.go +++ b/x/params/client/rest/rest.go @@ -4,9 +4,9 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/gov" govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" "github.com/cosmos/cosmos-sdk/x/params" @@ -42,6 +42,6 @@ func postProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/slashing/client/cli/query.go b/x/slashing/client/cli/query.go index 5ca6004af..07b55458b 100644 --- a/x/slashing/client/cli/query.go +++ b/x/slashing/client/cli/query.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -23,7 +22,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the slashing module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } slashingQueryCmd.AddCommand( diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 01663254a..ccc57275c 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -5,10 +5,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "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" "github.com/cosmos/cosmos-sdk/x/slashing/types" ) @@ -19,7 +19,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Slashing transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } slashingTxCmd.AddCommand(client.PostCommands( diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 51b44004a..39b330ab6 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -7,9 +7,9 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/slashing/types" ) @@ -65,6 +65,6 @@ func unjailRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/staking/client/cli/query.go b/x/staking/client/cli/query.go index 8f4258b75..e0fb7417c 100644 --- a/x/staking/client/cli/query.go +++ b/x/staking/client/cli/query.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -22,7 +21,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { Short: "Querying commands for the staking module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } stakingQueryCmd.AddCommand(client.GetCommands( GetCmdQueryDelegation(queryRoute, cdc), diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 3f39e481d..5baf19304 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -14,11 +14,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -29,7 +29,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Staking transaction subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: utils.ValidateCmd, + RunE: client.ValidateCmd, } stakingTxCmd.AddCommand(client.PostCommands( diff --git a/x/staking/client/rest/tx.go b/x/staking/client/rest/tx.go index 1e7d8f27b..e755c9a4e 100644 --- a/x/staking/client/rest/tx.go +++ b/x/staking/client/rest/tx.go @@ -7,9 +7,9 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - clientrest "github.com/cosmos/cosmos-sdk/client/rest" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -85,7 +85,7 @@ func postDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -119,7 +119,7 @@ func postRedelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -153,6 +153,6 @@ func postUnbondingDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFu return } - clientrest.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/staking/client/rest/utils.go b/x/staking/client/rest/utils.go index 6730346c9..1d07c04a2 100644 --- a/x/staking/client/rest/utils.go +++ b/x/staking/client/rest/utils.go @@ -7,9 +7,9 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/staking/tags" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -33,7 +33,7 @@ func queryTxs(cliCtx context.CLIContext, tag string, delegatorAddr string) (*sdk fmt.Sprintf("%s='%s'", tags.Sender, delegatorAddr), } - return tx.SearchTxs(cliCtx, tags, page, limit) + return utils.QueryTxsByTags(cliCtx, tags, page, limit) } func queryBonds(cliCtx context.CLIContext, endpoint string) http.HandlerFunc {