From 5c0d79607e51ca162605b1811ff8b1fd87093127 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 10:53:47 -0500 Subject: [PATCH 01/11] Remove password and gen only from base request type --- types/rest/rest.go | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index f40fff747176..017337c7490b 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -22,7 +22,6 @@ type GasEstimateResponse struct { // that all share common "base" fields. type BaseReq struct { From string `json:"from"` - Password string `json:"password"` Memo string `json:"memo"` ChainID string `json:"chain_id"` AccountNumber uint64 `json:"account_number"` @@ -31,19 +30,17 @@ type BaseReq struct { GasPrices sdk.DecCoins `json:"gas_prices"` Gas string `json:"gas"` GasAdjustment string `json:"gas_adjustment"` - GenerateOnly bool `json:"generate_only"` Simulate bool `json:"simulate"` } // NewBaseReq creates a new basic request instance and sanitizes its values func NewBaseReq( - from, password, memo, chainID string, gas, gasAdjustment string, - accNumber, seq uint64, fees sdk.Coins, gasPrices sdk.DecCoins, genOnly, simulate bool, + from, memo, chainID string, gas, gasAdjustment string, accNumber, seq uint64, + fees sdk.Coins, gasPrices sdk.DecCoins, simulate bool, ) BaseReq { return BaseReq{ From: strings.TrimSpace(from), - Password: password, Memo: strings.TrimSpace(memo), ChainID: strings.TrimSpace(chainID), Fees: fees, @@ -52,7 +49,6 @@ func NewBaseReq( GasAdjustment: strings.TrimSpace(gasAdjustment), AccountNumber: accNumber, Sequence: seq, - GenerateOnly: genOnly, Simulate: simulate, } } @@ -60,8 +56,8 @@ func NewBaseReq( // Sanitize performs basic sanitization on a BaseReq object. func (br BaseReq) Sanitize() BaseReq { return NewBaseReq( - br.From, br.Password, br.Memo, br.ChainID, br.Gas, br.GasAdjustment, - br.AccountNumber, br.Sequence, br.Fees, br.GasPrices, br.GenerateOnly, br.Simulate, + br.From, br.Memo, br.ChainID, br.Gas, br.GasAdjustment, + br.AccountNumber, br.Sequence, br.Fees, br.GasPrices, br.Simulate, ) } @@ -69,12 +65,8 @@ func (br BaseReq) Sanitize() BaseReq { // logic is needed, the implementing request handler should perform those // checks manually. func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { - if !br.GenerateOnly && !br.Simulate { + if !br.Simulate { switch { - case len(br.Password) == 0: - WriteErrorResponse(w, http.StatusUnauthorized, "password required but not specified") - return false - case len(br.ChainID) == 0: WriteErrorResponse(w, http.StatusUnauthorized, "chain-id required but not specified") return false From d23232070cb2b50e57be1272c1878b9f3cb23cfd Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 10:59:35 -0500 Subject: [PATCH 02/11] Fix TestBaseReqValidateBasic --- types/rest/rest_test.go | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 56c2eac82c6c..a5c11f3b63a0 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -14,35 +14,26 @@ import ( type mockResponseWriter struct{} -func TestBaseReq_ValidateBasic(t *testing.T) { +func TestBaseReqValidateBasic(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, + "nonempty", "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) req2 := NewBaseReq( - "", "nonempty", "", "nonempty", "", "", - 0, 0, tenstakes, nil, false, false, + "", "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) req3 := NewBaseReq( - "nonempty", "", "", "nonempty", "", "", - 0, 0, tenstakes, nil, false, false, + "nonempty", "", "", "", "", 0, 0, tenstakes, nil, false, ) req4 := NewBaseReq( - "nonempty", "nonempty", "", "", "", "", - 0, 0, tenstakes, nil, false, false, + "nonempty", "", "nonempty", "", "", 0, 0, tenstakes, onestake, 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, + "nonempty", "", "nonempty", "", "", 0, 0, types.Coins{}, types.DecCoins{}, false, ) tests := []struct { @@ -52,11 +43,10 @@ func TestBaseReq_ValidateBasic(t *testing.T) { want bool }{ {"ok", req1, httptest.NewRecorder(), true}, - {"neither fees nor gasprices provided", req6, httptest.NewRecorder(), true}, + {"neither fees nor gasprices provided", req5, 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}, + {"empty chain-id", req3, httptest.NewRecorder(), false}, + {"fees and gasprices provided", req4, httptest.NewRecorder(), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 78a0c206dbe6d31e100c07f6d9d3a8af1f2e41ff Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 11:28:06 -0500 Subject: [PATCH 03/11] Require all sign txs to generate only --- client/rest/rest.go | 79 -------------------------------- client/utils/utils.go | 4 +- x/bank/client/rest/sendtx.go | 23 ++-------- x/distribution/client/rest/tx.go | 34 ++++---------- x/gov/client/rest/rest.go | 21 ++------- x/ibc/client/rest/transfer.go | 7 +-- x/slashing/client/rest/tx.go | 20 +++----- x/staking/client/rest/tx.go | 42 ++++------------- 8 files changed, 31 insertions(+), 199 deletions(-) diff --git a/client/rest/rest.go b/client/rest/rest.go index d5cc7bab11f8..2556a8e07bb9 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "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" @@ -17,84 +16,6 @@ import ( //----------------------------------------------------------------------------- // Building / Sending utilities -// CompleteAndBroadcastTxREST implements a utility function that facilitates -// sending a series of messages in a signed tx. In addition, it will handle -// tx gas simulation and estimation. -// -// NOTE: Also see CompleteAndBroadcastTxCLI. -func CompleteAndBroadcastTxREST(w http.ResponseWriter, cliCtx context.CLIContext, - baseReq rest.BaseReq, msgs []sdk.Msg, cdc *codec.Codec) { - - gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment) - if !ok { - return - } - - simAndExec, gas, err := client.ParseGas(baseReq.Gas) - if err != nil { - 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 { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - txBldr := authtxb.NewTxBuilder( - utils.GetTxEncoder(cdc), baseReq.AccountNumber, - baseReq.Sequence, gas, gasAdj, baseReq.Simulate, - baseReq.ChainID, baseReq.Memo, baseReq.Fees, baseReq.GasPrices, - ) - - txBldr, err = utils.PrepareTxBuilder(txBldr, cliCtx) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - if baseReq.Simulate || simAndExec { - if gasAdj < 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) - return - } - - txBldr, err = utils.EnrichWithGas(txBldr, cliCtx, msgs) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - if baseReq.Simulate { - rest.WriteSimulationResponse(w, cdc, txBldr.Gas()) - return - } - } - - txBytes, err := txBldr.BuildAndSign(cliCtx.GetFromName(), baseReq.Password, msgs) - if keyerror.IsErrKeyNotFound(err) { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } else if keyerror.IsErrWrongPassword(err) { - rest.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) - return - } else if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - res, err := cliCtx.BroadcastTx(txBytes) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - 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 rest.BaseReq, msgs []sdk.Msg) { diff --git a/client/utils/utils.go b/client/utils/utils.go index 8f4283088885..55ce058ff868 100644 --- a/client/utils/utils.go +++ b/client/utils/utils.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - "github.com/tendermint/go-amino" + amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/libs/common" "github.com/cosmos/cosmos-sdk/client/context" @@ -40,8 +40,6 @@ func GenerateOrBroadcastMsgs(cliCtx context.CLIContext, txBldr authtxb.TxBuilder // QueryContext. It ensures that the account exists, has a proper number and // sequence set. In addition, it builds and signs a transaction with the // supplied messages. Finally, it broadcasts the signed transaction to a node. -// -// NOTE: Also see CompleteAndBroadcastTxREST. func CompleteAndBroadcastTxCLI(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) error { txBldr, err := PrepareTxBuilder(txBldr, cliCtx) if err != nil { diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 73d0a42cee01..552aa2d8ce03 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -54,30 +54,13 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC return } - if req.BaseReq.GenerateOnly { - // When generate only is supplied, the from field must be a valid Bech32 - // address. - fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - msg := bank.NewMsgSend(fromAddr, toAddr, req.Amount) - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(req.BaseReq.From) + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - msg := bank.NewMsgSend(cliCtx.GetFromAddress(), toAddr, req.Amount) - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + msg := bank.NewMsgSend(fromAddr, toAddr, req.Amount) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/distribution/client/rest/tx.go b/x/distribution/client/rest/tx.go index b5607be80ff6..80d442585ddb 100644 --- a/x/distribution/client/rest/tx.go +++ b/x/distribution/client/rest/tx.go @@ -56,8 +56,10 @@ type ( ) // Withdraw delegator rewards -func withdrawDelegatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext, - queryRoute string) http.HandlerFunc { +func withdrawDelegatorRewardsHandlerFn( + cdc *codec.Codec, cliCtx context.CLIContext, queryRoute string, +) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { var req withdrawRewardsReq if !rest.ReadRESTReq(w, r, cdc, &req) { @@ -81,12 +83,7 @@ func withdrawDelegatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIConte return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, msgs, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) } } @@ -121,12 +118,7 @@ func withdrawDelegationRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLICont return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -156,12 +148,7 @@ func setDelegatorWithdrawalAddrHandlerFn(cdc *codec.Codec, cliCtx context.CLICon return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -192,12 +179,7 @@ func withdrawValidatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIConte return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, msgs, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs) } } diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index 48d1fe782bd6..5bfd676a9cca 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -101,12 +101,7 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -143,12 +138,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -191,12 +181,7 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index e0a228bb58c5..6a8eaac0a4b9 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -65,11 +65,6 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. packet := ibc.NewIBCPacket(fromAddr, to, req.Amount, req.BaseReq.ChainID, destChainID) msg := ibc.IBCTransferMsg{IBCPacket: packet} - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 8233543f7552..95b93740b0ac 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -49,32 +49,24 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL return } - msg := slashing.NewMsgUnjail(valAddr) - err = msg.ValidateBasic() + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) + if !bytes.Equal(fromAddr, valAddr) { + rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own validator address") return } - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(req.BaseReq.From) + msg := slashing.NewMsgUnjail(valAddr) + err = msg.ValidateBasic() if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - - if !bytes.Equal(cliCtx.GetFromAddress(), valAddr) { - rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own validator address") - return - } - - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/staking/client/rest/tx.go b/x/staking/client/rest/tx.go index b7a417351838..e707438bf4b1 100644 --- a/x/staking/client/rest/tx.go +++ b/x/staking/client/rest/tx.go @@ -76,26 +76,18 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(req.BaseReq.From) + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - - if !bytes.Equal(cliCtx.GetFromAddress(), req.DelegatorAddr) { + if !bytes.Equal(fromAddr, req.DelegatorAddr) { rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address") return } - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -118,26 +110,18 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(req.BaseReq.From) + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - - if !bytes.Equal(cliCtx.GetFromAddress(), req.DelegatorAddr) { + if !bytes.Equal(fromAddr, req.DelegatorAddr) { rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address") return } - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -160,25 +144,17 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx return } - if req.BaseReq.GenerateOnly { - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) - return - } - - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(req.BaseReq.From) + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - - if !bytes.Equal(cliCtx.GetFromAddress(), req.DelegatorAddr) { + if !bytes.Equal(fromAddr, req.DelegatorAddr) { rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address") return } - clientrest.CompleteAndBroadcastTxREST(w, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc) + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } From b84fc259658d3b142231e5a74e1e0bdc718c6193 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 12:00:15 -0500 Subject: [PATCH 04/11] Remove Keybase routes --- client/keys/add.go | 195 +---------------------------------- client/keys/delete.go | 53 ---------- client/keys/list.go | 36 ------- client/keys/root.go | 12 --- client/keys/show.go | 47 --------- client/keys/update.go | 59 ----------- client/lcd/test_helpers.go | 1 - cmd/gaia/cmd/gaiacli/main.go | 1 - 8 files changed, 1 insertion(+), 403 deletions(-) diff --git a/client/keys/add.go b/client/keys/add.go index a6f374e2a27b..2f697be40182 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -2,10 +2,7 @@ package keys import ( "bytes" - "encoding/json" "fmt" - "io/ioutil" - "net/http" "os" "sort" @@ -13,15 +10,13 @@ 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" - "github.com/gorilla/mux" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/go-bip39" + bip39 "github.com/cosmos/go-bip39" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/multisig" @@ -304,191 +299,3 @@ func printCreate(info keys.Info, showMnemonic bool, mnemonic string) error { return nil } - -///////////////////////////// -// REST - -// function to just create a new seed to display in the UI before actually persisting it in the keybase -func generateMnemonic(algo keys.SigningAlgo) string { - kb := keys.NewInMemory() - pass := app.DefaultKeyPass - name := "inmemorykey" - _, seed, _ := kb.CreateMnemonic(name, keys.English, pass, algo) - return seed -} - -// CheckAndWriteErrorResponse will check for errors and return -// a given error message when corresponding -//TODO: Move to utils/rest or similar -func CheckAndWriteErrorResponse(w http.ResponseWriter, httpErr int, err error) bool { - if err != nil { - w.WriteHeader(httpErr) - _, _ = w.Write([]byte(err.Error())) - return true - } - return false -} - -// add new key REST handler -func AddNewKeyRequestHandler(indent bool) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var kb keys.Keybase - var m AddNewKey - - kb, err := NewKeyBaseFromHomeFlag() - if CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) { - return - } - - body, err := ioutil.ReadAll(r.Body) - if CheckAndWriteErrorResponse(w, http.StatusBadRequest, err) { - return - } - - err = json.Unmarshal(body, &m) - if CheckAndWriteErrorResponse(w, http.StatusBadRequest, err) { - return - } - - // Check parameters - if m.Name == "" { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errMissingName()) - return - } - if m.Password == "" { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errMissingPassword()) - return - } - - mnemonic := m.Mnemonic - // if mnemonic is empty, generate one - if mnemonic == "" { - mnemonic = generateMnemonic(keys.Secp256k1) - } - if !bip39.IsMnemonicValid(mnemonic) { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidMnemonic()) - } - - if m.Account < 0 || m.Account > maxValidAccountValue { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidAccountNumber()) - return - } - - if m.Index < 0 || m.Index > maxValidIndexalue { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidIndexNumber()) - return - } - - _, err = kb.Get(m.Name) - if err == nil { - CheckAndWriteErrorResponse(w, http.StatusConflict, errKeyNameConflict(m.Name)) - return - } - - // create account - account := uint32(m.Account) - index := uint32(m.Index) - info, err := kb.CreateAccount(m.Name, mnemonic, keys.DefaultBIP39Passphrase, m.Password, account, index) - if CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) { - return - } - - keyOutput, err := Bech32KeyOutput(info) - if CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) { - return - } - - keyOutput.Mnemonic = mnemonic - - rest.PostProcessResponse(w, cdc, keyOutput, indent) - } -} - -// Seed REST request handler -func SeedRequestHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - algoType := vars["type"] - - // algo type defaults to secp256k1 - if algoType == "" { - algoType = "secp256k1" - } - - algo := keys.SigningAlgo(algoType) - seed := generateMnemonic(algo) - - w.Header().Set("Content-Type", "application/json") - _, _ = w.Write([]byte(seed)) -} - -// RecoverRequestHandler performs key recover request -func RecoverRequestHandler(indent bool) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - var m RecoverKey - - body, err := ioutil.ReadAll(r.Body) - if CheckAndWriteErrorResponse(w, http.StatusBadRequest, err) { - return - } - - err = cdc.UnmarshalJSON(body, &m) - if CheckAndWriteErrorResponse(w, http.StatusBadRequest, err) { - return - } - - kb, err := NewKeyBaseFromHomeFlag() - CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) - - if name == "" { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errMissingName()) - return - } - if m.Password == "" { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errMissingPassword()) - return - } - - mnemonic := m.Mnemonic - if !bip39.IsMnemonicValid(mnemonic) { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidMnemonic()) - } - - if m.Mnemonic == "" { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errMissingMnemonic()) - return - } - - if m.Account < 0 || m.Account > maxValidAccountValue { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidAccountNumber()) - return - } - - if m.Index < 0 || m.Index > maxValidIndexalue { - CheckAndWriteErrorResponse(w, http.StatusBadRequest, errInvalidIndexNumber()) - return - } - - _, err = kb.Get(name) - if err == nil { - CheckAndWriteErrorResponse(w, http.StatusConflict, errKeyNameConflict(name)) - return - } - - account := uint32(m.Account) - index := uint32(m.Index) - - info, err := kb.CreateAccount(name, mnemonic, keys.DefaultBIP39Passphrase, m.Password, account, index) - if CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) { - return - } - - keyOutput, err := Bech32KeyOutput(info) - if CheckAndWriteErrorResponse(w, http.StatusInternalServerError, err) { - return - } - - rest.PostProcessResponse(w, cdc, keyOutput, indent) - } -} diff --git a/client/keys/delete.go b/client/keys/delete.go index 614bcce7c98d..3803a3a18869 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -2,19 +2,14 @@ package keys import ( "bufio" - "encoding/json" "errors" "fmt" - "net/http" "os" "github.com/spf13/viper" - "github.com/gorilla/mux" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/spf13/cobra" ) @@ -101,51 +96,3 @@ func confirmDeletion(buf *bufio.Reader) error { } return nil } - -//////////////////////// -// REST - -// delete key request REST body -type DeleteKeyBody struct { - Password string `json:"password"` -} - -// delete key REST handler -func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - var kb keys.Keybase - var m DeleteKeyBody - - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(&m) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(err.Error())) - return - } - - kb, err = NewKeyBaseFromHomeFlag() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - err = kb.Delete(name, m.Password, false) - if keyerror.IsErrKeyNotFound(err) { - w.WriteHeader(http.StatusNotFound) - _, _ = w.Write([]byte(err.Error())) - return - } else if keyerror.IsErrWrongPassword(err) { - w.WriteHeader(http.StatusUnauthorized) - _, _ = w.Write([]byte(err.Error())) - return - } else if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - w.WriteHeader(http.StatusOK) -} diff --git a/client/keys/list.go b/client/keys/list.go index 4dda3a86b8c4..db4cf0fe2f71 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -1,9 +1,6 @@ package keys import ( - "net/http" - - "github.com/cosmos/cosmos-sdk/types/rest" "github.com/spf13/cobra" ) @@ -29,36 +26,3 @@ func runListCmd(cmd *cobra.Command, args []string) error { } return err } - -///////////////////////// -// REST - -// query key list REST handler -func QueryKeysRequestHandler(indent bool) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - kb, err := NewKeyBaseFromHomeFlag() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - infos, err := kb.List() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - // an empty list will be JSONized as null, but we want to keep the empty list - if len(infos) == 0 { - rest.PostProcessResponse(w, cdc, []string{}, indent) - return - } - keysOutput, err := Bech32KeysOutput(infos) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - rest.PostProcessResponse(w, cdc, keysOutput, indent) - } -} diff --git a/client/keys/root.go b/client/keys/root.go index 5b70025fd008..e49b57d4affd 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -1,7 +1,6 @@ package keys import ( - "github.com/gorilla/mux" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" @@ -30,14 +29,3 @@ func Commands() *cobra.Command { ) return cmd } - -// resgister REST routes -func RegisterRoutes(r *mux.Router, indent bool) { - r.HandleFunc("/keys", QueryKeysRequestHandler(indent)).Methods("GET") - r.HandleFunc("/keys", AddNewKeyRequestHandler(indent)).Methods("POST") - r.HandleFunc("/keys/seed", SeedRequestHandler).Methods("GET") - r.HandleFunc("/keys/{name}/recover", RecoverRequestHandler(indent)).Methods("POST") - r.HandleFunc("/keys/{name}", GetKeyRequestHandler(indent)).Methods("GET") - r.HandleFunc("/keys/{name}", UpdateKeyRequestHandler).Methods("PUT") - r.HandleFunc("/keys/{name}", DeleteKeyRequestHandler).Methods("DELETE") -} diff --git a/client/keys/show.go b/client/keys/show.go index 903dfeb192b0..cb8a5dce9a69 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -2,22 +2,18 @@ package keys import ( "fmt" - "net/http" "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/types/rest" "errors" - "github.com/gorilla/mux" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tendermint/tendermint/crypto/multisig" "github.com/tendermint/tendermint/libs/cli" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -149,46 +145,3 @@ func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) { return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix) } - -/////////////////////////// -// REST - -// get key REST handler -func GetKeyRequestHandler(indent bool) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - bechPrefix := r.URL.Query().Get(FlagBechPrefix) - - if bechPrefix == "" { - bechPrefix = "acc" - } - - bechKeyOut, err := getBechKeyOut(bechPrefix) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(err.Error())) - return - } - - info, err := GetKeyInfo(name) - if keyerror.IsErrKeyNotFound(err) { - w.WriteHeader(http.StatusNotFound) - _, _ = w.Write([]byte(err.Error())) - return - } else if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - keyOutput, err := bechKeyOut(info) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - rest.PostProcessResponse(w, cdc, keyOutput, indent) - } -} diff --git a/client/keys/update.go b/client/keys/update.go index d3a03f22c7c3..392286d4801f 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -1,18 +1,11 @@ package keys import ( - "encoding/json" "fmt" - "net/http" - - "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) func updateKeyCommand() *cobra.Command { @@ -52,55 +45,3 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error { fmt.Println("Password successfully updated!") return nil } - -/////////////////////// -// REST - -// update key request REST body -type UpdateKeyBody struct { - NewPassword string `json:"new_password"` - OldPassword string `json:"old_password"` -} - -// update key REST handler -func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - var kb keys.Keybase - var m UpdateKeyBody - - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(&m) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(err.Error())) - return - } - - kb, err = NewKeyBaseFromHomeFlag() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - getNewpass := func() (string, error) { return m.NewPassword, nil } - - err = kb.Update(name, m.OldPassword, getNewpass) - if keyerror.IsErrKeyNotFound(err) { - w.WriteHeader(http.StatusNotFound) - _, _ = w.Write([]byte(err.Error())) - return - } else if keyerror.IsErrWrongPassword(err) { - w.WriteHeader(http.StatusUnauthorized) - _, _ = w.Write([]byte(err.Error())) - return - } else if err != nil { - w.WriteHeader(http.StatusInternalServerError) - _, _ = w.Write([]byte(err.Error())) - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) -} diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index cbb97ebaecae..317218dd118b 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -397,7 +397,6 @@ func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec, t *testing // NOTE: If making updates here also update cmd/gaia/cmd/gaiacli/main.go func registerRoutes(rs *RestServer) { - keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) rpc.RegisterRoutes(rs.CliCtx, rs.Mux) tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) authrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, auth.StoreKey) diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index a5939116ffd6..f49a0e3ac7d7 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -158,7 +158,6 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { // NOTE: If making updates here you also need to update the test helper in client/lcd/test_helper.go func registerRoutes(rs *lcd.RestServer) { registerSwaggerUI(rs) - keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) rpc.RegisterRoutes(rs.CliCtx, rs.Mux) tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, at.StoreKey) From 1b18df80765bb0406aed144ec77b9898daf81938 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 12:00:24 -0500 Subject: [PATCH 05/11] Remove tx sign route --- x/auth/client/rest/query.go | 4 -- x/auth/client/rest/sign.go | 81 ------------------------------------- 2 files changed, 85 deletions(-) delete mode 100644 x/auth/client/rest/sign.go diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 70301aa7fb61..9e57bf9fd18c 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -31,10 +31,6 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, "/tx/encode", EncodeTxRequestHandlerFn(cdc, cliCtx), ).Methods("POST") - r.HandleFunc( - "/tx/sign", - SignTxRequestHandlerFn(cdc, cliCtx), - ).Methods("POST") } // query accountREST Handler diff --git a/x/auth/client/rest/sign.go b/x/auth/client/rest/sign.go deleted file mode 100644 index deae5ce6bd82..000000000000 --- a/x/auth/client/rest/sign.go +++ /dev/null @@ -1,81 +0,0 @@ -package rest - -import ( - "net/http" - - "github.com/cosmos/cosmos-sdk/client/context" - "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" -) - -// SignBody defines the properties of a sign request's body. -type SignBody struct { - Tx auth.StdTx `json:"tx"` - AppendSig bool `json:"append_sig"` - BaseReq rest.BaseReq `json:"base_req"` -} - -// nolint: unparam -// sign tx REST handler -func SignTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var m SignBody - - if !rest.ReadRESTReq(w, r, cdc, &m) { - return - } - - if !m.BaseReq.ValidateBasic(w) { - return - } - - // validate tx - // discard error if it's CodeNoSignatures as the tx comes with no signatures - if err := m.Tx.ValidateBasic(); err != nil && err.Code() != sdk.CodeNoSignatures { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - // derive the from account address and name from the Keybase - fromAddress, fromName, err := context.GetFromFields(m.BaseReq.From) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - cliCtx = cliCtx.WithFromName(fromName).WithFromAddress(fromAddress) - - txBldr := authtxb.NewTxBuilder( - utils.GetTxEncoder(cdc), - m.BaseReq.AccountNumber, - m.BaseReq.Sequence, - m.Tx.Fee.Gas, - 1.0, - false, - m.BaseReq.ChainID, - m.Tx.GetMemo(), - m.Tx.Fee.Amount, - nil, - ) - - signedTx, err := txBldr.SignStdTx(cliCtx.GetFromName(), m.BaseReq.Password, m.Tx, m.AppendSig) - if keyerror.IsErrKeyNotFound(err) { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } else if keyerror.IsErrWrongPassword(err) { - rest.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) - return - } else if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - rest.PostProcessResponse(w, cdc, signedTx, cliCtx.Indent) - } -} From e03285d06fa7f925f677e68e3cc2be190b53ae68 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 19:51:43 -0500 Subject: [PATCH 06/11] squash commits --- client/rest/rest.go | 7 ++++++- types/rest/rest.go | 4 ++-- types/rest/rest_test.go | 9 +++++---- x/auth/client/rest/requests.go | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/rest/rest.go b/client/rest/rest.go index 2556a8e07bb9..81d2cc57b933 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -36,7 +36,7 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cdc *codec.Codec, br.Simulate, br.ChainID, br.Memo, br.Fees, br.GasPrices, ) - if simAndExec { + if br.Simulate || simAndExec { if gasAdj < 0 { rest.WriteErrorResponse(w, http.StatusBadRequest, client.ErrInvalidGasAdjustment.Error()) return @@ -47,6 +47,11 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cdc *codec.Codec, rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } + + if br.Simulate { + rest.WriteSimulationResponse(w, cdc, txBldr.Gas()) + return + } } stdMsg, err := txBldr.BuildSignMsg(msgs) diff --git a/types/rest/rest.go b/types/rest/rest.go index 017337c7490b..b19c8fddb676 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -83,8 +83,8 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { } } - if len(br.From) == 0 { - WriteErrorResponse(w, http.StatusUnauthorized, "name or address required but not specified") + if _, err := sdk.AccAddressFromBech32(br.From); err != nil || len(br.From) == 0 { + WriteErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("invalid from address: %s", br.From)) return false } diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index a5c11f3b63a0..876cffe683ee 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -15,25 +15,26 @@ import ( type mockResponseWriter struct{} func TestBaseReqValidateBasic(t *testing.T) { + fromAddr := "cosmos1cq0sxam6x4l0sv9yz3a2vlqhdhvt2k6jtgcse0" tenstakes, err := types.ParseCoins("10stake") require.NoError(t, err) onestake, err := types.ParseDecCoins("1.0stake") require.NoError(t, err) req1 := NewBaseReq( - "nonempty", "", "nonempty", "", "", 0, 0, tenstakes, nil, false, + fromAddr, "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) req2 := NewBaseReq( "", "", "nonempty", "", "", 0, 0, tenstakes, nil, false, ) req3 := NewBaseReq( - "nonempty", "", "", "", "", 0, 0, tenstakes, nil, false, + fromAddr, "", "", "", "", 0, 0, tenstakes, nil, false, ) req4 := NewBaseReq( - "nonempty", "", "nonempty", "", "", 0, 0, tenstakes, onestake, false, + fromAddr, "", "nonempty", "", "", 0, 0, tenstakes, onestake, false, ) req5 := NewBaseReq( - "nonempty", "", "nonempty", "", "", 0, 0, types.Coins{}, types.DecCoins{}, false, + fromAddr, "", "nonempty", "", "", 0, 0, types.Coins{}, types.DecCoins{}, false, ) tests := []struct { diff --git a/x/auth/client/rest/requests.go b/x/auth/client/rest/requests.go index 2910c2158478..5fa6a8ec6a25 100644 --- a/x/auth/client/rest/requests.go +++ b/x/auth/client/rest/requests.go @@ -5,5 +5,5 @@ 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"` + Return string `json:"return"` // TODO: Do we need this? } From e7719e4d8b3652a0006f6383c830b610b71573e8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 22:40:51 -0500 Subject: [PATCH 07/11] update REST client integration tests --- client/lcd/lcd_test.go | 205 ++++------------------ client/lcd/test_helpers.go | 341 +++++++++++++++++++++++-------------- 2 files changed, 245 insertions(+), 301 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index c0fd09c64c1d..77dd2f879443 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -11,7 +11,6 @@ import ( "testing" "time" - "github.com/spf13/viper" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" @@ -23,7 +22,6 @@ import ( "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" "github.com/cosmos/cosmos-sdk/x/bank" dclcommon "github.com/cosmos/cosmos-sdk/x/distribution/client/common" distrrest "github.com/cosmos/cosmos-sdk/x/distribution/client/rest" @@ -48,119 +46,6 @@ func init() { version.Version = os.Getenv("VERSION") } -func TestSeedsAreDifferent(t *testing.T) { - kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) - require.NoError(t, err) - addr, _ := CreateAddr(t, name1, pw, kb) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true) - defer cleanup() - - mnemonic1 := getKeysSeed(t, port) - mnemonic2 := getKeysSeed(t, port) - - require.NotEqual(t, mnemonic1, mnemonic2) -} - -func TestKeyRecover(t *testing.T) { - kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) - require.NoError(t, err) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true) - defer cleanup() - - myName1 := "TestKeyRecover_1" - myName2 := "TestKeyRecover_2" - - mnemonic := getKeysSeed(t, port) - expectedInfo, _ := kb.CreateAccount(myName1, mnemonic, "", pw, 0, 0) - expectedAddress := expectedInfo.GetAddress().String() - expectedPubKey := sdk.MustBech32ifyAccPub(expectedInfo.GetPubKey()) - - // recover key - doRecoverKey(t, port, myName2, pw, mnemonic, 0, 0) - - keys := getKeys(t, port) - - require.Equal(t, expectedAddress, keys[0].Address) - require.Equal(t, expectedPubKey, keys[0].PubKey) -} - -func TestKeyRecoverHDPath(t *testing.T) { - kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) - require.NoError(t, err) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true) - defer cleanup() - - mnemonic := getKeysSeed(t, port) - - for account := uint32(0); account < 50; account += 13 { - for index := uint32(0); index < 50; index += 15 { - name1Idx := fmt.Sprintf("name1_%d_%d", account, index) - name2Idx := fmt.Sprintf("name2_%d_%d", account, index) - - expectedInfo, _ := kb.CreateAccount(name1Idx, mnemonic, "", pw, account, index) - expectedAddress := expectedInfo.GetAddress().String() - expectedPubKey := sdk.MustBech32ifyAccPub(expectedInfo.GetPubKey()) - - // recover key - doRecoverKey(t, port, name2Idx, pw, mnemonic, account, index) - - keysName2Idx := getKey(t, port, name2Idx) - - require.Equal(t, expectedAddress, keysName2Idx.Address) - require.Equal(t, expectedPubKey, keysName2Idx.PubKey) - } - } -} - -func TestKeys(t *testing.T) { - kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) - require.NoError(t, err) - addr1, _ := CreateAddr(t, name1, pw, kb) - addr1Bech32 := addr1.String() - - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr1}, true) - defer cleanup() - - // get new seed & recover key - mnemonic2 := getKeysSeed(t, port) - doRecoverKey(t, port, name2, pw, mnemonic2, 0, 0) - - // add key - mnemonic3 := mnemonic2 - resp := doKeysPost(t, port, name3, pw, mnemonic3, 0, 0) - - addr3Bech32 := resp.Address - _, err = sdk.AccAddressFromBech32(addr3Bech32) - require.NoError(t, err, "Failed to return a correct bech32 address") - - // test if created account is the correct account - expectedInfo3, _ := kb.CreateAccount(name3, mnemonic3, "", pw, 0, 0) - expectedAddress3 := sdk.AccAddress(expectedInfo3.GetPubKey().Address()).String() - require.Equal(t, expectedAddress3, addr3Bech32) - - // existing keys - require.Equal(t, name1, getKey(t, port, name1).Name, "Did not serve keys name correctly") - require.Equal(t, addr1Bech32, getKey(t, port, name1).Address, "Did not serve keys Address correctly") - require.Equal(t, name2, getKey(t, port, name2).Name, "Did not serve keys name correctly") - require.Equal(t, addr3Bech32, getKey(t, port, name2).Address, "Did not serve keys Address correctly") - require.Equal(t, name3, getKey(t, port, name3).Name, "Did not serve keys name correctly") - require.Equal(t, addr3Bech32, getKey(t, port, name3).Address, "Did not serve keys Address correctly") - - // select key - key := getKey(t, port, name3) - require.Equal(t, name3, key.Name, "Did not serve keys name correctly") - require.Equal(t, addr3Bech32, key.Address, "Did not serve keys Address correctly") - - // update key - updateKey(t, port, name3, pw, altPw, false) - - // here it should say unauthorized as we changed the password before - updateKey(t, port, name3, pw, altPw, true) - - // delete key - deleteKey(t, port, name3, altPw) -} - func TestVersion(t *testing.T) { // skip the test if the VERSION environment variable has not been set if version.Version == "" { @@ -255,7 +140,7 @@ func TestCoinSend(t *testing.T) { require.Equal(t, int64(1), coins2[0].Amount.Int64()) // test failure with too little gas - res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "100", 0, false, false, fees) + res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "100", 0, false, true, fees) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) require.Nil(t, err) @@ -268,11 +153,11 @@ func TestCoinSend(t *testing.T) { require.Equal(t, http.StatusBadRequest, res.StatusCode, body) // test failure with 0 gas - res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "0", 0, false, false, fees) + res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "0", 0, false, true, fees) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) // test failure with wrong adjustment - res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, client.GasFlagAuto, 0.1, false, false, fees) + res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, client.GasFlagAuto, 0.1, false, true, fees) require.Equal(t, http.StatusInternalServerError, res.StatusCode, body) @@ -291,7 +176,7 @@ func TestCoinSend(t *testing.T) { // run successful tx gas := fmt.Sprintf("%d", gasEstResp.GasEstimate) - res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, gas, 1.0, false, false, fees) + res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, gas, 1.0, false, true, fees) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &resultTx) @@ -316,7 +201,9 @@ func TestCoinSendAccAuto(t *testing.T) { initialBalance := acc.GetCoins() // send a transfer tx without specifying account number and sequence - res, body, _ := doTransferWithGasAccAuto(t, port, seed, name1, memo, pw, "200000", 1.0, false, false, fees) + res, body, _ := doTransferWithGasAccAuto( + t, port, seed, name1, memo, pw, addr, "200000", 1.0, false, true, fees, + ) require.Equal(t, http.StatusOK, res.StatusCode, body) // query sender @@ -336,7 +223,7 @@ func TestCoinMultiSendGenerateOnly(t *testing.T) { defer cleanup() // generate only - res, body, _ := doTransferWithGas(t, port, seed, "", memo, "", addr, "200000", 1, false, true, fees) + res, body, _ := doTransferWithGas(t, port, seed, "", memo, "", addr, "200000", 1, false, false, fees) require.Equal(t, http.StatusOK, res.StatusCode, body) var stdTx auth.StdTx @@ -356,6 +243,7 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) { require.NoError(t, err) addr, seed := CreateAddr(t, name1, pw, kb) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true) + defer cleanup() acc := getAccount(t, port, addr) @@ -371,74 +259,40 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) { // generate tx gas := fmt.Sprintf("%d", gasEstResp.GasEstimate) - res, body, _ = doTransferWithGas(t, port, seed, name1, memo, "", addr, gas, 1, false, true, fees) + res, body, _ = doTransferWithGas(t, port, seed, name1, memo, "", addr, gas, 1, false, false, fees) require.Equal(t, http.StatusOK, res.StatusCode, body) - var msg auth.StdTx - require.Nil(t, cdc.UnmarshalJSON([]byte(body), &msg)) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, msg.Msgs[0].Route(), "bank") - require.Equal(t, msg.Msgs[0].GetSigners(), []sdk.AccAddress{addr}) - require.Equal(t, 0, len(msg.Signatures)) - require.Equal(t, memo, msg.Memo) - require.NotZero(t, msg.Fee.Gas) - - gasEstimate := int64(msg.Fee.Gas) - accnum := acc.GetAccountNumber() - sequence := acc.GetSequence() - - // sign tx - var signedMsg auth.StdTx - - payload := authrest.SignBody{ - Tx: msg, - BaseReq: rest.NewBaseReq( - name1, pw, "", viper.GetString(client.FlagChainID), "", "", - accnum, sequence, nil, nil, false, false, - ), - } - json, err := cdc.MarshalJSON(payload) - require.Nil(t, err) + var tx auth.StdTx + require.Nil(t, cdc.UnmarshalJSON([]byte(body), &tx)) + require.Equal(t, len(tx.Msgs), 1) + require.Equal(t, tx.Msgs[0].Route(), "bank") + require.Equal(t, tx.Msgs[0].GetSigners(), []sdk.AccAddress{addr}) + require.Equal(t, 0, len(tx.Signatures)) + require.Equal(t, memo, tx.Memo) + require.NotZero(t, tx.Fee.Gas) - res, body = Request(t, port, "POST", "/tx/sign", json) - require.Equal(t, http.StatusOK, res.StatusCode, body) - require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg)) - require.Equal(t, len(msg.Msgs), len(signedMsg.Msgs)) - require.Equal(t, msg.Msgs[0].Type(), signedMsg.Msgs[0].Type()) - require.Equal(t, msg.Msgs[0].GetSigners(), signedMsg.Msgs[0].GetSigners()) - require.Equal(t, 1, len(signedMsg.Signatures)) - - // broadcast tx - broadcastPayload := struct { - Tx auth.StdTx `json:"tx"` - Return string `json:"return"` - }{Tx: signedMsg, Return: "block"} - json, err = cdc.MarshalJSON(broadcastPayload) - require.Nil(t, err) - res, body = Request(t, port, "POST", "/tx/broadcast", json) - require.Equal(t, http.StatusOK, res.StatusCode, body) + gasEstimate := int64(tx.Fee.Gas) + _, body = signAndBroadcastGenTx(t, port, name1, pw, body, acc, 1.0, false) // check if tx was committed - var resultTx sdk.TxResponse - require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx)) - require.Equal(t, uint32(0), resultTx.Code) - require.Equal(t, gasEstimate, resultTx.GasWanted) + var txResp sdk.TxResponse + require.Nil(t, cdc.UnmarshalJSON([]byte(body), &txResp)) + require.Equal(t, uint32(0), txResp.Code) + require.Equal(t, gasEstimate, txResp.GasWanted) } func TestEncodeTx(t *testing.T) { - // Setup kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) require.NoError(t, err) addr, seed := CreateAddr(t, name1, pw, kb) cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true) defer cleanup() - // Make a transaction to test with - res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "2", 1, false, true, fees) + res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "2", 1, false, false, fees) var tx auth.StdTx cdc.UnmarshalJSON([]byte(body), &tx) - // Build the request + // build the request encodeReq := struct { Tx auth.StdTx `json:"tx"` }{Tx: tx} @@ -446,20 +300,19 @@ func TestEncodeTx(t *testing.T) { res, body = Request(t, port, "POST", "/tx/encode", encodedJSON) // Make sure it came back ok, and that we can decode it back to the transaction - // 200 response + // 200 response. require.Equal(t, http.StatusOK, res.StatusCode, body) encodeResp := struct { Tx string `json:"tx"` }{} - // No error decoding the JSON require.Nil(t, cdc.UnmarshalJSON([]byte(body), &encodeResp)) - // Check that the base64 decodes + // verify that the base64 decodes decodedBytes, err := base64.StdEncoding.DecodeString(encodeResp.Tx) require.Nil(t, err) - // Check that the transaction decodes as expected + // check that the transaction decodes as expected var decodedTx auth.StdTx require.Nil(t, cdc.UnmarshalBinaryLengthPrefixed(decodedBytes, &decodedTx)) require.Equal(t, memo, decodedTx.Memo) diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 317218dd118b..0f26a18517b8 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -20,6 +20,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" @@ -646,52 +647,42 @@ func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account { // ICS 20 - Tokens // ---------------------------------------------------------------------- -// POST /tx/sign Sign a Tx -func doSign(t *testing.T, port, name, password, chainID string, accnum, sequence uint64, msg auth.StdTx) auth.StdTx { - var signedMsg auth.StdTx - payload := authrest.SignBody{ - Tx: msg, - BaseReq: rest.NewBaseReq( - name, password, "", chainID, "", "", accnum, sequence, nil, nil, false, false, - ), - } - json, err := cdc.MarshalJSON(payload) - require.Nil(t, err) - res, body := Request(t, port, "POST", "/tx/sign", json) - require.Equal(t, http.StatusOK, res.StatusCode, body) - require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg)) - return signedMsg -} - // POST /tx/broadcast Send a signed Tx -func doBroadcast(t *testing.T, port string, msg auth.StdTx) sdk.TxResponse { - tx := authrest.BroadcastReq{Tx: msg, Return: "block"} - req, err := cdc.MarshalJSON(tx) +func doBroadcast(t *testing.T, port string, tx auth.StdTx) (*http.Response, string) { + txReq := authrest.BroadcastReq{Tx: tx, Return: "block"} + + req, err := cdc.MarshalJSON(txReq) require.Nil(t, err) - res, body := Request(t, port, "POST", "/tx/broadcast", req) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var resultTx sdk.TxResponse - require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx)) - return resultTx + + return Request(t, port, "POST", "/tx/broadcast", req) } -// GET /bank/balances/{address} Get the account balances +// doTransfer performs a balance transfer with auto gas calculation. It also signs +// the tx and broadcasts it. +func doTransfer( + t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress, fees sdk.Coins, +) (sdk.AccAddress, sdk.TxResponse) { -// POST /bank/accounts/{address}/transfers Send coins (build -> sign -> send) -func doTransfer(t *testing.T, port, seed, name, memo, password string, addr sdk.AccAddress, fees sdk.Coins) (receiveAddr sdk.AccAddress, resultTx sdk.TxResponse) { - res, body, receiveAddr := doTransferWithGas(t, port, seed, name, memo, password, addr, "", 1.0, false, false, fees) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body, recvAddr := doTransferWithGas( + t, port, seed, name, memo, pwd, addr, "", 1.0, false, true, fees, + ) + require.Equal(t, http.StatusOK, resp.StatusCode, resp) - err := cdc.UnmarshalJSON([]byte(body), &resultTx) - require.Nil(t, err) + var txResp sdk.TxResponse + err := cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return receiveAddr, resultTx + return recvAddr, txResp } +// doTransferWithGas performs a balance transfer with a specified gas value. The +// broadcast parameter determines if the tx should only be generated or also +// signed and broadcasted. The sending account's number and sequence are +// determined prior to generating the tx. func doTransferWithGas( - t *testing.T, port, seed, from, memo, password string, addr sdk.AccAddress, - gas string, gasAdjustment float64, simulate, generateOnly bool, fees sdk.Coins, -) (res *http.Response, body string, receiveAddr sdk.AccAddress) { + t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress, + gas string, gasAdjustment float64, simulate, broadcast bool, fees sdk.Coins, +) (resp *http.Response, body string, receiveAddr sdk.AccAddress) { // create receive address kb := crkeys.NewInMemory() @@ -707,15 +698,9 @@ func doTransferWithGas( sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - if generateOnly { - // generate only txs do not use a Keybase so the address must be used - from = addr.String() - } - + from := addr.String() baseReq := rest.NewBaseReq( - from, password, memo, chainID, gas, - fmt.Sprintf("%f", gasAdjustment), accnum, sequence, fees, nil, - generateOnly, simulate, + from, memo, chainID, gas, fmt.Sprintf("%f", gasAdjustment), accnum, sequence, fees, nil, simulate, ) sr := bankrest.SendReq{ @@ -726,17 +711,28 @@ func doTransferWithGas( req, err := cdc.MarshalJSON(sr) require.NoError(t, err) - res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req) - return + // generate tx + resp, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req) + if !broadcast { + return resp, body, receiveAddr + } + + // sign and broadcast + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, gasAdjustment, simulate) + return resp, body, receiveAddr } +// doTransferWithGasAccAuto is similar to doTransferWithGas except that it +// automatically determines the account's number and sequence when generating the +// tx. func doTransferWithGasAccAuto( - t *testing.T, port, seed, from, memo, password string, gas string, - gasAdjustment float64, simulate, generateOnly bool, fees sdk.Coins, -) (res *http.Response, body string, receiveAddr sdk.AccAddress) { + t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress, + gas string, gasAdjustment float64, simulate, broadcast bool, fees sdk.Coins, +) (resp *http.Response, body string, receiveAddr sdk.AccAddress) { // create receive address kb := crkeys.NewInMemory() + acc := getAccount(t, port, addr) receiveInfo, _, err := kb.CreateMnemonic( "receive_address", crkeys.English, gapp.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"), @@ -746,9 +742,9 @@ func doTransferWithGasAccAuto( receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address()) chainID := viper.GetString(client.FlagChainID) + from := addr.String() baseReq := rest.NewBaseReq( - from, password, memo, chainID, gas, - fmt.Sprintf("%f", gasAdjustment), 0, 0, fees, nil, generateOnly, simulate, + from, memo, chainID, gas, fmt.Sprintf("%f", gasAdjustment), 0, 0, fees, nil, simulate, ) sr := bankrest.SendReq{ @@ -759,8 +755,45 @@ func doTransferWithGasAccAuto( req, err := cdc.MarshalJSON(sr) require.NoError(t, err) - res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req) - return + resp, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req) + if !broadcast { + return resp, body, receiveAddr + } + + // sign and broadcast + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, gasAdjustment, simulate) + return resp, body, receiveAddr +} + +// signAndBroadcastGenTx accepts a successfully generated unsigned tx, signs it, +// and broadcasts it. +func signAndBroadcastGenTx( + t *testing.T, port, name, pwd, genTx string, acc auth.Account, gasAdjustment float64, simulate bool, +) (resp *http.Response, body string) { + + chainID := viper.GetString(client.FlagChainID) + + var tx auth.StdTx + err := cdc.UnmarshalJSON([]byte(genTx), &tx) + require.Nil(t, err) + + txbldr := txbuilder.NewTxBuilder( + utils.GetTxEncoder(cdc), + acc.GetAccountNumber(), + acc.GetSequence(), + tx.Fee.Gas, + gasAdjustment, + simulate, + chainID, + tx.Memo, + tx.Fee.Amount, + nil, + ) + + signedTx, err := txbldr.SignStdTx(name, pwd, tx, false) + require.NoError(t, err) + + return doBroadcast(t, port, signedTx) } // ---------------------------------------------------------------------- @@ -768,30 +801,40 @@ func doTransferWithGasAccAuto( // ---------------------------------------------------------------------- // POST /staking/delegators/{delegatorAddr}/delegations Submit delegation -func doDelegate(t *testing.T, port, name, password string, - delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doDelegate( + t *testing.T, port, name, pwd string, delAddr sdk.AccAddress, + valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins, +) sdk.TxResponse { acc := getAccount(t, port, delAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) msg := msgDelegationsInput{ BaseReq: baseReq, DelegatorAddr: delAddr, ValidatorAddr: valAddr, Delegation: sdk.NewCoin(sdk.DefaultBondDenom, amount), } + req, err := cdc.MarshalJSON(msg) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/delegations", delAddr.String()), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var result sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &result) - require.Nil(t, err) + resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/delegations", delAddr.String()), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + // sign and broadcast + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return result + return txResp } type msgDelegationsInput struct { @@ -802,31 +845,39 @@ type msgDelegationsInput struct { } // POST /staking/delegators/{delegatorAddr}/delegations Submit delegation -func doUndelegate(t *testing.T, port, name, password string, - delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doUndelegate( + t *testing.T, port, name, pwd string, delAddr sdk.AccAddress, + valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins, +) sdk.TxResponse { acc := getAccount(t, port, delAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) msg := msgUndelegateInput{ BaseReq: baseReq, DelegatorAddr: delAddr, ValidatorAddr: valAddr, SharesAmount: sdk.NewDecFromInt(amount), } + req, err := cdc.MarshalJSON(msg) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/unbonding_delegations", delAddr), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/unbonding_delegations", delAddr), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - var result sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &result) - require.Nil(t, err) + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - return result + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) + + return txResp } type msgUndelegateInput struct { @@ -837,17 +888,18 @@ type msgUndelegateInput struct { } // POST /staking/delegators/{delegatorAddr}/delegations Submit delegation -func doBeginRedelegation(t *testing.T, port, name, password string, - delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount sdk.Int, - fees sdk.Coins) (resultTx sdk.TxResponse) { +func doBeginRedelegation( + t *testing.T, port, name, pwd string, delAddr sdk.AccAddress, valSrcAddr, + valDstAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins, +) sdk.TxResponse { acc := getAccount(t, port, delAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() - chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) msg := stakingrest.MsgBeginRedelegateInput{ BaseReq: baseReq, DelegatorAddr: delAddr, @@ -855,17 +907,21 @@ func doBeginRedelegation(t *testing.T, port, name, password string, ValidatorDstAddr: valDstAddr, SharesAmount: sdk.NewDecFromInt(amount), } + req, err := cdc.MarshalJSON(msg) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/redelegations", delAddr), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/redelegations", delAddr), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - var result sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &result) - require.Nil(t, err) + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - return result + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) + + return txResp } type msgBeginRedelegateInput struct { @@ -1072,15 +1128,18 @@ func getStakingParams(t *testing.T, port string) staking.Params { // ICS 22 - Gov // ---------------------------------------------------------------------- // POST /gov/proposals Submit a proposal -func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, - amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doSubmitProposal( + t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress, + amount sdk.Int, fees sdk.Coins, +) sdk.TxResponse { acc := getAccount(t, port, proposerAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) pr := govrest.PostProposalReq{ Title: "Test", Description: "test", @@ -1094,14 +1153,17 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA require.NoError(t, err) // submitproposal - res, body := Request(t, port, "POST", "/gov/proposals", req) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body := Request(t, port, "POST", "/gov/proposals", req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - var results sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return results + return txResp } // GET /gov/proposals Query proposals @@ -1160,15 +1222,18 @@ func getProposalsFilterStatus(t *testing.T, port string, status gov.ProposalStat } // POST /gov/proposals/{proposalId}/deposits Deposit tokens to a proposal -func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, - amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doDeposit( + t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress, + proposalID uint64, amount sdk.Int, fees sdk.Coins, +) sdk.TxResponse { acc := getAccount(t, port, proposerAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) dr := govrest.DepositReq{ Depositor: proposerAddr, Amount: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, amount)}, @@ -1178,14 +1243,17 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk req, err := cdc.MarshalJSON(dr) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - var results sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return results + return txResp } // GET /gov/proposals/{proposalId}/deposits Query deposits @@ -1209,14 +1277,19 @@ func getTally(t *testing.T, port string, proposalID uint64) gov.TallyResult { } // POST /gov/proposals/{proposalId}/votes Vote a proposal -func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, option string, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doVote( + t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress, + proposalID uint64, option string, fees sdk.Coins, +) sdk.TxResponse { + // get the account to get the sequence acc := getAccount(t, port, proposerAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) vr := govrest.VoteReq{ Voter: proposerAddr, Option: option, @@ -1226,14 +1299,17 @@ func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.Ac req, err := cdc.MarshalJSON(vr) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) + resp, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) - var results sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return results + return txResp } // GET /gov/proposals/{proposalId}/votes Query voters @@ -1338,24 +1414,32 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing. // TODO: Test this functionality, it is not currently in any of the tests // POST /slashing/validators/{validatorAddr}/unjail Unjail a jailed validator -func doUnjail(t *testing.T, port, seed, name, password string, - valAddr sdk.ValAddress, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doUnjail( + t *testing.T, port, seed, name, pwd string, valAddr sdk.ValAddress, fees sdk.Coins, +) sdk.TxResponse { + + acc := getAccount(t, port, sdk.AccAddress(valAddr.Bytes())) + from := acc.GetAddress().String() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", 1, 1, fees, nil, false, false) + baseReq := rest.NewBaseReq(from, "", chainID, "", "", 1, 1, fees, nil, false) ur := slashingrest.UnjailReq{ BaseReq: baseReq, } req, err := cdc.MarshalJSON(ur) require.NoError(t, err) - res, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var results sdk.TxResponse - err = cdc.UnmarshalJSON([]byte(body), &results) - require.Nil(t, err) + resp, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err = cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return results + return txResp } type unjailReq struct { @@ -1365,27 +1449,34 @@ type unjailReq struct { // ICS24 - fee distribution // POST /distribution/delegators/{delgatorAddr}/rewards Withdraw delegator rewards -func doWithdrawDelegatorAllRewards(t *testing.T, port, seed, name, password string, - delegatorAddr sdk.AccAddress, fees sdk.Coins) (resultTx sdk.TxResponse) { +func doWithdrawDelegatorAllRewards( + t *testing.T, port, seed, name, pwd string, delegatorAddr sdk.AccAddress, fees sdk.Coins, +) sdk.TxResponse { // get the account to get the sequence acc := getAccount(t, port, delegatorAddr) accnum := acc.GetAccountNumber() sequence := acc.GetSequence() chainID := viper.GetString(client.FlagChainID) - baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false) + from := acc.GetAddress().String() + baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false) wr := struct { BaseReq rest.BaseReq `json:"base_req"` }{BaseReq: baseReq} req := cdc.MustMarshalJSON(wr) - res, body := Request(t, port, "POST", fmt.Sprintf("/distribution/delegators/%s/rewards", delegatorAddr), req) - require.Equal(t, http.StatusOK, res.StatusCode, body) - var results sdk.TxResponse - cdc.MustUnmarshalJSON([]byte(body), &results) + resp, body := Request(t, port, "POST", fmt.Sprintf("/distribution/delegators/%s/rewards", delegatorAddr), req) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false) + require.Equal(t, http.StatusOK, resp.StatusCode, body) + + var txResp sdk.TxResponse + err := cdc.UnmarshalJSON([]byte(body), &txResp) + require.NoError(t, err) - return results + return txResp } func mustParseDecCoins(dcstring string) sdk.DecCoins { From b009aed3110c3bbeb92a596fffe315a029b59a03 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 22:51:45 -0500 Subject: [PATCH 08/11] Fix IBC TransferRequestHandlerFn handler --- x/ibc/client/rest/transfer.go | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 6a8eaac0a4b9..99fa6feeb80a 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -48,21 +48,13 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context. return } - var fromAddr sdk.AccAddress - - if req.BaseReq.GenerateOnly { - // When generate only is supplied, the from field must be a valid Bech32 - // address. - addr, err := sdk.AccAddressFromBech32(req.BaseReq.From) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - fromAddr = addr + from, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return } - packet := ibc.NewIBCPacket(fromAddr, to, req.Amount, req.BaseReq.ChainID, destChainID) + packet := ibc.NewIBCPacket(from, to, req.Amount, req.BaseReq.ChainID, destChainID) msg := ibc.IBCTransferMsg{IBCPacket: packet} clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg}) From bed19efb68a6eb473a049530879e9025e72105a8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 22:54:38 -0500 Subject: [PATCH 09/11] Update Swagger meta info and remove keys --- client/lcd/swagger-ui/swagger.yaml | 215 +---------------------------- 1 file changed, 2 insertions(+), 213 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 82a6af083583..bb25b2aa4f7c 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -3,14 +3,12 @@ swagger: "2.0" info: version: "3.0" title: Gaia-Lite for Cosmos - description: A REST interface for state queries, transaction generation, signing, and broadcast. + description: A REST interface for state queries, transaction generation and broadcasting. tags: - name: ICS0 description: Tendermint APIs, such as query blocks, transactions and validatorset - - name: ICS1 - description: Key management APIs - name: ICS20 - description: Create, sign and broadcast transactions + description: Create and broadcast transactions - name: ICS21 description: Stake module APIs - name: ICS22 @@ -269,42 +267,6 @@ paths: $ref: "#/definitions/BroadcastTxCommitResult" 500: description: Internal Server Error - /tx/sign: - post: - tags: - - ICS20 - summary: Sign a Tx - description: Sign a Tx providing locally stored account and according password - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: sendToken - description: sign tx - required: true - schema: - type: object - properties: - base_req: - $ref: "#/definitions/BaseReq" - tx: - $ref: "#/definitions/StdTx" - append_sig: - type: boolean - example: true - responses: - 200: - description: The signed Tx - schema: - $ref: "#/definitions/StdTx" - 400: - description: The Tx was malformated or key doesn't exist - 401: - description: Key password is wrong - 500: - description: Server internal error /tx/broadcast: post: tags: @@ -431,179 +393,6 @@ paths: description: Key password is wrong 500: description: Server internal error - /keys: - get: - summary: List of accounts stored locally - tags: - - ICS1 - produces: - - application/json - responses: - 200: - description: Array of accounts - schema: - type: array - items: - $ref: "#/definitions/KeyOutput" - 500: - description: Server internal error - post: - summary: Create a new account locally - tags: - - ICS1 - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: account - description: The account to create - schema: - type: object - required: - - name - - password - - seed - properties: - name: - type: string - password: - type: string - seed: - type: string - responses: - 200: - description: Returns account information of the created key - schema: - $ref: "#/definitions/KeyOutput" - 400: - description: Invalid request - 409: - description: Key name confliction - 500: - description: Server internal error - /keys/seed: - get: - summary: Create a new seed to create a new account with - tags: - - ICS1 - responses: - 200: - description: 24 word Seed - schema: - type: string - example: blossom pool issue kidney elevator blame furnace winter account merry vessel security depend exact travel bargain problem jelly rural net again mask roast chest - /keys/{name}/recover: - post: - summary: Recover a account from a seed - tags: - - ICS1 - consumes: - - application/json - produces: - - application/json - parameters: - - in: path - name: name - description: Account name - required: true - type: string - - in: body - name: pwdAndSeed - description: Provide password and seed to recover a key - schema: - type: object - required: - - password - - seed - properties: - password: - type: string - seed: - type: string - responses: - 200: - description: Returns account information of the recovered key - schema: - $ref: "#/definitions/KeyOutput" - 400: - description: Invalid request - 409: - description: Key name confliction - 500: - description: Server internal error - /keys/{name}: - parameters: - - in: path - name: name - description: Account name - required: true - type: string - get: - summary: Get a certain locally stored account - tags: - - ICS1 - produces: - - application/json - responses: - 200: - description: Locally stored account - schema: - $ref: "#/definitions/KeyOutput" - 404: - description: Key doesn't exist - put: - summary: Update the password for this account in the KMS - tags: - - ICS1 - consumes: - - application/json - parameters: - - in: body - name: account - description: The new and old password - schema: - type: object - required: - - new_password - - old_password - properties: - new_password: - type: string - old_password: - type: string - responses: - 200: - description: Updated password - 401: - description: Key password is wrong - 404: - description: Key doesn't exist - delete: - summary: Remove an account - tags: - - ICS1 - consumes: - - application/json - parameters: - - in: body - name: account - description: The password of the account to remove from the KMS - schema: - type: object - required: - - password - properties: - password: - type: string - responses: - 200: - description: Removed account - 401: - description: Key password is wrong - 404: - description: Key doesn't exist /auth/accounts/{address}: get: summary: Get the account information on blockchain From 9129f90131f3cc742a5a8f2cd0f5323bd5f13d9e Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 18 Feb 2019 23:05:08 -0500 Subject: [PATCH 10/11] Update Swagger --- client/lcd/swagger-ui/swagger.yaml | 38 +++++++++--------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index bb25b2aa4f7c..c7126ec4dc47 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -355,8 +355,7 @@ paths: description: Server internal error /bank/accounts/{address}/transfers: post: - summary: Send coins (build -> sign -> send) - description: Send coins (build -> sign -> send) + summary: Send coins from one account to another tags: - ICS20 consumes: @@ -371,7 +370,7 @@ paths: type: string - in: body name: account - description: The password of the account to remove from the KMS + description: The sender and tx information required: true schema: type: object @@ -384,13 +383,11 @@ paths: $ref: "#/definitions/Coin" responses: 202: - description: Tx was send and will probably be added to the next block + description: Tx was succesfully generated schema: - $ref: "#/definitions/BroadcastTxCommitResult" + $ref: "#/definitions/StdTx" 400: description: Invalid request - 401: - description: Key password is wrong 500: description: Server internal error /auth/accounts/{address}: @@ -650,7 +647,7 @@ paths: parameters: - in: body name: delegation - description: The password of the account to remove from the KMS + description: The sender and tx information schema: type: object properties: @@ -673,13 +670,11 @@ paths: - application/json responses: 200: - description: OK + description: Tx was succesfully generated schema: - $ref: "#/definitions/BroadcastTxCommitResult" + $ref: "#/definitions/StdTx" 400: description: Invalid delegator address or redelegation request body - 401: - description: Key password is wrong 500: description: Internal Server Error /staking/delegators/{delegatorAddr}/validators: @@ -959,16 +954,14 @@ paths: type: object properties: base_req: - $ref: "#/definitions/BaseReq" + $ref: "#/definitions/StdTx" responses: 200: - description: OK + description: Tx was succesfully generated schema: $ref: "#/definitions/BroadcastTxCommitResult" 400: description: Invalid validator address or base_req - 401: - description: Key password is wrong 500: description: Internal Server Error /slashing/parameters: @@ -1035,13 +1028,11 @@ paths: $ref: "#/definitions/Coin" responses: 200: - description: OK + description: Tx was succesfully generated schema: - $ref: "#/definitions/BroadcastTxCommitResult" + $ref: "#/definitions/StdTx" 400: description: Invalid proposal body - 401: - description: Key password is wrong 500: description: Internal Server Error get: @@ -1978,9 +1969,6 @@ definitions: type: string example: "cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc" description: Sender address or Keybase name to generate a transaction - password: - type: string - example: "12345678" memo: type: string example: "Sent via Cosmos Voyager 🚀" @@ -2003,10 +1991,6 @@ definitions: type: array items: $ref: "#/definitions/Coin" - generate_only: - type: boolean - example: false - description: Create a JSON transaction that can be signed client side instead of actually signing and broadcasting simulate: type: boolean example: false From 392b9c27f20d46f76bc2933e3fa748ea1380a7f1 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 19 Feb 2019 09:32:53 -0500 Subject: [PATCH 11/11] Fix keys package tests --- client/keys/add_test.go | 40 ---------------------------------------- client/keys/root_test.go | 7 ------- 2 files changed, 47 deletions(-) diff --git a/client/keys/add_test.go b/client/keys/add_test.go index bca21393af2a..8a3e8a42df49 100644 --- a/client/keys/add_test.go +++ b/client/keys/add_test.go @@ -2,13 +2,9 @@ package keys import ( "bufio" - "net/http" "strings" "testing" - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/cli" @@ -61,39 +57,3 @@ func Test_runAddCmdBasic(t *testing.T) { err = runAddCmd(cmd, []string{"keyname2"}) assert.NoError(t, err) } - -type MockResponseWriter struct { - dataHeaderStatus int - dataBody []byte -} - -func (MockResponseWriter) Header() http.Header { - panic("Unexpected call!") -} - -func (w *MockResponseWriter) Write(data []byte) (int, error) { - w.dataBody = append(w.dataBody, data...) - return len(data), nil -} - -func (w *MockResponseWriter) WriteHeader(statusCode int) { - w.dataHeaderStatus = statusCode -} - -func TestCheckAndWriteErrorResponse(t *testing.T) { - mockRW := MockResponseWriter{} - - mockRW.WriteHeader(100) - assert.Equal(t, 100, mockRW.dataHeaderStatus) - - detected := CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, errors.New("some ERROR")) - require.True(t, detected) - require.Equal(t, http.StatusBadRequest, mockRW.dataHeaderStatus) - require.Equal(t, "some ERROR", string(mockRW.dataBody[:])) - - mockRW = MockResponseWriter{} - detected = CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, nil) - require.False(t, detected) - require.Equal(t, 0, mockRW.dataHeaderStatus) - require.Equal(t, "", string(mockRW.dataBody[:])) -} diff --git a/client/keys/root_test.go b/client/keys/root_test.go index ef7671593dc9..1cc2db425fa8 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -4,8 +4,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/gorilla/mux" ) func TestCommands(t *testing.T) { @@ -15,8 +13,3 @@ func TestCommands(t *testing.T) { // Commands are registered assert.Equal(t, 7, len(rootCommands.Commands())) } - -func TestRegisterRoutes(t *testing.T) { - fakeRouter := mux.Router{} - RegisterRoutes(&fakeRouter, false) -}