From 1aa6c197ffc57c0ee8cd840148d9b01eeb3786ef Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 14 Feb 2019 16:53:36 +0000 Subject: [PATCH] Merge PR #3580: Code cleanup of client types --- PENDING.md | 5 + client/keys/add.go | 5 +- client/keys/list.go | 5 +- client/keys/show.go | 3 +- client/keys/utils.go | 25 ---- client/lcd/lcd_test.go | 2 +- client/lcd/test_helpers.go | 57 +++----- client/rest/rest.go | 155 +++------------------ client/rpc/block.go | 10 +- client/rpc/codec.go | 2 +- client/rpc/root.go | 3 +- client/rpc/status.go | 5 +- client/rpc/validators.go | 8 +- client/tx/broadcast.go | 5 +- client/tx/query.go | 2 +- client/tx/search.go | 6 +- client/rest/types.go => types/rest/rest.go | 149 ++++++++++++-------- types/rest/rest_test.go | 66 +++++++++ x/auth/client/rest/broadcast.go | 2 +- x/auth/client/rest/encode.go | 3 +- x/auth/client/rest/query.go | 7 +- x/auth/client/rest/requests.go | 9 ++ x/auth/client/rest/sign.go | 3 +- x/bank/client/rest/sendtx.go | 16 ++- x/distribution/client/rest/query.go | 6 +- x/distribution/client/rest/tx.go | 20 +-- x/gov/client/rest/rest.go | 45 +++--- x/ibc/client/rest/transfer.go | 8 +- x/slashing/client/rest/query.go | 3 +- x/slashing/client/rest/rest.go | 4 +- x/slashing/client/rest/tx.go | 10 +- x/staking/client/rest/query.go | 3 +- x/staking/client/rest/tx.go | 33 +++-- x/staking/client/rest/utils.go | 7 +- 34 files changed, 330 insertions(+), 362 deletions(-) rename client/rest/types.go => types/rest/rest.go (52%) create mode 100644 types/rest/rest_test.go create mode 100644 x/auth/client/rest/requests.go diff --git a/PENDING.md b/PENDING.md index a559992b4..f023471de 100644 --- a/PENDING.md +++ b/PENDING.md @@ -9,6 +9,11 @@ BREAKING CHANGES * Gaia * SDK + * \#3580 Migrate HTTP request/response types and utilities to types/rest. + * \#3592 Drop deprecated keybase implementation's New() constructor in + favor of a new crypto/keys.New(string, string) implementation that + returns a lazy keybase instance. Remove client.MockKeyBase, + superseded by crypto/keys.NewInMemory() * \#3621 staking.GenesisState.Bonds -> Delegations * Tendermint diff --git a/client/keys/add.go b/client/keys/add.go index 9b437a340..a6f374e2a 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "errors" @@ -399,7 +400,7 @@ func AddNewKeyRequestHandler(indent bool) http.HandlerFunc { keyOutput.Mnemonic = mnemonic - PostProcessResponse(w, cdc, keyOutput, indent) + rest.PostProcessResponse(w, cdc, keyOutput, indent) } } @@ -488,6 +489,6 @@ func RecoverRequestHandler(indent bool) http.HandlerFunc { return } - PostProcessResponse(w, cdc, keyOutput, indent) + rest.PostProcessResponse(w, cdc, keyOutput, indent) } } diff --git a/client/keys/list.go b/client/keys/list.go index 81a45d0b7..4dda3a86b 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -3,6 +3,7 @@ package keys import ( "net/http" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/spf13/cobra" ) @@ -49,7 +50,7 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc { } // an empty list will be JSONized as null, but we want to keep the empty list if len(infos) == 0 { - PostProcessResponse(w, cdc, []string{}, indent) + rest.PostProcessResponse(w, cdc, []string{}, indent) return } keysOutput, err := Bech32KeysOutput(infos) @@ -58,6 +59,6 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc { _, _ = w.Write([]byte(err.Error())) return } - PostProcessResponse(w, cdc, keysOutput, indent) + rest.PostProcessResponse(w, cdc, keysOutput, indent) } } diff --git a/client/keys/show.go b/client/keys/show.go index 4c1ddf216..903dfeb19 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -7,6 +7,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/types/rest" "errors" @@ -188,6 +189,6 @@ func GetKeyRequestHandler(indent bool) http.HandlerFunc { return } - PostProcessResponse(w, cdc, keyOutput, indent) + rest.PostProcessResponse(w, cdc, keyOutput, indent) } } diff --git a/client/keys/utils.go b/client/keys/utils.go index d5c2f2f55..976654ba2 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -2,14 +2,12 @@ package keys import ( "fmt" - "net/http" "path/filepath" "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/cli" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -217,26 +215,3 @@ func printPubKey(info keys.Info, bechKeyOut bechKeyOutFn) { fmt.Println(ko.PubKey) } - -// PostProcessResponse performs post process for rest response -func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response interface{}, indent bool) { - var output []byte - switch response.(type) { - default: - var err error - if indent { - output, err = cdc.MarshalJSONIndent(response, "", " ") - } else { - output, err = cdc.MarshalJSON(response) - } - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - case []byte: - output = response.([]byte) - } - w.Header().Set("Content-Type", "application/json") - _, _ = w.Write(output) -} diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 6cdaf0331..33a02adfe 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -15,11 +15,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index ede3b4cfd..787f44049 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -20,7 +20,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/rest" + "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" @@ -29,6 +29,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/auth" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" txbuilder "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" @@ -130,7 +131,7 @@ func CreateAddrs(t *testing.T, kb crkeys.Keybase, numAddrs int) (addrs []sdk.Acc password := "1234567890" info, seed, err = kb.CreateMnemonic(name, crkeys.English, password, crkeys.Secp256k1) require.NoError(t, err) - addrSeeds = append(addrSeeds, rest.AddrSeed{Address: sdk.AccAddress(info.GetPubKey().Address()), Seed: seed, Name: name, Password: password}) + addrSeeds = append(addrSeeds, AddrSeed{Address: sdk.AccAddress(info.GetPubKey().Address()), Seed: seed, Name: name, Password: password}) } sort.Sort(addrSeeds) @@ -145,8 +146,16 @@ func CreateAddrs(t *testing.T, kb crkeys.Keybase, numAddrs int) (addrs []sdk.Acc return addrs, seeds, names, passwords } +// AddrSeed combines an Address with the mnemonic of the private key to that address +type AddrSeed struct { + Address sdk.AccAddress + Seed string + Name string + Password string +} + // AddrSeedSlice implements `Interface` in sort package. -type AddrSeedSlice []rest.AddrSeed +type AddrSeedSlice []AddrSeed func (b AddrSeedSlice) Len() int { return len(b) @@ -653,7 +662,7 @@ func doSign(t *testing.T, port, name, password, chainID string, accnum, sequence // POST /tx/broadcast Send a signed Tx func doBroadcast(t *testing.T, port string, msg auth.StdTx) sdk.TxResponse { - tx := rest.BroadcastReq{Tx: msg, Return: "block"} + tx := authrest.BroadcastReq{Tx: msg, Return: "block"} req, err := cdc.MarshalJSON(tx) require.Nil(t, err) res, body := Request(t, port, "POST", "/tx/broadcast", req) @@ -706,7 +715,7 @@ func doTransferWithGas( generateOnly, simulate, ) - sr := rest.SendReq{ + sr := bankrest.SendReq{ Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)}, BaseReq: baseReq, } @@ -739,7 +748,7 @@ func doTransferWithGasAccAuto( fmt.Sprintf("%f", gasAdjustment), 0, 0, fees, nil, generateOnly, simulate, ) - sr := rest.SendReq{ + sr := bankrest.SendReq{ Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)}, BaseReq: baseReq, } @@ -751,11 +760,6 @@ func doTransferWithGasAccAuto( return } -type sendReq struct { - Amount sdk.Coins `json:"amount"` - BaseReq rest.BaseReq `json:"base_req"` -} - // ---------------------------------------------------------------------- // ICS 21 - Stake // ---------------------------------------------------------------------- @@ -841,7 +845,7 @@ func doBeginRedelegation(t *testing.T, port, name, password string, chainID := viper.GetString(client.FlagChainID) baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) - msg := rest.MsgBeginRedelegateInput{ + msg := stakingrest.MsgBeginRedelegateInput{ BaseReq: baseReq, DelegatorAddr: delAddr, ValidatorSrcAddr: valSrcAddr, @@ -1074,7 +1078,7 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA chainID := viper.GetString(client.FlagChainID) baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) - pr := rest.PostProposalReq{ + pr := govrest.PostProposalReq{ Title: "Test", Description: "test", ProposalType: "Text", @@ -1097,15 +1101,6 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA return results } -type postProposalReq struct { - BaseReq rest.BaseReq `json:"base_req"` - Title string `json:"title"` // Title of the proposal - Description string `json:"description"` // Description of the proposal - ProposalType string `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal} - Proposer sdk.AccAddress `json:"proposer"` // Address of the proposer - InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit -} - // GET /gov/proposals Query proposals func getProposalsAll(t *testing.T, port string) []gov.Proposal { res, body := Request(t, port, "GET", "/gov/proposals", nil) @@ -1171,7 +1166,7 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk chainID := viper.GetString(client.FlagChainID) baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) - dr := rest.DepositReq{ + dr := govrest.DepositReq{ Depositor: proposerAddr, Amount: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, amount)}, BaseReq: baseReq, @@ -1190,12 +1185,6 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk return results } -type depositReq struct { - BaseReq rest.BaseReq `json:"base_req"` - Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor - Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit -} - // GET /gov/proposals/{proposalId}/deposits Query deposits func getDeposits(t *testing.T, port string, proposalID uint64) []gov.Deposit { res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), nil) @@ -1225,7 +1214,7 @@ func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.Ac chainID := viper.GetString(client.FlagChainID) baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) - vr := rest.VoteReq{ + vr := govrest.VoteReq{ Voter: proposerAddr, Option: option, BaseReq: baseReq, @@ -1244,12 +1233,6 @@ func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.Ac return results } -type voteReq struct { - BaseReq rest.BaseReq `json:"base_req"` - Voter sdk.AccAddress `json:"voter"` // address of the voter - Option string `json:"option"` // option from OptionSet chosen by the voter -} - // GET /gov/proposals/{proposalId}/votes Query voters func getVotes(t *testing.T, port string, proposalID uint64) []gov.Vote { res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), nil) @@ -1357,7 +1340,7 @@ func doUnjail(t *testing.T, port, seed, name, password string, chainID := viper.GetString(client.FlagChainID) baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", 1, 1, fees, nil, false, false) - ur := rest.UnjailReq{ + ur := slashingrest.UnjailReq{ BaseReq: baseReq, } req, err := cdc.MarshalJSON(ur) diff --git a/client/rest/rest.go b/client/rest/rest.go index 80f48ff29..d5cc7bab1 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -1,9 +1,7 @@ package rest import ( - "fmt" "net/http" - "strconv" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -11,91 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" ) -//----------------------------------------------------------------------------- -// Basic HTTP utilities - -// ErrorResponse defines the attributes of a JSON error response. -type ErrorResponse struct { - Code int `json:"code,omitempty"` - Message string `json:"message"` -} - -// NewErrorResponse creates a new ErrorResponse instance. -func NewErrorResponse(code int, msg string) ErrorResponse { - return ErrorResponse{Code: code, Message: msg} -} - -// WriteErrorResponse prepares and writes a HTTP error -// given a status code and an error message. -func WriteErrorResponse(w http.ResponseWriter, status int, err string) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - w.Write(codec.Cdc.MustMarshalJSON(NewErrorResponse(0, err))) -} - -// WriteSimulationResponse prepares and writes an HTTP -// response for transactions simulations. -func WriteSimulationResponse(w http.ResponseWriter, cdc *codec.Codec, gas uint64) { - gasEst := GasEstimateResponse{GasEstimate: gas} - resp, err := cdc.MarshalJSON(gasEst) - if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - w.Write(resp) -} - -// ParseInt64OrReturnBadRequest converts s to a int64 value. -func ParseInt64OrReturnBadRequest(w http.ResponseWriter, s string) (n int64, ok bool) { - var err error - - n, err = strconv.ParseInt(s, 10, 64) - if err != nil { - err := fmt.Errorf("'%s' is not a valid int64", s) - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return n, false - } - - return n, true -} - -// ParseUint64OrReturnBadRequest converts s to a uint64 value. -func ParseUint64OrReturnBadRequest(w http.ResponseWriter, s string) (n uint64, ok bool) { - var err error - - n, err = strconv.ParseUint(s, 10, 64) - if err != nil { - err := fmt.Errorf("'%s' is not a valid uint64", s) - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return n, false - } - - return n, true -} - -// ParseFloat64OrReturnBadRequest converts s to a float64 value. It returns a -// default value, defaultIfEmpty, if the string is empty. -func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEmpty float64) (n float64, ok bool) { - if len(s) == 0 { - return defaultIfEmpty, true - } - - n, err := strconv.ParseFloat(s, 64) - if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return n, false - } - - return n, true -} - //----------------------------------------------------------------------------- // Building / Sending utilities @@ -104,26 +22,24 @@ func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEm // tx gas simulation and estimation. // // NOTE: Also see CompleteAndBroadcastTxCLI. -func CompleteAndBroadcastTxREST( - w http.ResponseWriter, r *http.Request, cliCtx context.CLIContext, - baseReq BaseReq, msgs []sdk.Msg, cdc *codec.Codec, -) { +func CompleteAndBroadcastTxREST(w http.ResponseWriter, cliCtx context.CLIContext, + baseReq rest.BaseReq, msgs []sdk.Msg, cdc *codec.Codec) { - gasAdj, ok := ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment) + gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment) if !ok { return } simAndExec, gas, err := client.ParseGas(baseReq.Gas) if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } // derive the from account address and name from the Keybase fromAddress, fromName, err := context.GetFromFields(baseReq.From) if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } @@ -136,86 +52,61 @@ func CompleteAndBroadcastTxREST( txBldr, err = utils.PrepareTxBuilder(txBldr, cliCtx) if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } if baseReq.Simulate || simAndExec { if gasAdj < 0 { - WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) return } txBldr, err = utils.EnrichWithGas(txBldr, cliCtx, msgs) if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } if baseReq.Simulate { - WriteSimulationResponse(w, cdc, txBldr.Gas()) + rest.WriteSimulationResponse(w, cdc, txBldr.Gas()) return } } txBytes, err := txBldr.BuildAndSign(cliCtx.GetFromName(), baseReq.Password, msgs) if keyerror.IsErrKeyNotFound(err) { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } else if keyerror.IsErrWrongPassword(err) { - WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + rest.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) return } else if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } res, err := cliCtx.BroadcastTx(txBytes) if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - PostProcessResponse(w, cdc, res, cliCtx.Indent) -} - -// PostProcessResponse performs post processing for a REST response. -func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response interface{}, indent bool) { - var output []byte - - switch response.(type) { - default: - var err error - if indent { - output, err = cdc.MarshalJSONIndent(response, "", " ") - } else { - output, err = cdc.MarshalJSON(response) - } - if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - case []byte: - output = response.([]byte) - } - - w.Header().Set("Content-Type", "application/json") - w.Write(output) + rest.PostProcessResponse(w, cdc, res, cliCtx.Indent) } // WriteGenerateStdTxResponse writes response for the generate only mode. -func WriteGenerateStdTxResponse( - w http.ResponseWriter, cdc *codec.Codec, cliCtx context.CLIContext, br BaseReq, msgs []sdk.Msg, -) { +func WriteGenerateStdTxResponse(w http.ResponseWriter, cdc *codec.Codec, + cliCtx context.CLIContext, br rest.BaseReq, msgs []sdk.Msg) { - gasAdj, ok := ParseFloat64OrReturnBadRequest(w, br.GasAdjustment, client.DefaultGasAdjustment) + gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, br.GasAdjustment, client.DefaultGasAdjustment) if !ok { return } simAndExec, gas, err := client.ParseGas(br.Gas) if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } @@ -226,26 +117,26 @@ func WriteGenerateStdTxResponse( if simAndExec { if gasAdj < 0 { - WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) return } txBldr, err = utils.EnrichWithGas(txBldr, cliCtx, msgs) if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } } stdMsg, err := txBldr.BuildSignMsg(msgs) if err != nil { - WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } output, err := cdc.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo)) if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } diff --git a/client/rpc/block.go b/client/rpc/block.go index d5aaecc1f..127e9c9c8 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -5,14 +5,14 @@ import ( "net/http" "strconv" - "github.com/cosmos/cosmos-sdk/client/rest" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/context" - "github.com/gorilla/mux" "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/types/rest" + tmliteProxy "github.com/tendermint/tendermint/lite/proxy" ) diff --git a/client/rpc/codec.go b/client/rpc/codec.go index 841366fef..1a64ee4ae 100644 --- a/client/rpc/codec.go +++ b/client/rpc/codec.go @@ -1,7 +1,7 @@ package rpc import ( - amino "github.com/tendermint/go-amino" + "github.com/tendermint/go-amino" ctypes "github.com/tendermint/tendermint/rpc/core/types" ) diff --git a/client/rpc/root.go b/client/rpc/root.go index 6ea831cac..45533e3ea 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -4,11 +4,10 @@ import ( "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/version" ) diff --git a/client/rpc/status.go b/client/rpc/status.go index 438346f16..e017fa860 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -5,15 +5,14 @@ import ( "net/http" "strconv" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/spf13/cobra" - "github.com/spf13/viper" + ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" ) // StatusCommand returns the status of the network diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 091ac97e8..90389bf64 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -7,19 +7,17 @@ import ( "strconv" "strings" - "github.com/cosmos/cosmos-sdk/codec" - - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/gorilla/mux" "github.com/spf13/cobra" - "github.com/spf13/viper" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "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/types/rest" ) // TODO these next two functions feel kinda hacky based on their placement diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index 9dd7b3abd..e75a8cdc4 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -3,7 +3,7 @@ package tx import ( "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" + "github.com/cosmos/cosmos-sdk/types/rest" "io/ioutil" @@ -50,7 +50,8 @@ func BroadcastTxRequest(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle case flagAsync: res, err = cliCtx.BroadcastTxAsync(m.TxBytes) default: - rest.WriteErrorResponse(w, http.StatusInternalServerError, "unsupported return type. supported types: block, sync, async") + rest.WriteErrorResponse(w, http.StatusInternalServerError, + "unsupported return type. supported types: block, sync, async") return } if err != nil { diff --git a/client/tx/query.go b/client/tx/query.go index cbf64f34e..ea54814f2 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -13,9 +13,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "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" ) diff --git a/client/tx/search.go b/client/tx/search.go index 91c3b32c4..718ab5d03 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -8,12 +8,11 @@ import ( "strconv" "strings" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/cosmos/cosmos-sdk/client" "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/types/rest" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -176,7 +175,8 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http. var txs []sdk.TxResponse err := r.ParseForm() if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, sdk.AppendMsgToErr("could not parse query parameters", err.Error())) + rest.WriteErrorResponse(w, http.StatusBadRequest, + sdk.AppendMsgToErr("could not parse query parameters", err.Error())) return } if len(r.Form) == 0 { diff --git a/client/rest/types.go b/types/rest/rest.go similarity index 52% rename from client/rest/types.go rename to types/rest/rest.go index 0595042ba..f40fff747 100644 --- a/client/rest/types.go +++ b/types/rest/rest.go @@ -1,14 +1,16 @@ +// Package rest provides HTTP types and primitives for REST +// requests validation and responses handling. package rest import ( "fmt" "io/ioutil" "net/http" + "strconv" "strings" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" ) // GasEstimateResponse defines a response definition for tx gas estimation. @@ -97,21 +99,8 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { return true } -/* -ReadRESTReq is a simple convenience wrapper that reads the body and -unmarshals to the req interface. Returns false if errors occurred. - - Usage: - type SomeReq struct { - BaseReq `json:"base_req"` - CustomField string `json:"custom_field"` - } - - req := new(SomeReq) - if ok := ReadRESTReq(w, r, cdc, req); !ok { - return - } -*/ +// ReadRESTReq reads and unmarshals a Request's body to the the BaseReq stuct. +// Writes an error response to ResponseWriter and returns true if errors occurred. func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req interface{}) bool { body, err := ioutil.ReadAll(r.Body) if err != nil { @@ -128,60 +117,104 @@ func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req i return true } -// AddrSeed combines an Address with the mnemonic of the private key to that address -type AddrSeed struct { - Address sdk.AccAddress - Seed string - Name string - Password string +// ErrorResponse defines the attributes of a JSON error response. +type ErrorResponse struct { + Code int `json:"code,omitempty"` + Message string `json:"message"` } -// SendReq requests sending an amount of coins -type SendReq struct { - Amount sdk.Coins `json:"amount"` - BaseReq BaseReq `json:"base_req"` +// NewErrorResponse creates a new ErrorResponse instance. +func NewErrorResponse(code int, msg string) ErrorResponse { + return ErrorResponse{Code: code, Message: msg} } -// MsgBeginRedelegateInput request to begin a redelegation -type MsgBeginRedelegateInput struct { - BaseReq BaseReq `json:"base_req"` - DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 - ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // in bech32 - ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"` // in bech32 - SharesAmount sdk.Dec `json:"shares"` +// WriteErrorResponse prepares and writes a HTTP error +// given a status code and an error message. +func WriteErrorResponse(w http.ResponseWriter, status int, err string) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _, _ = w.Write(codec.Cdc.MustMarshalJSON(NewErrorResponse(0, err))) } -// PostProposalReq requests a proposals -type PostProposalReq struct { - BaseReq BaseReq `json:"base_req"` - Title string `json:"title"` // Title of the proposal - Description string `json:"description"` // Description of the proposal - ProposalType string `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal} - Proposer sdk.AccAddress `json:"proposer"` // Address of the proposer - InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit +// WriteSimulationResponse prepares and writes an HTTP +// response for transactions simulations. +func WriteSimulationResponse(w http.ResponseWriter, cdc *codec.Codec, gas uint64) { + gasEst := GasEstimateResponse{GasEstimate: gas} + resp, err := cdc.MarshalJSON(gasEst) + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(resp) } -// BroadcastReq requests broadcasting a transaction -type BroadcastReq struct { - Tx auth.StdTx `json:"tx"` - Return string `json:"return"` +// ParseInt64OrReturnBadRequest converts s to a int64 value. +func ParseInt64OrReturnBadRequest(w http.ResponseWriter, s string) (n int64, ok bool) { + var err error + + n, err = strconv.ParseInt(s, 10, 64) + if err != nil { + err := fmt.Errorf("'%s' is not a valid int64", s) + WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return n, false + } + + return n, true } -// DepositReq requests a deposit of an amount of coins -type DepositReq struct { - BaseReq BaseReq `json:"base_req"` - Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor - Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit +// ParseUint64OrReturnBadRequest converts s to a uint64 value. +func ParseUint64OrReturnBadRequest(w http.ResponseWriter, s string) (n uint64, ok bool) { + var err error + + n, err = strconv.ParseUint(s, 10, 64) + if err != nil { + err := fmt.Errorf("'%s' is not a valid uint64", s) + WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return n, false + } + + return n, true } -// VoteReq requests sending a vote -type VoteReq struct { - BaseReq BaseReq `json:"base_req"` - Voter sdk.AccAddress `json:"voter"` // address of the voter - Option string `json:"option"` // option from OptionSet chosen by the voter +// ParseFloat64OrReturnBadRequest converts s to a float64 value. It returns a +// default value, defaultIfEmpty, if the string is empty. +func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEmpty float64) (n float64, ok bool) { + if len(s) == 0 { + return defaultIfEmpty, true + } + + n, err := strconv.ParseFloat(s, 64) + if err != nil { + WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return n, false + } + + return n, true } -// UnjailReq request unjailing -type UnjailReq struct { - BaseReq BaseReq `json:"base_req"` +// PostProcessResponse performs post processing for a REST response. +func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response interface{}, indent bool) { + var output []byte + + switch response.(type) { + default: + var err error + if indent { + output, err = cdc.MarshalJSONIndent(response, "", " ") + } else { + output, err = cdc.MarshalJSON(response) + } + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + case []byte: + output = response.([]byte) + } + + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write(output) } diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go new file mode 100644 index 000000000..56c2eac82 --- /dev/null +++ b/types/rest/rest_test.go @@ -0,0 +1,66 @@ +// Package rest provides HTTP types and primitives for REST +// requests validation and responses handling. +package rest + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/types" +) + +type mockResponseWriter struct{} + +func TestBaseReq_ValidateBasic(t *testing.T) { + tenstakes, err := types.ParseCoins("10stake") + require.NoError(t, err) + onestake, err := types.ParseDecCoins("1.0stake") + require.NoError(t, err) + + req1 := NewBaseReq( + "nonempty", "nonempty", "", "nonempty", "", "", + 0, 0, tenstakes, nil, false, false, + ) + req2 := NewBaseReq( + "", "nonempty", "", "nonempty", "", "", + 0, 0, tenstakes, nil, false, false, + ) + req3 := NewBaseReq( + "nonempty", "", "", "nonempty", "", "", + 0, 0, tenstakes, nil, false, false, + ) + req4 := NewBaseReq( + "nonempty", "nonempty", "", "", "", "", + 0, 0, tenstakes, nil, false, false, + ) + req5 := NewBaseReq( + "nonempty", "nonempty", "", "nonempty", "", "", + 0, 0, tenstakes, onestake, false, false, + ) + req6 := NewBaseReq( + "nonempty", "nonempty", "", "nonempty", "", "", + 0, 0, types.Coins{}, types.DecCoins{}, false, false, + ) + + tests := []struct { + name string + req BaseReq + w http.ResponseWriter + want bool + }{ + {"ok", req1, httptest.NewRecorder(), true}, + {"neither fees nor gasprices provided", req6, httptest.NewRecorder(), true}, + {"empty from", req2, httptest.NewRecorder(), false}, + {"empty password", req3, httptest.NewRecorder(), false}, + {"empty chain-id", req4, httptest.NewRecorder(), false}, + {"fees and gasprices provided", req5, httptest.NewRecorder(), false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, tt.req.ValidateBasic(tt.w)) + }) + } +} diff --git a/x/auth/client/rest/broadcast.go b/x/auth/client/rest/broadcast.go index 3d923589a..2e0cc9c42 100644 --- a/x/auth/client/rest/broadcast.go +++ b/x/auth/client/rest/broadcast.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/auth" ) diff --git a/x/auth/client/rest/encode.go b/x/auth/client/rest/encode.go index bac646038..97c25f15f 100644 --- a/x/auth/client/rest/encode.go +++ b/x/auth/client/rest/encode.go @@ -5,8 +5,9 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth" ) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 97810cecf..70301aa7f 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -3,13 +3,14 @@ package rest import ( "net/http" + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client/context" - "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/x/auth" + "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/x/auth" ) // register REST routes diff --git a/x/auth/client/rest/requests.go b/x/auth/client/rest/requests.go new file mode 100644 index 000000000..2910c2158 --- /dev/null +++ b/x/auth/client/rest/requests.go @@ -0,0 +1,9 @@ +package rest + +import "github.com/cosmos/cosmos-sdk/x/auth" + +// BroadcastReq requests broadcasting a transaction +type BroadcastReq struct { + Tx auth.StdTx `json:"tx"` + Return string `json:"return"` +} diff --git a/x/auth/client/rest/sign.go b/x/auth/client/rest/sign.go index 67572eefe..deae5ce6b 100644 --- a/x/auth/client/rest/sign.go +++ b/x/auth/client/rest/sign.go @@ -4,11 +4,12 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" ) diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index e602539dc..73d0a42ce 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -3,15 +3,16 @@ package rest import ( "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" + "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" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/x/bank" ) // RegisterRoutes - Central function to define routes that get registered by the main application @@ -19,7 +20,8 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, r.HandleFunc("/bank/accounts/{address}/transfers", SendRequestHandlerFn(cdc, kb, cliCtx)).Methods("POST") } -type sendReq struct { +// SendReq defines the properties of a send request's body. +type SendReq struct { BaseReq rest.BaseReq `json:"base_req"` Amount sdk.Coins `json:"amount"` } @@ -42,7 +44,7 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC return } - var req sendReq + var req SendReq if !rest.ReadRESTReq(w, r, cdc, &req) { return } @@ -62,7 +64,7 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC } msg := bank.NewMsgSend(fromAddr, toAddr, req.Amount) - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } @@ -76,6 +78,6 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) msg := bank.NewMsgSend(cliCtx.GetFromAddress(), toAddr, req.Amount) - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/distribution/client/rest/query.go b/x/distribution/client/rest/query.go index 2c70e34fc..954a097fd 100644 --- a/x/distribution/client/rest/query.go +++ b/x/distribution/client/rest/query.go @@ -4,16 +4,16 @@ import ( "fmt" "net/http" + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/distribution/client/common" "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/gorilla/mux" - "github.com/cosmos/cosmos-sdk/client/context" - "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" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, diff --git a/x/distribution/client/rest/tx.go b/x/distribution/client/rest/tx.go index 8e5bff39f..b5607be80 100644 --- a/x/distribution/client/rest/tx.go +++ b/x/distribution/client/rest/tx.go @@ -3,16 +3,16 @@ package rest import ( "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - "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" "github.com/cosmos/cosmos-sdk/x/distribution/client/common" "github.com/cosmos/cosmos-sdk/x/distribution/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, @@ -82,11 +82,11 @@ func withdrawDelegatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIConte } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, msgs, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, msgs, cdc) } } @@ -122,11 +122,11 @@ func withdrawDelegationRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLICont } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } @@ -157,11 +157,11 @@ func setDelegatorWithdrawalAddrHandlerFn(cdc *codec.Codec, cliCtx context.CLICon } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } @@ -193,11 +193,11 @@ func withdrawValidatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIConte } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, msgs, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, msgs, cdc) } } diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index d53005405..48d1fe782 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -1,21 +1,19 @@ package rest import ( + "errors" "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - - "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/gov" - gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" - - "errors" - "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/gov" + gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" govClientUtils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" ) @@ -54,7 +52,8 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes/{%s}", RestProposalID, RestVoter), queryVoteHandlerFn(cdc, cliCtx)).Methods("GET") } -type postProposalReq struct { +// PostProposalReq defines the properties of a proposal request's body. +type PostProposalReq struct { BaseReq rest.BaseReq `json:"base_req"` Title string `json:"title"` // Title of the proposal Description string `json:"description"` // Description of the proposal @@ -63,13 +62,15 @@ type postProposalReq struct { InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit } -type depositReq struct { +// DepositReq defines the properties of a deposit request's body. +type DepositReq struct { BaseReq rest.BaseReq `json:"base_req"` Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit } -type voteReq struct { +// VoteReq defines the properties of a vote request's body. +type VoteReq struct { BaseReq rest.BaseReq `json:"base_req"` Voter sdk.AccAddress `json:"voter"` // address of the voter Option string `json:"option"` // option from OptionSet chosen by the voter @@ -77,7 +78,7 @@ type voteReq struct { func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req postProposalReq + var req PostProposalReq if !rest.ReadRESTReq(w, r, cdc, &req) { return } @@ -101,11 +102,11 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } @@ -125,7 +126,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF return } - var req depositReq + var req DepositReq if !rest.ReadRESTReq(w, r, cdc, &req) { return } @@ -143,11 +144,11 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } @@ -167,7 +168,7 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc return } - var req voteReq + var req VoteReq if !rest.ReadRESTReq(w, r, cdc, &req) { return } @@ -191,11 +192,11 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index f3ca528dc..e0a228bb5 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -3,12 +3,12 @@ package rest import ( "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/cosmos/cosmos-sdk/client/context" + clientrest "github.com/cosmos/cosmos-sdk/client/rest" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/gorilla/mux" @@ -66,10 +66,10 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. msg := ibc.IBCTransferMsg{IBCPacket: packet} if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index 812e9527f..2f037e5fb 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -4,13 +4,12 @@ import ( "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/gorilla/mux" "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/types/rest" "github.com/cosmos/cosmos-sdk/x/slashing" ) diff --git a/x/slashing/client/rest/rest.go b/x/slashing/client/rest/rest.go index 507fcb517..d06cd719d 100644 --- a/x/slashing/client/rest/rest.go +++ b/x/slashing/client/rest/rest.go @@ -1,11 +1,11 @@ package rest import ( + "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys" - - "github.com/gorilla/mux" ) // RegisterRoutes registers staking-related REST handlers to a router diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 609da021c..8233543f7 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -4,15 +4,15 @@ import ( "bytes" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" + "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" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/slashing" - - "github.com/gorilla/mux" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, kb keys.Keybase) { @@ -57,7 +57,7 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } @@ -75,6 +75,6 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/staking/client/rest/query.go b/x/staking/client/rest/query.go index 88e625194..8a5a5be3c 100644 --- a/x/staking/client/rest/query.go +++ b/x/staking/client/rest/query.go @@ -4,11 +4,10 @@ import ( "net/http" "strings" - "github.com/cosmos/cosmos-sdk/client/rest" - "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/types/rest" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/tags" diff --git a/x/staking/client/rest/tx.go b/x/staking/client/rest/tx.go index 6258d7a7e..b7a417351 100644 --- a/x/staking/client/rest/tx.go +++ b/x/staking/client/rest/tx.go @@ -4,15 +4,15 @@ import ( "bytes" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" + "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" "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/staking" - - "github.com/gorilla/mux" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, kb keys.Keybase) { @@ -31,14 +31,16 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec } type ( - msgDelegationsInput struct { + // MsgBeginRedelegateInput defines the properties of a delegation request's body. + MsgDelegationsInput struct { BaseReq rest.BaseReq `json:"base_req"` DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 Delegation sdk.Coin `json:"delegation"` } - msgBeginRedelegateInput struct { + // MsgBeginRedelegateInput defines the properties of a redelegate request's body. + MsgBeginRedelegateInput struct { BaseReq rest.BaseReq `json:"base_req"` DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // in bech32 @@ -46,7 +48,8 @@ type ( SharesAmount sdk.Dec `json:"shares"` } - msgUndelegateInput struct { + // MsgUndelegateInput defines the properties of a undelegate request's body. + MsgUndelegateInput struct { BaseReq rest.BaseReq `json:"base_req"` DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // in bech32 ValidatorAddr sdk.ValAddress `json:"validator_addr"` // in bech32 @@ -56,7 +59,7 @@ type ( func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req msgDelegationsInput + var req MsgDelegationsInput if !rest.ReadRESTReq(w, r, cdc, &req) { return @@ -74,7 +77,7 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } @@ -92,13 +95,13 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req msgBeginRedelegateInput + var req MsgBeginRedelegateInput if !rest.ReadRESTReq(w, r, cdc, &req) { return @@ -116,7 +119,7 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } @@ -134,13 +137,13 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req msgUndelegateInput + var req MsgUndelegateInput if !rest.ReadRESTReq(w, r, cdc, &req) { return @@ -158,7 +161,7 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx } if req.BaseReq.GenerateOnly { - rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) return } @@ -176,6 +179,6 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx return } - rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) } } diff --git a/x/staking/client/rest/utils.go b/x/staking/client/rest/utils.go index 3efd05d54..dd34dd053 100644 --- a/x/staking/client/rest/utils.go +++ b/x/staking/client/rest/utils.go @@ -4,18 +4,17 @@ import ( "fmt" "net/http" - "github.com/cosmos/cosmos-sdk/client/rest" - "github.com/gorilla/mux" + rpcclient "github.com/tendermint/tendermint/rpc/client" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/tx" "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/staking" "github.com/cosmos/cosmos-sdk/x/staking/tags" - - rpcclient "github.com/tendermint/tendermint/rpc/client" ) // contains checks if the a given query contains one of the tx types