From 126dc8aa7cb23781239b6f41e8dd3f812b85ba8f Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 00:16:50 +0800 Subject: [PATCH 01/22] Add swagger-ui for gov, stake and slashing --- client/lcd/swagger-ui/swagger.yaml | 648 ++++++++++++++++++++++++++++- 1 file changed, 644 insertions(+), 4 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index b7fb70ff3398..c49af58eeff4 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -7,8 +7,16 @@ info: tags: - name: ICS0 description: Tendermint APIs, such as query blocks, transactions and validatorset +- name: ICS1 + description: Key management APIs - name: ICS20 - description: Create and sign a send tx + description: Create, sign and broadcast transactions +- name: ICS21 + description: Stake module APIs +- name: ICS22 + description: Governance module APIs +- name: ICS23 + description: Slashing module APIs - name: version description: Information about the app version schemes: @@ -524,6 +532,586 @@ paths: $ref: "#/definitions/AccountQueryResponse" 404: description: Account is not available + /stake/delegators/{delegatorAddr}/delegations: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + post: + summary: Submit delegation + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - in: body + name: delegation + description: The password of the account to remove from the KMS + schema: + type: object + properties: + delegations: + type: array + items: + type: object + properties: + delegator_addr: + $ref: "#/definitions/Address" + validator_addr: + $ref: "#/definitions/ValidatorAddress" + delegation: + $ref: "#/definitions/Coin" + begin_unbondings: + type: array + items: + type: object + properties: + delegator_addr: + $ref: "#/definitions/Address" + validator_src_addr: + $ref: "#/definitions/ValidatorAddress" + validator_dst_addr: + $ref: "#/definitions/ValidatorAddress" + shares: + type: string + example: "100" + begin_redelegates: + type: array + items: + type: object + properties: + delegator_addr: + $ref: "#/definitions/Address" + validator_addr: + $ref: "#/definitions/ValidatorAddress" + shares: + type: string + example: "100" + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + 404: + description: Not Found + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: AccAddress of Delegator + required: true + type: string + get: + summary: Get all delegations (delegation, undelegation) from a delegator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/validators: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + get: + summary: Query all validators that a delegator is bonded to + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + /stake/delegators/{delegatorAddr}/validators/{validatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + - in: path + name: validatorAddr + description: Bech32 ValAddress of Delegator + required: true + type: string + get: + summary: Query a validator that a delegator is bonded to + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + /stake/delegators/{delegatorAddr}/txs: + parameters: + - in: path + name: delegatorAddr + description: AccAddress of Delegator + required: true + type: string + get: + summary: Get all staking txs (i.e msgs) from a delegator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/TxQuery" + 404: + description: Not Found + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + - in: path + name: validatorAddr + description: Bech32 ValAddress of Delegator + required: true + type: string + get: + summary: Query the current delegation status between a delegator and a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + - in: path + name: validatorAddr + description: Bech32 ValAddress of Delegator + required: true + type: string + get: + summary: Query all unbonding delegations between a delegator and a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + 500: + description: Internal Server Error + /stake/validators: + get: + summary: Get all validator candidates + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 500: + description: Internal Server Error + /stake/validators/{validatorAddr}: + parameters: + - in: path + name: validatorAddr + description: Bech32 ValAddress of Delegator + required: true + type: string + get: + summary: Query the information from a single validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 404: + description: Not Found + 500: + description: Internal Server Error + /stake/pool: + get: + summary: Get the current state of the staking pool + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 500: + description: Internal Server Error + /stake/parameters: + get: + summary: Get the current staking parameter values + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + 500: + description: Internal Server Error + /slashing/signing_info/{validator_pub}: + get: + description: Get validator's sign info + consumes: + - application/json + produces: + - application/json + tags: + - ICS23 + summary: Get validator's sign info + parameters: + - type: string + description: validator's public key + name: validator_pub + required: true + in: path + responses: + '200': + description: OK + /slashing/unrevoke: + post: + description: Unrevoke a revoked validator + consumes: + - application/json + produces: + - application/json + tags: + - ICS23 + summary: Unrevoke a revoked validator + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - description: '' + name: UnrevokeBody + in: body + required: true + schema: + type: object + properties: + base_req: + "$ref": "#/definitions/BaseReq" + validator_addr: + type: string + responses: + 200: + description: OK + schema: + $ref: "#/definitions/BroadcastTxCommitResult" + /gov/proposals: + post: + description: Send transaction to submit a proposal + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Submit a proposal + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - description: valid value of `"proposal_type"` can be `"Text"`, `"ParameterChange"`, `"SoftwareUpgrade"` + name: postProposalBody + in: body + required: true + schema: + type: object + properties: + base_req: + "$ref": "#/definitions/BaseReq" + title: + type: string + description: + type: string + proposal_type: + type: string + proposer: + "$ref": "#/definitions/Address" + initial_deposit: + type: array + items: + $ref: "#/definitions/Coin" + responses: + '200': + description: OK + schema: + "$ref": "#/definitions/BroadcastTxCommitResult" + get: + description: Query proposals information with parameters + produces: + - application/json + tags: + - ICS22 + parameters: + - in: query + name: voter + description: voter address + required: false + type: string + - in: query + name: depositer + description: depositer address + required: false + type: string + - in: query + name: status + description: proposal status, valid values can be `"DepositPeriod"`, `"VotingPeriod"`, `"Passed"`, `"Rejected"` + required: false + type: string + summary: Query proposals + responses: + 200: + description: OK + schema: + type: array + items: + "$ref": "#/definitions/TextProposal" + /gov/proposals/{proposal-id}/deposits: + post: + description: Send transaction to deposit tokens to a proposal + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Deposit tokens to a proposal + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - type: string + description: proposal id + name: proposal-id + required: true + in: path + - description: '' + name: depositBody + in: body + required: true + schema: + type: object + properties: + base_req: + "$ref": "#/definitions/BaseReq" + depositer: + "$ref": "#/definitions/Address" + amount: + type: array + items: + $ref: "#/definitions/Coin" + responses: + 200: + description: OK + schema: + "$ref": "#/definitions/BroadcastTxCommitResult" + /gov/proposals/{proposal-id}/votes: + post: + description: Send transaction to vote a proposal + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Vote a proposal + parameters: + - in: query + name: simulate + description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it + required: false + type: boolean + - in: query + name: generate_only + description: if true, build an unsigned transaction and write it back + required: false + type: boolean + - type: string + description: proposal id + name: proposal-id + required: true + in: path + - description: valid value of `"option"` field can be `"Yes"`, `"No"`, `"NoWithVeto"` and `"Abstain"` + name: voteBody + in: body + required: true + schema: + type: object + properties: + base_req: + "$ref": "#/definitions/BaseReq" + voter: + "$ref": "#/definitions/Address" + option: + type: string + responses: + 200: + description: OK + schema: + "$ref": "#/definitions/BroadcastTxCommitResult" + get: + description: Query voters information by proposal-id + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Query voters + parameters: + - type: string + description: proposal id + name: proposal-id + required: true + in: path + responses: + 200: + description: OK + schema: + type: array + items: + "$ref": "#/definitions/Vote" + /gov/proposals/{proposal-id}: + get: + description: Query a proposal by id + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Query a proposal + parameters: + - type: string + name: proposal-id + required: true + in: path + responses: + 200: + description: OK + schema: + "$ref": "#/definitions/TextProposal" + /gov/proposals/{proposal-id}/deposits/{depositer}: + get: + description: Query deposit by proposal-id and depositer address + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Query deposit + parameters: + - type: string + description: proposal id + name: proposal-id + required: true + in: path + - type: string + description: depositer address + name: depositer + required: true + in: path + responses: + 200: + description: OK + schema: + $ref: "#/definitions/Deposite" + /gov/proposals/{proposal-id}/votes/{voter}: + get: + description: Query vote information by proposal-id and voter address + consumes: + - application/json + produces: + - application/json + tags: + - ICS22 + summary: Query vote + parameters: + - type: string + description: proposal id + name: proposal-id + required: true + in: path + - type: string + description: voter address + name: voter + required: true + in: path + responses: + 200: + description: OK + schema: + $ref: "#/definitions/Vote" definitions: CheckTxResult: @@ -615,12 +1203,12 @@ definitions: type: string Address: type: string - description: bech32 encoded addres + description: bech32 encoded address example: cosmoszgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq ValidatorAddress: type: string - description: bech32 encoded addres - example: cosmosvaloper:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + description: bech32 encoded address + example: cosmosvaloper1depk54cuajgkzea6zpgkq36tnjwdzv4avv9cxd PubKey: type: object properties: @@ -908,3 +1496,55 @@ definitions: accum: type: number example: 1000 + TextProposal: + type: object + properties: + proposal_id: + type: integer + title: + type: string + description: + type: string + proposal_type: + type: string + proposal_status: + type: string + tally_result: + type: object + properties: + yes: + type: string + abstain: + type: string + no: + type: string + no_with_veto: + type: string + submit_block: + type: string + total_deposit: + type: array + items: + "$ref": "#/definitions/Coin" + voting_start_block: + type: string + Deposite: + type: object + properties: + amount: + type: array + items: + "$ref": "#/definitions/Coin" + proposal_id: + type: integer + depositer: + "$ref": "#/definitions/Address" + Vote: + type: object + properties: + voter: + type: string + proposal_id: + type: integer + option: + type: string From d8852d731fb255636bc097567a894365821e0e5d Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 00:33:06 +0800 Subject: [PATCH 02/22] Add json consume --- client/lcd/swagger-ui/swagger.yaml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index c49af58eeff4..db7693305927 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -597,6 +597,8 @@ paths: example: "100" tags: - ICS21 + consumes: + - application/json produces: - application/json responses: @@ -798,8 +800,6 @@ paths: /slashing/signing_info/{validator_pub}: get: description: Get validator's sign info - consumes: - - application/json produces: - application/json tags: @@ -1020,8 +1020,6 @@ paths: "$ref": "#/definitions/BroadcastTxCommitResult" get: description: Query voters information by proposal-id - consumes: - - application/json produces: - application/json tags: @@ -1043,8 +1041,6 @@ paths: /gov/proposals/{proposal-id}: get: description: Query a proposal by id - consumes: - - application/json produces: - application/json tags: @@ -1063,8 +1059,6 @@ paths: /gov/proposals/{proposal-id}/deposits/{depositer}: get: description: Query deposit by proposal-id and depositer address - consumes: - - application/json produces: - application/json tags: @@ -1089,8 +1083,6 @@ paths: /gov/proposals/{proposal-id}/votes/{voter}: get: description: Query vote information by proposal-id and voter address - consumes: - - application/json produces: - application/json tags: From eadaf4359849538c8cd061b8d080f56af0b6fd5e Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 10:58:56 +0800 Subject: [PATCH 03/22] Add json to response header --- client/lcd/swagger-ui/swagger.yaml | 84 ++++++++++++++++++++---------- x/gov/client/rest/rest.go | 11 ++-- x/slashing/client/rest/query.go | 10 +--- x/stake/client/rest/query.go | 17 +++--- x/stake/client/rest/tx.go | 2 +- 5 files changed, 74 insertions(+), 50 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index db7693305927..8a0f62de5da1 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -18,7 +18,7 @@ tags: - name: ICS23 description: Slashing module APIs - name: version - description: Information about the app version + description: Query app version schemes: - https securityDefinitions: @@ -38,7 +38,7 @@ paths: get: summary: Version of the connected node tags: - - ICS0 + - version description: Get the version of the SDK running on the connected node to compare against expected responses: 200: @@ -614,7 +614,7 @@ paths: parameters: - in: path name: delegatorAddr - description: AccAddress of Delegator + description: Bech32 AccAddress of Delegator required: true type: string get: @@ -648,6 +648,8 @@ paths: description: OK 404: description: Not Found + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/validators/{validatorAddr}: parameters: - in: path @@ -671,11 +673,13 @@ paths: description: OK 404: description: Not Found + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/txs: parameters: - in: path name: delegatorAddr - description: AccAddress of Delegator + description: Bech32 AccAddress of Delegator required: true type: string get: @@ -702,7 +706,7 @@ paths: type: string - in: path name: validatorAddr - description: Bech32 ValAddress of Delegator + description: Bech32 OperatorAddress of validator required: true type: string get: @@ -716,6 +720,8 @@ paths: description: OK 404: description: Not Found + 500: + description: Internal Server Error /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: parameters: - in: path @@ -725,7 +731,7 @@ paths: type: string - in: path name: validatorAddr - description: Bech32 ValAddress of Delegator + description: Bech32 OperatorAddress of validator required: true type: string get: @@ -751,13 +757,15 @@ paths: responses: 200: description: OK + 404: + description: Not Found 500: description: Internal Server Error /stake/validators/{validatorAddr}: parameters: - in: path name: validatorAddr - description: Bech32 ValAddress of Delegator + description: Bech32 OperatorAddress of validator required: true type: string get: @@ -797,33 +805,35 @@ paths: description: OK 500: description: Internal Server Error - /slashing/signing_info/{validator_pub}: + /slashing/signing_info/{validator}: get: - description: Get validator's sign info + summary: Get sign info of given validator + description: Get sign info of given validator produces: - application/json tags: - ICS23 - summary: Get validator's sign info parameters: - type: string - description: validator's public key - name: validator_pub + description: Bech32 validator public key + name: validator required: true in: path responses: '200': description: OK - /slashing/unrevoke: + 500: + description: Internal Server Error + /slashing/unjail: post: - description: Unrevoke a revoked validator + summary: Unjail a jailed validator + description: Send transaction to unjail a jailed validator consumes: - application/json produces: - application/json tags: - ICS23 - summary: Unrevoke a revoked validator parameters: - in: query name: simulate @@ -836,7 +846,7 @@ paths: required: false type: boolean - description: '' - name: UnrevokeBody + name: UnjailBody in: body required: true schema: @@ -845,14 +855,17 @@ paths: base_req: "$ref": "#/definitions/BaseReq" validator_addr: - type: string + "$ref": "#/definitions/ValidatorAddress" responses: 200: description: OK schema: $ref: "#/definitions/BroadcastTxCommitResult" + 500: + description: Internal Server Error /gov/proposals: post: + summary: Submit a proposal description: Send transaction to submit a proposal consumes: - application/json @@ -860,7 +873,6 @@ paths: - application/json tags: - ICS22 - summary: Submit a proposal parameters: - in: query name: simulate @@ -894,11 +906,14 @@ paths: items: $ref: "#/definitions/Coin" responses: - '200': + 200: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 500: + description: Internal Server Error get: + summary: Query proposals description: Query proposals information with parameters produces: - application/json @@ -920,7 +935,6 @@ paths: description: proposal status, valid values can be `"DepositPeriod"`, `"VotingPeriod"`, `"Passed"`, `"Rejected"` required: false type: string - summary: Query proposals responses: 200: description: OK @@ -928,8 +942,11 @@ paths: type: array items: "$ref": "#/definitions/TextProposal" + 500: + description: Internal Server Error /gov/proposals/{proposal-id}/deposits: post: + summary: Deposit tokens to a proposal description: Send transaction to deposit tokens to a proposal consumes: - application/json @@ -937,7 +954,6 @@ paths: - application/json tags: - ICS22 - summary: Deposit tokens to a proposal parameters: - in: query name: simulate @@ -974,8 +990,11 @@ paths: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 500: + description: Internal Server Error /gov/proposals/{proposal-id}/votes: post: + summary: Vote a proposal description: Send transaction to vote a proposal consumes: - application/json @@ -983,7 +1002,6 @@ paths: - application/json tags: - ICS22 - summary: Vote a proposal parameters: - in: query name: simulate @@ -1018,13 +1036,15 @@ paths: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 500: + description: Internal Server Error get: + summary: Query voters description: Query voters information by proposal-id produces: - application/json tags: - ICS22 - summary: Query voters parameters: - type: string description: proposal id @@ -1038,14 +1058,16 @@ paths: type: array items: "$ref": "#/definitions/Vote" + 500: + description: Internal Server Error /gov/proposals/{proposal-id}: get: + summary: Query a proposal description: Query a proposal by id produces: - application/json tags: - ICS22 - summary: Query a proposal parameters: - type: string name: proposal-id @@ -1056,14 +1078,16 @@ paths: description: OK schema: "$ref": "#/definitions/TextProposal" + 500: + description: Internal Server Error /gov/proposals/{proposal-id}/deposits/{depositer}: get: + summary: Query deposit description: Query deposit by proposal-id and depositer address produces: - application/json tags: - ICS22 - summary: Query deposit parameters: - type: string description: proposal id @@ -1071,7 +1095,7 @@ paths: required: true in: path - type: string - description: depositer address + description: Bech32 depositer address name: depositer required: true in: path @@ -1080,14 +1104,16 @@ paths: description: OK schema: $ref: "#/definitions/Deposite" + 500: + description: Internal Server Error /gov/proposals/{proposal-id}/votes/{voter}: get: + summary: Query vote description: Query vote information by proposal-id and voter address produces: - application/json tags: - ICS22 - summary: Query vote parameters: - type: string description: proposal id @@ -1095,7 +1121,7 @@ paths: required: true in: path - type: string - description: voter address + description: Bech32 voter address name: voter required: true in: path @@ -1104,6 +1130,8 @@ paths: description: OK schema: $ref: "#/definitions/Vote" + 500: + description: Internal Server Error definitions: CheckTxResult: diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index f66331ad5a18..0f0f509cfb8d 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -197,7 +197,7 @@ func queryProposalHandlerFn(cdc *codec.Codec) http.HandlerFunc { utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -264,7 +264,7 @@ func queryDepositHandlerFn(cdc *codec.Codec) http.HandlerFunc { utils.WriteErrorResponse(w, http.StatusNotFound, err.Error()) return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -335,6 +335,7 @@ func queryVoteHandlerFn(cdc *codec.Codec) http.HandlerFunc { utils.WriteErrorResponse(w, http.StatusNotFound, err.Error()) return } + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -372,7 +373,7 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec) http.HandlerFunc { utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -437,7 +438,7 @@ func queryProposalsWithParameterFn(cdc *codec.Codec) http.HandlerFunc { utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -479,7 +480,7 @@ func queryTallyOnProposalHandlerFn(cdc *codec.Codec) http.HandlerFunc { w.Write([]byte(err.Error())) return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index e83f1a235dcd..27921070e26e 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/gorilla/mux" + "github.com/cosmos/cosmos-sdk/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) { @@ -49,13 +50,6 @@ func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *code return } - output, err := cdc.MarshalJSON(signingInfo) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) - return - } - - w.Write(output) + utils.PostProcessResponse(w, cdc, signingInfo, cliCtx.Indent) } } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index a8fbfecf4d76..6598c5b29686 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -115,7 +115,7 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -194,6 +194,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Han w.Write([]byte(err.Error())) return } + w.Header().Set("Content-Type", "application/json") w.Write(output) } } @@ -240,7 +241,7 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -288,7 +289,7 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handl return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -327,7 +328,7 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -369,7 +370,7 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) ht return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -427,7 +428,7 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -445,7 +446,7 @@ func poolHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } @@ -463,7 +464,7 @@ func paramsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - + w.Header().Set("Content-Type", "application/json") w.Write(res) } } diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index 427fb5e19e14..62701be79894 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -271,7 +271,7 @@ func delegationsRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx conte utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - + w.Header().Set("Content-Type", "application/json") w.Write(output) } } From 1774658b8dfea7da4a3e98ceb859330f3177504f Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 11:36:48 +0800 Subject: [PATCH 04/22] Fix some bugs in stake APIs --- client/lcd/swagger-ui/swagger.yaml | 69 +++++++++++++++--------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 8a0f62de5da1..693f3fc8d734 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -367,7 +367,7 @@ paths: schema: type: array items: - $ref: '#/definitions/Account' + $ref: '#/definitions/KeyOutput' post: summary: Create a new account locally tags: @@ -397,7 +397,7 @@ paths: 200: description: Returns account information of the created key schema: - $ref: "#/definitions/Account" + $ref: "#/definitions/KeyOutput" /keys/seed: get: summary: Create a new seed to create a new account with @@ -440,7 +440,7 @@ paths: 200: description: Returns account information of the recovered key schema: - $ref: "#/definitions/Account" + $ref: "#/definitions/KeyOutput" /keys/{name}: parameters: - in: path @@ -458,7 +458,7 @@ paths: 200: description: Locally stored account schema: - $ref: "#/definitions/Account" + $ref: "#/definitions/KeyOutput" 404: description: Account is not available put: @@ -529,7 +529,25 @@ paths: 200: description: Account information on the blockchain schema: - $ref: "#/definitions/AccountQueryResponse" + type: object + properties: + type: + type: string + value: + type: object + properties: + account_number: + type: string + address: + type: string + coins: + type: array + items: + $ref: "#/definitions/Coin" + public_key: + type: string + sequence: + type: string 404: description: Account is not available /stake/delegators/{delegatorAddr}/delegations: @@ -558,6 +576,8 @@ paths: schema: type: object properties: + base_req: + "$ref": "#/definitions/BaseReq" delegations: type: array items: @@ -576,9 +596,7 @@ paths: properties: delegator_addr: $ref: "#/definitions/Address" - validator_src_addr: - $ref: "#/definitions/ValidatorAddress" - validator_dst_addr: + validator_addr: $ref: "#/definitions/ValidatorAddress" shares: type: string @@ -590,7 +608,9 @@ paths: properties: delegator_addr: $ref: "#/definitions/Address" - validator_addr: + validator_src_addr: + $ref: "#/definitions/ValidatorAddress" + validator_dst_addr: $ref: "#/definitions/ValidatorAddress" shares: type: string @@ -1224,7 +1244,7 @@ definitions: Address: type: string description: bech32 encoded address - example: cosmoszgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + example: cosmos1depk54cuajgkzea6zpgkq36tnjwdzv4afc3d27 ValidatorAddress: type: string description: bech32 encoded address @@ -1338,44 +1358,23 @@ definitions: sequence: type: string example: "0" - Account: + KeyOutput: type: object properties: name: type: string example: Main Account address: - $ref: "#/definitions/Address" + type: string + example: cosmos1depk54cuajgkzea6zpgkq36tnjwdzv4afc3d27 pub_key: type: string - example: "cosmospub1addwnpepqfgv3pakxazq2fgs8tmmhmzsrs94fptl7kyztyxprjpf0mkus3h7cxqe70s" + example: "cosmospub1addwnpepqtqc88gfdxyzcdm2eqr3tnlnxnelyqehy8k95qzgwdz5zccdft9rq5q7wj2" type: type: string example: local seed: type: string - AccountInfo: - type: object - properties: - account_number: - type: string - address: - type: string - coins: - type: array - items: - $ref: "#/definitions/Coin" - public_key: - type: string - sequence: - type: string - AccountQueryResponse: - type: object - properties: - type: - type: string - value: - $ref: "#/definitions/AccountInfo" BlockID: type: object properties: From da7dc49c23e37e52fae62bc64979d0fb2e9d2aa2 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 12:04:56 +0800 Subject: [PATCH 05/22] Refactor swagger.ymal, remove definitions which are only referenced once --- client/lcd/swagger-ui/swagger.yaml | 152 +++++++++++++---------------- 1 file changed, 69 insertions(+), 83 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 693f3fc8d734..88aecb7fd83e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -99,7 +99,7 @@ paths: 200: description: The latest block schema: - $ref: "#/definitions/QueryBlock" + $ref: "#/definitions/BlockQuery" /blocks/{height}: get: summary: Get a block at a certain height @@ -117,7 +117,7 @@ paths: 200: description: The block at a specific height schema: - $ref: "#/definitions/QueryBlock" + $ref: "#/definitions/BlockQuery" 404: description: Block at height is not available /validatorsets/latest: @@ -232,7 +232,13 @@ paths: description: Build a StdTx transaction and serilize it to a byte array with amino, then the `"tx"` field in the post body will be the base64 encoding of the byte array. The supported return types includes `"block"`(return after tx commit), `"sync"`(return afer CheckTx) and `"async"`(return right away). required: true schema: - $ref: "#/definitions/TendertmintTx" + type: object + properties: + tx: + type: string + return: + type: string + example: block responses: 200: description: Broadcast tx result @@ -254,7 +260,25 @@ paths: description: sign tx required: true schema: - $ref: "#/definitions/TxSign" + type: object + properties: + tx: + $ref: "#/definitions/StdTx" + name: + type: string + password: + type: string + chain_id: + type: string + account_number: + type: string + example: "0" + sequence: + type: string + example: "0" + append_sig: + type: boolean + example: true responses: 200: description: The signed Tx @@ -278,7 +302,10 @@ paths: description: broadcast tx required: true schema: - $ref: "#/definitions/TxBroadcast" + type: object + properties: + tx: + $ref: "#/definitions/StdTx" responses: 202: description: Tx was send and will probably be added to the next block @@ -1230,15 +1257,6 @@ definitions: type: string value: type: string - Fee: - type: object - properties: - gas: - type: string - amount: - type: array - items: - $ref: "#/definitions/Coin" Msg: type: string Address: @@ -1249,15 +1267,6 @@ definitions: type: string description: bech32 encoded address example: cosmosvaloper1depk54cuajgkzea6zpgkq36tnjwdzv4avv9cxd - PubKey: - type: object - properties: - type: - type: string - example: "tendermint/PubKeySecp256k1" - value: - type: string - example: "Avz04VhtKJh8ACCVzlI8aTosGy0ikFXKIVHQ3jKMrosH" ValidatorPubKey: type: string description: bech32 encoded public key @@ -1274,21 +1283,6 @@ definitions: Hash: type: string example: EE5F3404034C524501629B56E0DDC38FAD651F04 - Result: - type: object - properties: - log: - type: string - gas_wanted: - type: string - example: "0" - gas_used: - type: string - example: "0" - tags: - type: array - items: - $ref: "#/definitions/KVPair" TxQuery: type: object properties: @@ -1299,40 +1293,20 @@ definitions: tx: $ref: "#/definitions/StdTx" result: - $ref: "#/definitions/Result" - TendertmintTx: - type: object - properties: - tx: - type: string - return: - type: string - example: block - TxBroadcast: - type: object - properties: - tx: - $ref: "#/definitions/StdTx" - TxSign: - type: object - properties: - tx: - $ref: "#/definitions/StdTx" - name: - type: string - password: - type: string - chain_id: - type: string - account_number: - type: string - example: "0" - sequence: - type: string - example: "0" - append_sig: - type: boolean - example: true + type: object + properties: + log: + type: string + gas_wanted: + type: string + example: "0" + gas_used: + type: string + example: "0" + tags: + type: array + items: + $ref: "#/definitions/KVPair" StdTx: type: object properties: @@ -1341,7 +1315,14 @@ definitions: items: $ref: "#/definitions/Msg" fee: - $ref: "#/definitions/Fee" + type: object + properties: + gas: + type: string + amount: + type: array + items: + $ref: "#/definitions/Coin" memo: type: string signature: @@ -1351,7 +1332,14 @@ definitions: type: string example: MEUCIQD02fsDPra8MtbRsyB1w7bqTM55Wu138zQbFcWx4+CFyAIge5WNPfKIuvzBZ69MyqHsqD8S1IwiEp+iUb6VSdtlpgY= pub_key: - $ref: "#/definitions/PubKey" + type: object + properties: + type: + type: string + example: "tendermint/PubKeySecp256k1" + value: + type: string + example: "Avz04VhtKJh8ACCVzlI8aTosGy0ikFXKIVHQ3jKMrosH" account_number: type: string example: "0" @@ -1467,18 +1455,16 @@ definitions: signature: type: string example: '7uTC74QlknqYWEwg7Vn6M8Om7FuZ0EO4bjvuj6rwH1mTUJrRuMMZvAAqT9VjNgP0RA/TDp6u/92AqrZfXJSpBQ==' - BlockMeta: - type: object - properties: - header: - $ref: "#/definitions/BlockHeader" - block_id: - $ref: "#/definitions/BlockID" - QueryBlock: + BlockQuery: type: object properties: block_meta: - $ref: "#/definitions/BlockMeta" + type: object + properties: + header: + $ref: "#/definitions/BlockHeader" + block_id: + $ref: "#/definitions/BlockID" block: $ref: "#/definitions/Block" BaseReq: From e529488d1e0d6c66e91418915740d19f177a6db2 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 12:12:00 +0800 Subject: [PATCH 06/22] Remove duplicated json header --- x/stake/client/rest/query.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 6598c5b29686..a8fbfecf4d76 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -115,7 +115,7 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -194,7 +194,6 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Han w.Write([]byte(err.Error())) return } - w.Header().Set("Content-Type", "application/json") w.Write(output) } } @@ -241,7 +240,7 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -289,7 +288,7 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handl return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -328,7 +327,7 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -370,7 +369,7 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) ht return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -428,7 +427,7 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -446,7 +445,7 @@ func poolHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -464,7 +463,7 @@ func paramsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - w.Header().Set("Content-Type", "application/json") + w.Write(res) } } From 4ba59c7333e966df67898de5000e231c4a66cbab Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 14:01:44 +0800 Subject: [PATCH 07/22] refactor query validator set response --- client/lcd/swagger-ui/swagger.yaml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 88aecb7fd83e..47e19a2618a2 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -1267,10 +1267,6 @@ definitions: type: string description: bech32 encoded address example: cosmosvaloper1depk54cuajgkzea6zpgkq36tnjwdzv4avv9cxd - ValidatorPubKey: - type: string - description: bech32 encoded public key - example: cosmosvalconspub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq Coin: type: object properties: @@ -1494,13 +1490,14 @@ definitions: address: $ref: '#/definitions/ValidatorAddress' pub_key: - $ref: "#/definitions/ValidatorPubKey" + type: string + example: cosmosvalconspub1zcjduepq7sjfglw7ra4mjxpw4ph7dtdhdheh7nz8dfgl6t8u2n5szuuql9mqsrwquu power: - type: number - example: 1000 + type: string + example: "1000" accum: - type: number - example: 1000 + type: string + example: "1000" TextProposal: type: object properties: From 6e1a4d1dd01b63d466e338fbb3bb5a0c130f91da Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 10 Oct 2018 23:48:22 +0800 Subject: [PATCH 08/22] Refactor swagger.yaml according code reviewer feedback --- client/lcd/swagger-ui/swagger.yaml | 121 ++++++++++++++++++----------- x/gov/client/rest/rest.go | 2 +- x/slashing/client/rest/query.go | 9 ++- x/slashing/client/rest/tx.go | 9 ++- 4 files changed, 88 insertions(+), 53 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 47e19a2618a2..2adb4d71351d 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -118,6 +118,8 @@ paths: description: The block at a specific height schema: $ref: "#/definitions/BlockQuery" + 400: + description: Invalid height 404: description: Block at height is not available /validatorsets/latest: @@ -184,8 +186,8 @@ paths: description: Tx with the provided hash schema: $ref: "#/definitions/TxQuery" - 404: - description: Tx not available for provided hash + 500: + description: Internal Server Error /txs: get: tags: @@ -215,8 +217,10 @@ paths: type: array items: $ref: "#/definitions/TxQuery" - 404: - description: Pagination is out of bounds + 400: + description: Invalid request + 500: + description: Internal Server Error post: tags: - ICS0 @@ -244,6 +248,8 @@ paths: description: Broadcast tx result schema: $ref: "#/definitions/BroadcastTxCommitResult" + 500: + description: Internal Server Error /tx/sign: post: tags: @@ -575,8 +581,8 @@ paths: type: string sequence: type: string - 404: - description: Account is not available + 204: + description: No content about this account address /stake/delegators/{delegatorAddr}/delegations: parameters: - in: path @@ -653,8 +659,10 @@ paths: description: OK schema: $ref: "#/definitions/BroadcastTxCommitResult" - 404: - description: Not Found + 400: + description: Invalid request + 401: + description: Password is wrong 500: description: Internal Server Error /stake/delegators/{delegatorAddr}: @@ -673,8 +681,8 @@ paths: responses: 200: description: OK - 404: - description: Not Found + 400: + description: Invalid delegatorAddr 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/validators: @@ -693,8 +701,8 @@ paths: responses: 200: description: OK - 404: - description: Not Found + 400: + description: Invalid delegatorAddr 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/validators/{validatorAddr}: @@ -718,8 +726,8 @@ paths: responses: 200: description: OK - 404: - description: Not Found + 400: + description: Invalid delegatorAddr or validatorAddr 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/txs: @@ -739,9 +747,11 @@ paths: 200: description: OK schema: - $ref: "#/definitions/TxQuery" - 404: - description: Not Found + type: array + items: + $ref: "#/definitions/TxQuery" + 400: + description: Invalid delegatorAddr 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}: @@ -765,8 +775,8 @@ paths: responses: 200: description: OK - 404: - description: Not Found + 400: + description: Invalid delegatorAddr or validatorAddr 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: @@ -790,8 +800,8 @@ paths: responses: 200: description: OK - 404: - description: Not Found + 400: + description: Invalid delegatorAddr or validatorAddr 500: description: Internal Server Error /stake/validators: @@ -804,8 +814,6 @@ paths: responses: 200: description: OK - 404: - description: Not Found 500: description: Internal Server Error /stake/validators/{validatorAddr}: @@ -824,8 +832,6 @@ paths: responses: 200: description: OK - 404: - description: Not Found 500: description: Internal Server Error /stake/pool: @@ -852,7 +858,7 @@ paths: description: OK 500: description: Internal Server Error - /slashing/signing_info/{validator}: + /slashing/validators/{validatorPubKey}/signing_info: get: summary: Get sign info of given validator description: Get sign info of given validator @@ -863,15 +869,17 @@ paths: parameters: - type: string description: Bech32 validator public key - name: validator + name: validatorPubKey required: true in: path responses: - '200': + 200: description: OK + 204: + description: No sign info of this validator 500: description: Internal Server Error - /slashing/unjail: + /slashing/validators/{validatorAddr}/unjail: post: summary: Unjail a jailed validator description: Send transaction to unjail a jailed validator @@ -892,6 +900,11 @@ paths: description: if true, build an unsigned transaction and write it back required: false type: boolean + - type: string + description: Bech32 validator address + name: validatorAddr + required: true + in: path - description: '' name: UnjailBody in: body @@ -901,8 +914,6 @@ paths: properties: base_req: "$ref": "#/definitions/BaseReq" - validator_addr: - "$ref": "#/definitions/ValidatorAddress" responses: 200: description: OK @@ -932,7 +943,7 @@ paths: required: false type: boolean - description: valid value of `"proposal_type"` can be `"Text"`, `"ParameterChange"`, `"SoftwareUpgrade"` - name: postProposalBody + name: post_proposal_body in: body required: true schema: @@ -989,9 +1000,11 @@ paths: type: array items: "$ref": "#/definitions/TextProposal" + 400: + description: Invalid request 500: description: Internal Server Error - /gov/proposals/{proposal-id}/deposits: + /gov/proposals/{proposalId}/deposits: post: summary: Deposit tokens to a proposal description: Send transaction to deposit tokens to a proposal @@ -1014,11 +1027,11 @@ paths: type: boolean - type: string description: proposal id - name: proposal-id + name: proposalId required: true in: path - description: '' - name: depositBody + name: deposit_body in: body required: true schema: @@ -1039,7 +1052,7 @@ paths: "$ref": "#/definitions/BroadcastTxCommitResult" 500: description: Internal Server Error - /gov/proposals/{proposal-id}/votes: + /gov/proposals/{proposalId}/votes: post: summary: Vote a proposal description: Send transaction to vote a proposal @@ -1062,7 +1075,7 @@ paths: type: boolean - type: string description: proposal id - name: proposal-id + name: proposalId required: true in: path - description: valid value of `"option"` field can be `"Yes"`, `"No"`, `"NoWithVeto"` and `"Abstain"` @@ -1087,7 +1100,7 @@ paths: description: Internal Server Error get: summary: Query voters - description: Query voters information by proposal-id + description: Query voters information by proposalId produces: - application/json tags: @@ -1095,7 +1108,7 @@ paths: parameters: - type: string description: proposal id - name: proposal-id + name: proposalId required: true in: path responses: @@ -1105,9 +1118,11 @@ paths: type: array items: "$ref": "#/definitions/Vote" + 400: + description: Invalid request 500: description: Internal Server Error - /gov/proposals/{proposal-id}: + /gov/proposals/{proposalId}: get: summary: Query a proposal description: Query a proposal by id @@ -1117,7 +1132,7 @@ paths: - ICS22 parameters: - type: string - name: proposal-id + name: proposalId required: true in: path responses: @@ -1125,12 +1140,16 @@ paths: description: OK schema: "$ref": "#/definitions/TextProposal" + 400: + description: Invalid request + 404: + description: Found no proposal 500: description: Internal Server Error - /gov/proposals/{proposal-id}/deposits/{depositer}: + /gov/proposals/{proposalId}/deposits/{depositer}: get: summary: Query deposit - description: Query deposit by proposal-id and depositer address + description: Query deposit by proposalId and depositer address produces: - application/json tags: @@ -1138,7 +1157,7 @@ paths: parameters: - type: string description: proposal id - name: proposal-id + name: proposalId required: true in: path - type: string @@ -1151,12 +1170,16 @@ paths: description: OK schema: $ref: "#/definitions/Deposite" + 400: + description: Invalid request + 404: + description: Found no deposite 500: description: Internal Server Error - /gov/proposals/{proposal-id}/votes/{voter}: + /gov/proposals/{proposalId}/votes/{voter}: get: summary: Query vote - description: Query vote information by proposal-id and voter address + description: Query vote information by proposalId and voter address produces: - application/json tags: @@ -1164,7 +1187,7 @@ paths: parameters: - type: string description: proposal id - name: proposal-id + name: proposalId required: true in: path - type: string @@ -1177,6 +1200,10 @@ paths: description: OK schema: $ref: "#/definitions/Vote" + 400: + description: Invalid request + 404: + description: Found no vote 500: description: Internal Server Error diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index 0f0f509cfb8d..86396e05b3a6 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -17,7 +17,7 @@ import ( // REST Variable names // nolint const ( - RestProposalID = "proposal-id" + RestProposalID = "proposalId" RestDepositer = "depositer" RestVoter = "voter" RestProposalStatus = "status" diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index 27921070e26e..c01c0db2b9a3 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -14,7 +14,7 @@ import ( func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) { r.HandleFunc( - "/slashing/signing_info/{validator}", + "/slashing/validators/{validatorPubKey}/signing_info", signingInfoHandlerFn(cliCtx, "slashing", cdc), ).Methods("GET") } @@ -25,7 +25,7 @@ func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *code return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - pk, err := sdk.GetConsPubKeyBech32(vars["validator"]) + pk, err := sdk.GetConsPubKeyBech32(vars["validatorPubKey"]) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -41,6 +41,11 @@ func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *code return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + var signingInfo slashing.ValidatorSigningInfo err = cdc.UnmarshalBinary(res, &signingInfo) diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 972d4351fadb..8e3056a14b22 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -17,7 +17,7 @@ import ( func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, kb keys.Keybase) { r.HandleFunc( - "/slashing/unjail", + "/slashing/validators/{validatorAddr}/unjail", unjailRequestHandlerFn(cdc, kb, cliCtx), ).Methods("POST") } @@ -25,11 +25,14 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec // Unjail TX body type UnjailReq struct { BaseReq utils.BaseReq `json:"base_req"` - ValidatorAddr string `json:"validator_addr"` } func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + bech32validator := vars["validatorAddr"] + var req UnjailReq err := utils.ReadRESTReq(w, r, cdc, &req) if err != nil { @@ -47,7 +50,7 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL return } - valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) + valAddr, err := sdk.ValAddressFromBech32(bech32validator) if err != nil { utils.WriteErrorResponse( w, http.StatusInternalServerError, From ba4eadd39cd24b8bb79439fe5bd2a1dd30ca7b62 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Thu, 11 Oct 2018 15:50:41 +0800 Subject: [PATCH 09/22] Add response model --- client/lcd/swagger-ui/swagger.yaml | 115 ++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 2adb4d71351d..dc926fc58cf6 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -140,7 +140,7 @@ paths: validators: type: array items: - $ref: "#/definitions/Validator" + $ref: "#/definitions/TendermintValidator" /validatorsets/{height}: get: summary: Get a validator set a certain height @@ -165,7 +165,7 @@ paths: validators: type: array items: - $ref: "#/definitions/Validator" + $ref: "#/definitions/TendermintValidator" 404: description: Block at height not available /txs/{hash}: @@ -701,6 +701,10 @@ paths: responses: 200: description: OK + schema: + type: array + items: + $ref: "#/definitions/Validator" 400: description: Invalid delegatorAddr 500: @@ -726,6 +730,8 @@ paths: responses: 200: description: OK + schema: + $ref: "#/definitions/Validator" 400: description: Invalid delegatorAddr or validatorAddr 500: @@ -814,6 +820,10 @@ paths: responses: 200: description: OK + schema: + type: array + items: + $ref: "#/definitions/Validator" 500: description: Internal Server Error /stake/validators/{validatorAddr}: @@ -832,6 +842,8 @@ paths: responses: 200: description: OK + schema: + $ref: "#/definitions/Validator" 500: description: Internal Server Error /stake/pool: @@ -844,6 +856,21 @@ paths: responses: 200: description: OK + schema: + type: object + properties: + loose_tokens: + type: string + bonded_tokens: + type: string + inflation_last_time: + type: string + inflation: + type: string + date_last_commission_reset: + type: string + prev_bonded_shares: + type: string 500: description: Internal Server Error /stake/parameters: @@ -856,6 +883,23 @@ paths: responses: 200: description: OK + schema: + type: object + properties: + inflation_rate_change: + type: string + inflation_max: + type: string + inflation_min: + type: string + goal_bonded: + type: string + unbonding_time: + type: string + max_validators: + type: integer + bond_denom: + type: string 500: description: Internal Server Error /slashing/validators/{validatorPubKey}/signing_info: @@ -875,6 +919,17 @@ paths: responses: 200: description: OK + schema: + type: object + properties: + start_height: + type: string + index_offset: + type: string + jailed_until: + type: string + signed_blocks_counter: + type: string 204: description: No sign info of this validator 500: @@ -1511,7 +1566,7 @@ definitions: gas_adjustment: type: string example: "1.2" - Validator: + TendermintValidator: type: object properties: address: @@ -1577,3 +1632,57 @@ definitions: type: integer option: type: string + Validator: + type: object + properties: + operator_address: + $ref: '#/definitions/ValidatorAddress' + consensus_pubkey: + type: string + example: cosmosvalconspub1zcjduepq7sjfglw7ra4mjxpw4ph7dtdhdheh7nz8dfgl6t8u2n5szuuql9mqsrwquu + jailed: + type: boolean + status: + type: integer + tokens: + type: string + delegator_shares: + type: string + description: + type: object + properties: + moniker: + type: string + identity: + type: string + website: + type: string + details: + type: string + bond_height: + type: string + example: '0' + bond_intra_tx_counter: + type: integer + example: 0 + unbonding_height: + type: string + example: '0' + unbonding_time: + type: string + example: '1970-01-01T00:00:00Z' + commission: + type: object + properties: + rate: + type: string + example: '0' + max_rate: + type: string + example: '0' + max_change_rate: + type: string + example: '0' + update_time: + type: string + example: '1970-01-01T00:00:00Z' From e050d8912168a13113ed6dbcffff4dcdbad10fd3 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 19 Oct 2018 09:46:44 +0800 Subject: [PATCH 10/22] Fix lcd test failure: TestUnjail --- client/lcd/lcd_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 7aea16d868c6..a2fc9ce10f6e 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -951,7 +951,7 @@ func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Acc } func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo { - res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/signing_info/%s", validatorPubKey), nil) + res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/validators/%s/signing_info", validatorPubKey), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var signingInfo slashing.ValidatorSigningInfo From 9db8dc2fa5cc63692582ab8acb0fbe75045de64e Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 19 Oct 2018 13:27:58 +0800 Subject: [PATCH 11/22] Add response mode and add error code for all query endpoints --- PENDING.md | 2 +- client/keys/show.go | 8 +- client/keys/utils.go | 17 +++ client/lcd/swagger-ui/swagger.yaml | 233 ++++++++++++++++++++++++----- client/rpc/block.go | 10 +- client/rpc/status.go | 6 +- client/rpc/validators.go | 10 +- client/tx/query.go | 2 +- client/tx/search.go | 8 +- client/utils/rest.go | 24 ++- x/auth/client/rest/sign.go | 8 +- x/bank/client/rest/sendtx.go | 2 +- x/gov/client/cli/tx.go | 15 +- x/gov/client/rest/rest.go | 60 +++++++- x/gov/client/utils.go | 48 ++++++ x/stake/client/rest/query.go | 45 ++++++ 16 files changed, 427 insertions(+), 71 deletions(-) create mode 100644 x/gov/client/utils.go diff --git a/PENDING.md b/PENDING.md index ca0c316bee65..5bb8b3907131 100644 --- a/PENDING.md +++ b/PENDING.md @@ -96,7 +96,7 @@ FEATURES * [gaia-lite] [\#966](https://github.com/cosmos/cosmos-sdk/issues/966) Add support for `generate_only=true` query argument to generate offline unsigned transactions * [gaia-lite] [\#1953](https://github.com/cosmos/cosmos-sdk/issues/1953) Add /sign endpoint to sign transactions generated with `generate_only=true`. * [gaia-lite] [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) Add /broadcast endpoint to broadcast transactions signed by the /sign endpoint. - * [gaia-lite] [\#2113](https://github.com/cosmos/cosmos-sdk/issues/2113) Rename `/accounts/{address}/send` to `/bank/accounts/{address}/transfers`, rename `/accounts/{address}` to `/auth/accounts/{address}` + * [gaia-lite] [\#2113](https://github.com/cosmos/cosmos-sdk/issues/2113) Rename `/accounts/{address}/send` to `/bank/accounts/{address}/transfers`, rename `/accounts/{address}` to `/auth/accounts/{address}`, replace `proposal-id` with `proposalId` in all gov endpoints * [gaia-lite] [\#2478](https://github.com/cosmos/cosmos-sdk/issues/2478) Add query gov proposal's deposits endpoint * Gaia CLI (`gaiacli`) diff --git a/client/keys/show.go b/client/keys/show.go index b567daf12435..7f5b7e92d7a0 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -108,12 +108,14 @@ func GetKeyRequestHandler(indent bool) http.HandlerFunc { } info, err := GetKeyInfo(name) - // TODO: check for the error if key actually does not exist, instead of - // assuming this as the reason - if err != nil { + if IsKeyNotFoundErr(err, name) { 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) diff --git a/client/keys/utils.go b/client/keys/utils.go index 4ca8fc8f4279..8c7503ab36bc 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "net/http" + "strings" ) // KeyDBName is the directory under root where we store the keys @@ -256,3 +257,19 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter w.Header().Set("Content-Type", "application/json") w.Write(output) } + +// IsKeyNotFoundErr - check if the error means that the specified key doesn't exist +func IsKeyNotFoundErr(err error, name string) bool { + if err != nil && strings.Contains(err.Error(), fmt.Sprintf("Key %s not found", name)) { + return true + } + return false +} + +// IsWrongKeyPasswordErr - check if the error means that the specified key password is wrong +func IsWrongKeyPasswordErr(err error) bool { + if err != nil && strings.Contains(err.Error(), "Ciphertext decryption failed") { + return true + } + return false +} \ No newline at end of file diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index aa150b0cc777..c7669af53ccb 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -33,7 +33,7 @@ paths: description: Get the version of gaia-lite running locally to compare against expected responses: 200: - description: Plaintext version i.e. "v0.5.0" + description: Plaintext version i.e. "v0.25.0" /node_version: get: summary: Version of the connected node @@ -42,7 +42,9 @@ paths: description: Get the version of the SDK running on the connected node to compare against expected responses: 200: - description: Plaintext version i.e. "v0.5.0" + description: Plaintext version i.e. "v0.25.0" + 500: + description: failed to query node version /node_info: get: description: Information about the connected node @@ -79,6 +81,8 @@ paths: type: array items: type: string + 500: + description: Failed to query node status /syncing: get: summary: Syncing state of node @@ -88,6 +92,8 @@ paths: responses: 200: description: '"true" or "false"' + 500: + description: Server internal error /blocks/latest: get: summary: Get the latest block @@ -100,6 +106,8 @@ paths: description: The latest block schema: $ref: "#/definitions/BlockQuery" + 500: + description: Server internal error /blocks/{height}: get: summary: Get a block at a certain height @@ -118,10 +126,12 @@ paths: description: The block at a specific height schema: $ref: "#/definitions/BlockQuery" + 404: + description: Request block height doesn't 400: description: Invalid height - 404: - description: Block at height is not available + 500: + description: Server internal error /validatorsets/latest: get: summary: Get the latest validator set @@ -141,6 +151,8 @@ paths: type: array items: $ref: "#/definitions/TendermintValidator" + 500: + description: Server internal error /validatorsets/{height}: get: summary: Get a validator set a certain height @@ -168,6 +180,10 @@ paths: $ref: "#/definitions/TendermintValidator" 404: description: Block at height not available + 400: + description: Invalid height + 500: + description: Server internal error /txs/{hash}: get: summary: Get a Tx by hash @@ -218,7 +234,7 @@ paths: items: $ref: "#/definitions/TxQuery" 400: - description: Invalid request + description: Invalid search tags 500: description: Internal Server Error post: @@ -290,8 +306,12 @@ paths: description: The signed Tx schema: $ref: "#/definitions/StdTx" + 400: + description: The Tx was malformated or key doesn't exist 401: - description: Account name and/or password where wrong + description: Key password is wrong + 500: + description: Server internal error /tx/broadcast: post: tags: @@ -319,6 +339,8 @@ paths: $ref: "#/definitions/BroadcastTxCommitResult" 400: description: The Tx was malformated + 500: + description: Server internal error /bank/balances/{address}: get: summary: Get the account balances @@ -340,7 +362,9 @@ paths: items: $ref: "#/definitions/Coin" 204: - description: There is no data for the requested account. This is not a 404 as the account might exist, just does not hold data. + description: There is no data for the requested account + 500: + description: Server internal error /bank/accounts/{address}/transfers: post: summary: Send coins (build -> sign -> send) @@ -386,7 +410,11 @@ paths: schema: $ref: "#/definitions/BroadcastTxCommitResult" 400: - description: The Tx was malformated + description: Invalid request + 401: + description: Key password is wrong + 500: + description: Server internal error /keys: get: summary: List of accounts stored locally @@ -401,6 +429,8 @@ paths: type: array items: $ref: '#/definitions/KeyOutput' + 500: + description: Server internal error post: summary: Create a new account locally tags: @@ -431,6 +461,12 @@ paths: 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 @@ -475,6 +511,12 @@ paths: 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 @@ -494,7 +536,7 @@ paths: schema: $ref: "#/definitions/KeyOutput" 404: - description: Account is not available + description: Key doesn't exist put: summary: Update the password for this account in the KMS tags: @@ -519,9 +561,9 @@ paths: 200: description: Updated password 401: - description: Password is wrong + description: Key password is wrong 404: - description: Account is not available + description: Key doesn't exist delete: summary: Remove an account tags: @@ -543,9 +585,9 @@ paths: 200: description: Removed account 401: - description: Password is wrong + description: Key password is wrong 404: - description: Account is not available + description: Key doesn't exist /auth/accounts/{address}: get: summary: Get the account information on blockchain @@ -584,6 +626,8 @@ paths: type: string 204: description: No content about this account address + 500: + description: Server internel error /stake/delegators/{delegatorAddr}/delegations: parameters: - in: path @@ -661,9 +705,9 @@ paths: schema: $ref: "#/definitions/BroadcastTxCommitResult" 400: - description: Invalid request + description: Invalid delegator address or delegation body 401: - description: Password is wrong + description: Key password is wrong 500: description: Internal Server Error /stake/delegators/{delegatorAddr}: @@ -682,8 +726,28 @@ paths: responses: 200: description: OK + schema: + type: object + properties: + redelegations: + type: array + items: + type: object + "$ref": "#/definitions/Redelegation" + unbonding_delegations: + type: array + items: + type: object + "$ref": "#/definitions/UnbondingDelegation" + delegations: + type: array + items: + type: object + "$ref": "#/definitions/Delegation" 400: - description: Invalid delegatorAddr + description: Invalid delegator address + 204: + description: No content 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/validators: @@ -706,8 +770,10 @@ paths: type: array items: $ref: "#/definitions/Validator" + 204: + description: No content 400: - description: Invalid delegatorAddr + description: Invalid delegator address 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/validators/{validatorAddr}: @@ -733,8 +799,10 @@ paths: description: OK schema: $ref: "#/definitions/Validator" + 204: + description: No content 400: - description: Invalid delegatorAddr or validatorAddr + description: Invalid delegator address or validator address 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/txs: @@ -757,8 +825,10 @@ paths: type: array items: $ref: "#/definitions/TxQuery" + 204: + description: No content 400: - description: Invalid delegatorAddr + description: Invalid delegator address 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}: @@ -774,7 +844,7 @@ paths: required: true type: string get: - summary: Query the current delegation status between a delegator and a validator + summary: Query the current delegation between a delegator and a validator tags: - ICS21 produces: @@ -782,8 +852,12 @@ paths: responses: 200: description: OK + schema: + $ref: "#/definitions/Delegation" + 204: + description: No content 400: - description: Invalid delegatorAddr or validatorAddr + description: Invalid delegator address or validator address 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: @@ -807,8 +881,15 @@ paths: responses: 200: description: OK + schema: + type: array + items: + type: object + "$ref": "#/definitions/UnbondingDelegation" + 204: + description: No content 400: - description: Invalid delegatorAddr or validatorAddr + description: Invalid delegator address or validator address 500: description: Internal Server Error /stake/validators: @@ -825,6 +906,8 @@ paths: type: array items: $ref: "#/definitions/Validator" + 204: + description: No content 500: description: Internal Server Error /stake/validators/{validatorAddr}: @@ -845,6 +928,10 @@ paths: description: OK schema: $ref: "#/definitions/Validator" + 204: + description: No content + 400: + description: Invalid validator address 500: description: Internal Server Error /stake/pool: @@ -872,6 +959,8 @@ paths: type: string prev_bonded_shares: type: string + 204: + description: No content 500: description: Internal Server Error /stake/parameters: @@ -901,6 +990,8 @@ paths: type: integer bond_denom: type: string + 204: + description: No content 500: description: Internal Server Error /slashing/validators/{validatorPubKey}/signing_info: @@ -933,6 +1024,8 @@ paths: type: string 204: description: No sign info of this validator + 400: + description: Invalid validator public key 500: description: Internal Server Error /slashing/validators/{validatorAddr}/unjail: @@ -975,6 +1068,10 @@ paths: description: OK schema: $ref: "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid validator address or base_req + 401: + description: Key password is wrong 500: description: Internal Server Error /gov/proposals: @@ -998,7 +1095,7 @@ paths: description: if true, build an unsigned transaction and write it back required: false type: boolean - - description: valid value of `"proposal_type"` can be `"Text"`, `"ParameterChange"`, `"SoftwareUpgrade"` + - description: valid value of `"proposal_type"` can be `"text"`, `"parameter_change"`, `"software_upgrade"` name: post_proposal_body in: body required: true @@ -1024,6 +1121,10 @@ paths: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid proposal body + 401: + description: Key password is wrong 500: description: Internal Server Error get: @@ -1046,7 +1147,7 @@ paths: type: string - in: query name: status - description: proposal status, valid values can be `"DepositPeriod"`, `"VotingPeriod"`, `"Passed"`, `"Rejected"` + description: proposal status, valid values can be `"deposit_period"`, `"voting_period"`, `"passed"`, `"rejected"` required: false type: string responses: @@ -1056,8 +1157,10 @@ paths: type: array items: "$ref": "#/definitions/TextProposal" + 204: + description: No content 400: - description: Invalid request + description: Invalid query parameters 500: description: Internal Server Error /gov/proposals/{proposalId}/deposits: @@ -1087,7 +1190,7 @@ paths: required: true in: path - description: '' - name: deposit_body + name: post_deposit_body in: body required: true schema: @@ -1106,6 +1209,10 @@ paths: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid proposal id or deposite body + 401: + description: Key password is wrong 500: description: Internal Server Error /gov/proposals/{proposalId}/votes: @@ -1134,8 +1241,8 @@ paths: name: proposalId required: true in: path - - description: valid value of `"option"` field can be `"Yes"`, `"No"`, `"NoWithVeto"` and `"Abstain"` - name: voteBody + - description: valid value of `"option"` field can be `"yes"`, `"no"`, `"no_with_veto"` and `"abstain"` + name: post_vote_body in: body required: true schema: @@ -1152,6 +1259,10 @@ paths: description: OK schema: "$ref": "#/definitions/BroadcastTxCommitResult" + 400: + description: Invalid proposal id or vote body + 401: + description: Key password is wrong 500: description: Internal Server Error get: @@ -1174,8 +1285,10 @@ paths: type: array items: "$ref": "#/definitions/Vote" + 204: + description: No content 400: - description: Invalid request + description: Invalid proposal id 500: description: Internal Server Error /gov/proposals/{proposalId}: @@ -1196,10 +1309,10 @@ paths: description: OK schema: "$ref": "#/definitions/TextProposal" + 204: + description: No content 400: - description: Invalid request - 404: - description: Found no proposal + description: Invalid proposal id 500: description: Internal Server Error /gov/proposals/{proposalId}/deposits/{depositer}: @@ -1226,8 +1339,10 @@ paths: description: OK schema: $ref: "#/definitions/Deposite" + 204: + description: No content 400: - description: Invalid request + description: Invalid proposal id or depositer address 404: description: Found no deposite 500: @@ -1256,8 +1371,10 @@ paths: description: OK schema: $ref: "#/definitions/Vote" + 204: + description: No content 400: - description: Invalid request + description: Invalid proposal id or voter address 404: description: Found no vote 500: @@ -1553,6 +1670,7 @@ definitions: type: string password: type: string + example: "12345678" chain_id: type: string account_number: @@ -1687,3 +1805,50 @@ definitions: update_time: type: string example: '1970-01-01T00:00:00Z' + Delegation: + type: object + properties: + delegator_addr: + type: string + validator_addr: + type: string + shares: + type: string + height: + type: integer + UnbondingDelegation: + type: object + properties: + delegator_addr: + type: string + validator_addr: + type: string + initial_balance: + type: string + balance: + type: string + creation_height: + type: integer + min_time: + type: integer + Redelegation: + type: object + properties: + delegator_addr: + type: string + validator_src_addr: + type: string + validator_dst_addr: + type: string + creation_height: + type: integer + min_time: + type: integer + initial_balance: + type: string + balance: + type: string + shares_src: + type: string + shares_dst: + type: string diff --git a/client/rpc/block.go b/client/rpc/block.go index 1090fd2d25d9..b2db545dbdd1 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -115,19 +115,19 @@ func BlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { vars := mux.Vars(r) height, err := strconv.ParseInt(vars["height"], 10, 64) if err != nil { - w.WriteHeader(400) + w.WriteHeader(http.StatusBadRequest) w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/block/{height}'.")) return } chainHeight, err := GetChainHeight(cliCtx) if height > chainHeight { - w.WriteHeader(404) + w.WriteHeader(http.StatusNotFound) w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) return } output, err := getBlock(cliCtx, &height) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } @@ -140,13 +140,13 @@ func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight(cliCtx) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } output, err := getBlock(cliCtx, &height) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } diff --git a/client/rpc/status.go b/client/rpc/status.go index 7f3494216024..68716f3a0b75 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -69,7 +69,7 @@ func NodeInfoRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus(cliCtx) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } @@ -84,14 +84,14 @@ func NodeSyncingRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus(cliCtx) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } syncing := status.SyncInfo.CatchingUp if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } diff --git a/client/rpc/validators.go b/client/rpc/validators.go index fc37881cba92..330966bf874f 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -140,21 +140,21 @@ func ValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { height, err := strconv.ParseInt(vars["height"], 10, 64) if err != nil { - w.WriteHeader(400) + w.WriteHeader(http.StatusBadRequest) w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/validatorsets/{height}'.")) return } chainHeight, err := GetChainHeight(cliCtx) if height > chainHeight { - w.WriteHeader(404) + w.WriteHeader(http.StatusNotFound) w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) return } output, err := getValidators(cliCtx, &height) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } @@ -167,14 +167,14 @@ func LatestValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerF return func(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight(cliCtx) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } output, err := getValidators(cliCtx, &height) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } diff --git a/client/tx/query.go b/client/tx/query.go index ec7daf41b4f8..3e7da623a348 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -142,7 +142,7 @@ func QueryTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.H output, err := queryTx(cdc, cliCtx, hashHexStr) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } diff --git a/client/tx/search.go b/client/tx/search.go index 672df0e339f2..930466a6dd15 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -141,7 +141,7 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http. return func(w http.ResponseWriter, r *http.Request) { tag := r.FormValue("tag") if tag == "" { - w.WriteHeader(400) + w.WriteHeader(http.StatusBadRequest) w.Write([]byte("You need to provide at least a tag as a key=value pair to search for. Postfix the key with _bech32 to search bech32-encoded addresses or public keys")) return } @@ -151,7 +151,7 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http. value, err := url.QueryUnescape(keyValue[1]) if err != nil { - w.WriteHeader(400) + w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Could not decode address: " + err.Error())) return } @@ -161,7 +161,7 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http. prefix := strings.Split(bech32address, "1")[0] bz, err := sdk.GetFromBech32(bech32address, prefix) if err != nil { - w.WriteHeader(400) + w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } @@ -171,7 +171,7 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http. txs, err := searchTxs(cliCtx, cdc, []string{tag}) if err != nil { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } diff --git a/client/utils/rest.go b/client/utils/rest.go index effb7bb73776..277cf329d53a 100644 --- a/client/utils/rest.go +++ b/client/utils/rest.go @@ -229,7 +229,13 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c } txBytes, err := txBldr.BuildAndSign(baseReq.Name, baseReq.Password, msgs) - if err != nil { + if IsKeyNotFoundErr(err, baseReq.Name) { + WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } else if IsWrongKeyPasswordErr(err) { + WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + return + } else if err != nil { WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) return } @@ -264,3 +270,19 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter w.Header().Set("Content-Type", "application/json") w.Write(output) } + +// IsKeyNotFoundErr - check if the error means that the specified key doesn't exist +func IsKeyNotFoundErr(err error, name string) bool { + if err != nil && strings.Contains(err.Error(), fmt.Sprintf("Key %s not found", name)) { + return true + } + return false +} + +// IsWrongKeyPasswordErr - check if the error means that the specified key password is wrong +func IsWrongKeyPasswordErr(err error) bool { + if err != nil && strings.Contains(err.Error(), "Ciphertext decryption failed") { + return true + } + return false +} \ No newline at end of file diff --git a/x/auth/client/rest/sign.go b/x/auth/client/rest/sign.go index 9e9b92b5ade1..0347982edc27 100644 --- a/x/auth/client/rest/sign.go +++ b/x/auth/client/rest/sign.go @@ -47,7 +47,13 @@ func SignTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha } signedTx, err := txBldr.SignStdTx(m.LocalAccountName, m.Password, m.Tx, m.AppendSig) - if err != nil { + if utils.IsKeyNotFoundErr(err, m.LocalAccountName) { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } else if utils.IsWrongKeyPasswordErr(err) { + utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + return + } else if err != nil { utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index a06cf58460da..7bb2640fddfd 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -56,7 +56,7 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC info, err := kb.Get(baseReq.Name) if err != nil { - utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 23e95105e0ed..eebcda882faf 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -17,6 +17,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/x/gov/client" ) const ( @@ -115,7 +116,7 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome cmd.Flags().String(flagTitle, "", "title of proposal") cmd.Flags().String(flagDescription, "", "description of proposal") - cmd.Flags().String(flagProposalType, "", "proposalType of proposal") + cmd.Flags().String(flagProposalType, "", "proposalType of proposal, types: text/parameter_change/software_upgrade") cmd.Flags().String(flagDeposit, "", "deposit of proposal") cmd.Flags().String(flagProposal, "", "proposal file path (if this path is given, other proposal flags are ignored)") @@ -129,7 +130,7 @@ func parseSubmitProposalFlags() (*proposal, error) { if proposalFile == "" { proposal.Title = viper.GetString(flagTitle) proposal.Description = viper.GetString(flagDescription) - proposal.Type = viper.GetString(flagProposalType) + proposal.Type = client.NormalizeProposalType(viper.GetString(flagProposalType)) proposal.Deposit = viper.GetString(flagDeposit) return proposal, nil } @@ -202,7 +203,7 @@ func GetCmdDeposit(cdc *codec.Codec) *cobra.Command { func GetCmdVote(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "vote", - Short: "Vote for an active proposal, options: Yes/No/NoWithVeto/Abstain", + Short: "Vote for an active proposal, options: yes/no/no_with_veto/abstain", RunE: func(cmd *cobra.Command, args []string) error { txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc) cliCtx := context.NewCLIContext(). @@ -217,7 +218,7 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command { proposalID := viper.GetInt64(flagProposalID) option := viper.GetString(flagOption) - byteVoteOption, err := gov.VoteOptionFromString(option) + byteVoteOption, err := gov.VoteOptionFromString(client.NormalizeVoteOption(option)) if err != nil { return err } @@ -243,7 +244,7 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command { } cmd.Flags().String(flagProposalID, "", "proposalID of proposal voting on") - cmd.Flags().String(flagOption, "", "vote option {Yes, No, NoWithVeto, Abstain}") + cmd.Flags().String(flagOption, "", "vote option {yes, no, no_with_veto, abstain}") return cmd } @@ -313,7 +314,7 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command { } if len(strProposalStatus) != 0 { - proposalStatus, err := gov.ProposalStatusFromString(strProposalStatus) + proposalStatus, err := gov.ProposalStatusFromString(client.NormalizeProposalStatus(strProposalStatus)) if err != nil { return err } @@ -354,7 +355,7 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd.Flags().String(flagLatestProposalIDs, "", "(optional) limit to latest [number] proposals. Defaults to all proposals") cmd.Flags().String(flagDepositer, "", "(optional) filter by proposals deposited on by depositer") cmd.Flags().String(flagVoter, "", "(optional) filter by proposals voted on by voted") - cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status") + cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status, status: deposit_period/voting_period/passed/rejected") return cmd } diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index dd087a5a6dff..ab65622901e1 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/mux" "github.com/pkg/errors" + "github.com/cosmos/cosmos-sdk/x/gov/client" ) // REST Variable names @@ -43,7 +44,7 @@ type postProposalReq struct { BaseReq utils.BaseReq `json:"base_req"` Title string `json:"title"` // Title of the proposal Description string `json:"description"` // Description of the proposal - ProposalType gov.ProposalKind `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal} + 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 } @@ -57,7 +58,7 @@ type depositReq struct { type voteReq struct { BaseReq utils.BaseReq `json:"base_req"` Voter sdk.AccAddress `json:"voter"` // address of the voter - Option gov.VoteOption `json:"option"` // option from OptionSet chosen by the voter + Option string `json:"option"` // option from OptionSet chosen by the voter } func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { @@ -65,6 +66,7 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han var req postProposalReq err := utils.ReadRESTReq(w, r, cdc, &req) if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } @@ -73,8 +75,14 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } + proposalType, err := gov.ProposalTypeFromString(client.NormalizeProposalType(req.ProposalType)) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + // create the message - msg := gov.NewMsgSubmitProposal(req.Title, req.Description, req.ProposalType, req.Proposer, req.InitialDeposit) + msg := gov.NewMsgSubmitProposal(req.Title, req.Description, proposalType, req.Proposer, req.InitialDeposit) err = msg.ValidateBasic() if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -151,8 +159,14 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc return } + voteOption, err := gov.VoteOptionFromString(client.NormalizeVoteOption(req.Option)) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + // create the message - msg := gov.NewMsgVote(req.Voter, proposalID, req.Option) + msg := gov.NewMsgVote(req.Voter, proposalID, voteOption) err = msg.ValidateBasic() if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -195,6 +209,11 @@ func queryProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -225,6 +244,11 @@ func queryDepositsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -276,6 +300,11 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + var deposit gov.Deposit cdc.UnmarshalJSON(res, &deposit) if deposit.Empty() { @@ -340,6 +369,11 @@ func queryVoteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Handle return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + var vote gov.Vote cdc.UnmarshalJSON(res, &vote) if vote.Empty() { @@ -394,6 +428,11 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -429,7 +468,7 @@ func queryProposalsWithParameterFn(cdc *codec.Codec, cliCtx context.CLIContext) } if len(strProposalStatus) != 0 { - proposalStatus, err := gov.ProposalStatusFromString(strProposalStatus) + proposalStatus, err := gov.ProposalStatusFromString(client.NormalizeProposalStatus(strProposalStatus)) if err != nil { err := errors.Errorf("'%s' is not a valid Proposal Status", strProposalStatus) utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -456,6 +495,12 @@ func queryProposalsWithParameterFn(cdc *codec.Codec, cliCtx context.CLIContext) utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } + + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -496,6 +541,11 @@ func queryTallyOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } diff --git a/x/gov/client/utils.go b/x/gov/client/utils.go new file mode 100644 index 000000000000..a656c1687852 --- /dev/null +++ b/x/gov/client/utils.go @@ -0,0 +1,48 @@ +package client + +// NormalizeVoteOption - normalize user specified vote option +func NormalizeVoteOption(option string) string { + switch option { + case "yes": + return "Yes" + case "abstain": + return "Abstain" + case "no": + return "No" + case "no_with_veto": + return "NoWithVeto" + default: + return "" + } +} + +//NormalizeProposalType - normalize user specified proposal type +func NormalizeProposalType(proposalType string) string { + switch proposalType { + case "text": + return "Text" + case "parameter_change": + return "ParameterChange" + case "software_upgrade": + return "SoftwareUpgrade" + default: + return "" + } +} + +//NormalizeProposalStatus - normalize user specified proposal status +func NormalizeProposalStatus(status string) string { + switch status { + case "deposit_period": + return "DepositPeriod" + case "voting_period": + return "VotingPeriod" + case "passed": + return "Passed" + case "rejected": + return "Rejected" + default: + return "" + } +} + diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index a8fbfecf4d76..7e2b5c1d524d 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -116,6 +116,11 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -241,6 +246,11 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -289,6 +299,11 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handl return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -328,6 +343,11 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -370,6 +390,11 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) ht return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -388,6 +413,11 @@ func validatorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Header().Set("Content-Type", "application/json") w.Write(res) } @@ -428,6 +458,11 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -446,6 +481,11 @@ func poolHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } @@ -464,6 +504,11 @@ func paramsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + w.Write(res) } } From 5270da65886c3e1be070353579168864e18d40a0 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 19 Oct 2018 14:46:17 +0800 Subject: [PATCH 12/22] fix ci test failure --- client/utils/rest.go | 2 +- x/gov/client/utils.go | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/client/utils/rest.go b/client/utils/rest.go index 277cf329d53a..2a71c57326d9 100644 --- a/client/utils/rest.go +++ b/client/utils/rest.go @@ -285,4 +285,4 @@ func IsWrongKeyPasswordErr(err error) bool { return true } return false -} \ No newline at end of file +} diff --git a/x/gov/client/utils.go b/x/gov/client/utils.go index a656c1687852..a272ad00933d 100644 --- a/x/gov/client/utils.go +++ b/x/gov/client/utils.go @@ -4,45 +4,53 @@ package client func NormalizeVoteOption(option string) string { switch option { case "yes": + case "Yes": return "Yes" case "abstain": + case "Abstain": return "Abstain" case "no": + case "No": return "No" case "no_with_veto": + case "NoWithVeto": return "NoWithVeto" - default: - return "" } + return "" } //NormalizeProposalType - normalize user specified proposal type func NormalizeProposalType(proposalType string) string { switch proposalType { case "text": + case "Text": return "Text" case "parameter_change": + case "ParameterChange": return "ParameterChange" case "software_upgrade": + case "SoftwareUpgrade": return "SoftwareUpgrade" - default: - return "" } + return "" } //NormalizeProposalStatus - normalize user specified proposal status func NormalizeProposalStatus(status string) string { switch status { case "deposit_period": + case "DepositPeriod": return "DepositPeriod" case "voting_period": + case "VotingPeriod": return "VotingPeriod" case "passed": + case "Passed": return "Passed" case "rejected": + case "Rejected": return "Rejected" - default: - return "" } + return "" } From 6ec2d88288941cd5dafabcba16362a34ad229ad8 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 19 Oct 2018 23:47:31 +0800 Subject: [PATCH 13/22] Resolve some spell error, add missing gov endpoint and modify swagger title --- client/lcd/swagger-ui/swagger.yaml | 46 +++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index c7669af53ccb..08a8bfe9cff2 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -2,8 +2,8 @@ swagger: '2.0' info: version: 1.1.0 - title: Gaia-Lite (former LCD) to interface with Cosmos BaseServer via REST - description: Specification for Gaia-lite provided by `gaiacli rest-server` + title: Gaia-Lite for Cosmos + description: A REST interface for state queries, transaction generation, signing, and broadcast. tags: - name: ICS0 description: Tendermint APIs, such as query blocks, transactions and validatorset @@ -474,10 +474,10 @@ paths: - ICS1 responses: 200: - description: 16 word Seed + 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 + 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 @@ -1210,7 +1210,7 @@ paths: schema: "$ref": "#/definitions/BroadcastTxCommitResult" 400: - description: Invalid proposal id or deposite body + description: Invalid proposal id or deposit body 401: description: Key password is wrong 500: @@ -1315,6 +1315,32 @@ paths: description: Invalid proposal id 500: description: Internal Server Error + /gov/proposal/{proposalId}/deposits: + get: + summary: Query deposits + description: Query deposits by proposalId + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + type: array + items: + "$ref": "#/definitions/TextProposal" + 204: + description: No content + 400: + description: Invalid proposal id + 500: + description: Internal Server Error /gov/proposals/{proposalId}/deposits/{depositer}: get: summary: Query deposit @@ -1338,13 +1364,13 @@ paths: 200: description: OK schema: - $ref: "#/definitions/Deposite" + $ref: "#/definitions/Deposit" 204: description: No content 400: description: Invalid proposal id or depositer address 404: - description: Found no deposite + description: Found no deposit 500: description: Internal Server Error /gov/proposals/{proposalId}/votes/{voter}: @@ -1723,15 +1749,15 @@ definitions: type: string no_with_veto: type: string - submit_block: + submit_time: type: string total_deposit: type: array items: "$ref": "#/definitions/Coin" - voting_start_block: + voting_start_time: type: string - Deposite: + Deposit: type: object properties: amount: From 9136254c15326bdeb7f5102e3ebfdd19475b6e9f Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 00:15:15 +0800 Subject: [PATCH 14/22] Fix wrong response body --- client/lcd/swagger-ui/swagger.yaml | 51 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 08a8bfe9cff2..dd953d112e46 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -1215,6 +1215,31 @@ paths: description: Key password is wrong 500: description: Internal Server Error + get: + summary: Query deposits + description: Query deposits by proposalId + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + type: array + items: + "$ref": "#/definitions/Deposit" + 204: + description: No content + 400: + description: Invalid proposal id + 500: + description: Internal Server Error /gov/proposals/{proposalId}/votes: post: summary: Vote a proposal @@ -1315,32 +1340,6 @@ paths: description: Invalid proposal id 500: description: Internal Server Error - /gov/proposal/{proposalId}/deposits: - get: - summary: Query deposits - description: Query deposits by proposalId - produces: - - application/json - tags: - - ICS22 - parameters: - - type: string - name: proposalId - required: true - in: path - responses: - 200: - description: OK - schema: - type: array - items: - "$ref": "#/definitions/TextProposal" - 204: - description: No content - 400: - description: Invalid proposal id - 500: - description: Internal Server Error /gov/proposals/{proposalId}/deposits/{depositer}: get: summary: Query deposit From 131e0ca676c96247de28ea5bed48d541c4c7a23f Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 00:19:45 +0800 Subject: [PATCH 15/22] Resolve inconsistence between swagger.yaml and code implementation --- client/lcd/swagger-ui/swagger.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index dd953d112e46..dda425feefef 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -1020,7 +1020,7 @@ paths: type: string jailed_until: type: string - signed_blocks_counter: + missed_blocks_counter: type: string 204: description: No sign info of this validator @@ -1623,6 +1623,8 @@ definitions: $ref: "#/definitions/Hash" validators_hash: $ref: "#/definitions/Hash" + next_validators_hash: + $ref: "#/definitions/Hash" consensus_hash: $ref: "#/definitions/Hash" app_hash: @@ -1631,6 +1633,8 @@ definitions: $ref: "#/definitions/Hash" evidence_hash: $ref: "#/definitions/Hash" + proposer_address: + $ref: "#/definitions/Address" Block: type: object properties: From eb7d3df84e1b2914f9ec4a291e7b3c32ec16acc3 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 09:04:06 +0800 Subject: [PATCH 16/22] Update swagger.yaml to accommodate handler implementation changes --- client/lcd/swagger-ui/swagger.yaml | 32 +----------------------------- x/gov/client/rest/rest.go | 20 ------------------- x/slashing/client/rest/query.go | 1 - 3 files changed, 1 insertion(+), 52 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index dda425feefef..0fd838f64398 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -746,8 +746,6 @@ paths: "$ref": "#/definitions/Delegation" 400: description: Invalid delegator address - 204: - description: No content 500: description: Internal Server Error /stake/delegators/{delegatorAddr}/validators: @@ -770,8 +768,6 @@ paths: type: array items: $ref: "#/definitions/Validator" - 204: - description: No content 400: description: Invalid delegator address 500: @@ -799,8 +795,6 @@ paths: description: OK schema: $ref: "#/definitions/Validator" - 204: - description: No content 400: description: Invalid delegator address or validator address 500: @@ -826,7 +820,7 @@ paths: items: $ref: "#/definitions/TxQuery" 204: - description: No content + description: No staking transaction about this delegator address 400: description: Invalid delegator address 500: @@ -854,8 +848,6 @@ paths: description: OK schema: $ref: "#/definitions/Delegation" - 204: - description: No content 400: description: Invalid delegator address or validator address 500: @@ -886,8 +878,6 @@ paths: items: type: object "$ref": "#/definitions/UnbondingDelegation" - 204: - description: No content 400: description: Invalid delegator address or validator address 500: @@ -906,8 +896,6 @@ paths: type: array items: $ref: "#/definitions/Validator" - 204: - description: No content 500: description: Internal Server Error /stake/validators/{validatorAddr}: @@ -928,8 +916,6 @@ paths: description: OK schema: $ref: "#/definitions/Validator" - 204: - description: No content 400: description: Invalid validator address 500: @@ -959,8 +945,6 @@ paths: type: string prev_bonded_shares: type: string - 204: - description: No content 500: description: Internal Server Error /stake/parameters: @@ -990,8 +974,6 @@ paths: type: integer bond_denom: type: string - 204: - description: No content 500: description: Internal Server Error /slashing/validators/{validatorPubKey}/signing_info: @@ -1157,8 +1139,6 @@ paths: type: array items: "$ref": "#/definitions/TextProposal" - 204: - description: No content 400: description: Invalid query parameters 500: @@ -1234,8 +1214,6 @@ paths: type: array items: "$ref": "#/definitions/Deposit" - 204: - description: No content 400: description: Invalid proposal id 500: @@ -1310,8 +1288,6 @@ paths: type: array items: "$ref": "#/definitions/Vote" - 204: - description: No content 400: description: Invalid proposal id 500: @@ -1334,8 +1310,6 @@ paths: description: OK schema: "$ref": "#/definitions/TextProposal" - 204: - description: No content 400: description: Invalid proposal id 500: @@ -1364,8 +1338,6 @@ paths: description: OK schema: $ref: "#/definitions/Deposit" - 204: - description: No content 400: description: Invalid proposal id or depositer address 404: @@ -1396,8 +1368,6 @@ paths: description: OK schema: $ref: "#/definitions/Vote" - 204: - description: No content 400: description: Invalid proposal id or voter address 404: diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index fb7641259bf3..882dcf0e1b55 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -209,11 +209,6 @@ func queryProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha return } - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -244,11 +239,6 @@ func queryDepositsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha return } - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } @@ -299,11 +289,6 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - var deposit gov.Deposit cdc.UnmarshalJSON(res, &deposit) if deposit.Empty() { @@ -367,11 +352,6 @@ func queryVoteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Handle return } - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - var vote gov.Vote cdc.UnmarshalJSON(res, &vote) if vote.Empty() { diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index f988463c05bd..8beab13adfbf 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -4,7 +4,6 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/slashing" From 2b267fcf83f69b6e603db98e87ed7b9335ba4a22 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 09:24:38 +0800 Subject: [PATCH 17/22] Fix bug in normalize gov parameters --- x/gov/client/utils.go | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/x/gov/client/utils.go b/x/gov/client/utils.go index a272ad00933d..8dcde5c62e97 100644 --- a/x/gov/client/utils.go +++ b/x/gov/client/utils.go @@ -3,17 +3,13 @@ package client // NormalizeVoteOption - normalize user specified vote option func NormalizeVoteOption(option string) string { switch option { - case "yes": - case "Yes": + case "Yes", "yes": return "Yes" - case "abstain": - case "Abstain": + case "Abstain", "abstain": return "Abstain" - case "no": - case "No": + case "No", "no": return "No" - case "no_with_veto": - case "NoWithVeto": + case "NoWithVeto", "no_with_veto": return "NoWithVeto" } return "" @@ -22,14 +18,11 @@ func NormalizeVoteOption(option string) string { //NormalizeProposalType - normalize user specified proposal type func NormalizeProposalType(proposalType string) string { switch proposalType { - case "text": - case "Text": + case "Text", "text": return "Text" - case "parameter_change": - case "ParameterChange": + case "ParameterChange", "parameter_change": return "ParameterChange" - case "software_upgrade": - case "SoftwareUpgrade": + case "SoftwareUpgrade", "software_upgrade": return "SoftwareUpgrade" } return "" @@ -38,17 +31,13 @@ func NormalizeProposalType(proposalType string) string { //NormalizeProposalStatus - normalize user specified proposal status func NormalizeProposalStatus(status string) string { switch status { - case "deposit_period": - case "DepositPeriod": + case "DepositPeriod", "deposit_period": return "DepositPeriod" - case "voting_period": - case "VotingPeriod": + case "VotingPeriod", "voting_period": return "VotingPeriod" - case "passed": - case "Passed": + case "Passed", "passed": return "Passed" - case "rejected": - case "Rejected": + case "Rejected", "rejected": return "Rejected" } return "" From 8363685794a28f88169144629c3b5cbf85fd6bcc Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 09:30:26 +0800 Subject: [PATCH 18/22] Add example value to proposal type and vote option --- client/lcd/swagger-ui/swagger.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 0fd838f64398..b5dcc4a1d03e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -1092,6 +1092,7 @@ paths: type: string proposal_type: type: string + example: "text" proposer: "$ref": "#/definitions/Address" initial_deposit: @@ -1257,6 +1258,7 @@ paths: "$ref": "#/definitions/Address" option: type: string + example: "yes" responses: 200: description: OK From 88b4c66907a321b2768b2e59a57f913d72d56f64 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Sat, 20 Oct 2018 09:48:01 +0800 Subject: [PATCH 19/22] Improve error handler in delete and update key --- client/keys/delete.go | 11 +++++++++-- client/keys/update.go | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/client/keys/delete.go b/client/keys/delete.go index 23fc41ffd6ae..1af61e39081a 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -80,9 +80,16 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) { return } - // TODO handle error if key is not available or pass is wrong err = kb.Delete(name, m.Password) - if err != nil { + if IsKeyNotFoundErr(err, name) { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(err.Error())) + return + } else if IsWrongKeyPasswordErr(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 diff --git a/client/keys/update.go b/client/keys/update.go index 9416e9b0b45a..860d18857c60 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -83,12 +83,19 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) { getNewpass := func() (string, error) { return m.NewPassword, nil } - // TODO check if account exists and if password is correct err = kb.Update(name, m.OldPassword, getNewpass) - if err != nil { + if IsKeyNotFoundErr(err, name) { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(err.Error())) + return + } else if IsWrongKeyPasswordErr(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") From 8045d49860fc5a021009b0795597e6e7e1ad8cf6 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Tue, 23 Oct 2018 11:00:33 +0800 Subject: [PATCH 20/22] Implement error type in key base --- client/keys/delete.go | 5 ++- client/keys/show.go | 3 +- client/keys/update.go | 5 ++- client/keys/utils.go | 17 ------- client/utils/rest.go | 23 ++-------- crypto/keys/keybase.go | 3 +- crypto/keys/keyerror/errors.go | 81 ++++++++++++++++++++++++++++++++++ crypto/keys/mintkey/mintkey.go | 5 ++- x/auth/client/rest/sign.go | 5 ++- 9 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 crypto/keys/keyerror/errors.go diff --git a/client/keys/delete.go b/client/keys/delete.go index 1af61e39081a..66e5ff367da2 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" keys "github.com/cosmos/cosmos-sdk/crypto/keys" + keyerror "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -81,11 +82,11 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) { } err = kb.Delete(name, m.Password) - if IsKeyNotFoundErr(err, name) { + if keyerror.IsErrKeyNotFound(err) { w.WriteHeader(http.StatusNotFound) w.Write([]byte(err.Error())) return - } else if IsWrongKeyPasswordErr(err) { + } else if keyerror.IsErrWrongPassword(err) { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(err.Error())) return diff --git a/client/keys/show.go b/client/keys/show.go index 7f5b7e92d7a0..71123e7da77d 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/cli" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) const ( @@ -108,7 +109,7 @@ func GetKeyRequestHandler(indent bool) http.HandlerFunc { } info, err := GetKeyInfo(name) - if IsKeyNotFoundErr(err, name) { + if keyerror.IsErrKeyNotFound(err) { w.WriteHeader(http.StatusNotFound) w.Write([]byte(err.Error())) return diff --git a/client/keys/update.go b/client/keys/update.go index 860d18857c60..334fd258090c 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -10,6 +10,7 @@ import ( "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) func updateKeyCommand() *cobra.Command { @@ -84,11 +85,11 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) { getNewpass := func() (string, error) { return m.NewPassword, nil } err = kb.Update(name, m.OldPassword, getNewpass) - if IsKeyNotFoundErr(err, name) { + if keyerror.IsErrKeyNotFound(err) { w.WriteHeader(http.StatusNotFound) w.Write([]byte(err.Error())) return - } else if IsWrongKeyPasswordErr(err) { + } else if keyerror.IsErrWrongPassword(err) { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(err.Error())) return diff --git a/client/keys/utils.go b/client/keys/utils.go index 8c7503ab36bc..4ca8fc8f4279 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -15,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "net/http" - "strings" ) // KeyDBName is the directory under root where we store the keys @@ -257,19 +256,3 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter w.Header().Set("Content-Type", "application/json") w.Write(output) } - -// IsKeyNotFoundErr - check if the error means that the specified key doesn't exist -func IsKeyNotFoundErr(err error, name string) bool { - if err != nil && strings.Contains(err.Error(), fmt.Sprintf("Key %s not found", name)) { - return true - } - return false -} - -// IsWrongKeyPasswordErr - check if the error means that the specified key password is wrong -func IsWrongKeyPasswordErr(err error) bool { - if err != nil && strings.Contains(err.Error(), "Ciphertext decryption failed") { - return true - } - return false -} \ No newline at end of file diff --git a/client/utils/rest.go b/client/utils/rest.go index 8d3af9c04211..e9d948514720 100644 --- a/client/utils/rest.go +++ b/client/utils/rest.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "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/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" @@ -229,14 +230,14 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c } txBytes, err := txBldr.BuildAndSign(baseReq.Name, baseReq.Password, msgs) - if IsKeyNotFoundErr(err, baseReq.Name) { + if keyerror.IsErrKeyNotFound(err) { WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return - } else if IsWrongKeyPasswordErr(err) { + } else if keyerror.IsErrWrongPassword(err) { WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) return } else if err != nil { - WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } @@ -270,19 +271,3 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter w.Header().Set("Content-Type", "application/json") w.Write(output) } - -// IsKeyNotFoundErr - check if the error means that the specified key doesn't exist -func IsKeyNotFoundErr(err error, name string) bool { - if err != nil && strings.Contains(err.Error(), fmt.Sprintf("Key %s not found", name)) { - return true - } - return false -} - -// IsWrongKeyPasswordErr - check if the error means that the specified key password is wrong -func IsWrongKeyPasswordErr(err error) bool { - if err != nil && strings.Contains(err.Error(), "Ciphertext decryption failed") { - return true - } - return false -} diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index ddcd0357e1a3..a97a5d72e354 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -19,6 +19,7 @@ import ( "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) var _ Keybase = dbKeybase{} @@ -217,7 +218,7 @@ func (kb dbKeybase) List() ([]Info, error) { func (kb dbKeybase) Get(name string) (Info, error) { bs := kb.db.Get(infoKey(name)) if len(bs) == 0 { - return nil, fmt.Errorf("Key %s not found", name) + return nil, keyerror.NewErrKeyNotFound(name) } return readInfo(bs) } diff --git a/crypto/keys/keyerror/errors.go b/crypto/keys/keyerror/errors.go new file mode 100644 index 000000000000..1042689e3891 --- /dev/null +++ b/crypto/keys/keyerror/errors.go @@ -0,0 +1,81 @@ +package keyerror + +import ( + "fmt" +) + +const ( + codeKeyNotFound = 1 + codeWrongPassword = 2 +) + +type keybaseError interface { + error + Code() int +} + +type errKeyNotFound struct { + code int + name string +} + +func (e errKeyNotFound) Code() int { + return e.code +} + +func (e errKeyNotFound) Error() string { + return fmt.Sprintf("Key %s not found", e.name) +} + +// NewErrKeyNotFound returns a standardized error reflecting that the specified key doesn't exist +func NewErrKeyNotFound(name string) error { + return errKeyNotFound{ + code: codeKeyNotFound, + name: name, + } +} + +// IsErrKeyNotFound returns true if the given error is errKeyNotFound +func IsErrKeyNotFound(err error) bool { + if err == nil { + return false + } + if keyErr, ok := err.(keybaseError); ok { + if keyErr.Code() == codeKeyNotFound { + return true + } + } + return false +} + +type errWrongPassword struct { + code int +} + +func (e errWrongPassword) Code() int { + return e.code +} + +func (e errWrongPassword) Error() string { + return fmt.Sprintf("Ciphertext decryption failed") +} + +// NewErrWrongPassword returns a standardized error reflecting that the specified password is wrong +func NewErrWrongPassword() error { + return errWrongPassword{ + code: codeWrongPassword, + } +} + +// IsErrWrongPassword returns true if the given error is errWrongPassword +func IsErrWrongPassword(err error) bool { + if err == nil { + return false + } + if keyErr, ok := err.(keybaseError); ok { + if keyErr.Code() == codeWrongPassword { + return true + } + } + return false +} diff --git a/crypto/keys/mintkey/mintkey.go b/crypto/keys/mintkey/mintkey.go index 80377920fe46..20a183f33074 100644 --- a/crypto/keys/mintkey/mintkey.go +++ b/crypto/keys/mintkey/mintkey.go @@ -12,6 +12,7 @@ import ( "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" cmn "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) const ( @@ -144,7 +145,9 @@ func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privK } key = crypto.Sha256(key) // Get 32 bytes privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key) - if err != nil { + if err != nil && err.Error() == "Ciphertext decryption failed" { + return privKey, keyerror.NewErrWrongPassword() + } else if err != nil { return privKey, err } privKey, err = cryptoAmino.PrivKeyFromBytes(privKeyBytes) diff --git a/x/auth/client/rest/sign.go b/x/auth/client/rest/sign.go index 0347982edc27..4a257ff6c666 100644 --- a/x/auth/client/rest/sign.go +++ b/x/auth/client/rest/sign.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" ) // SignBody defines the properties of a sign request's body. @@ -47,10 +48,10 @@ func SignTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha } signedTx, err := txBldr.SignStdTx(m.LocalAccountName, m.Password, m.Tx, m.AppendSig) - if utils.IsKeyNotFoundErr(err, m.LocalAccountName) { + if keyerror.IsErrKeyNotFound(err) { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return - } else if utils.IsWrongKeyPasswordErr(err) { + } else if keyerror.IsErrWrongPassword(err) { utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error()) return } else if err != nil { From d88a213cfaeceb0faa2de08098d341feea62d52f Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Tue, 23 Oct 2018 18:02:30 +0800 Subject: [PATCH 21/22] Add /stake/validators/{validatorAddr}/unbonding_delegations and /stake/validators/{validatorAddr}/redelegations --- client/lcd/swagger-ui/swagger.yaml | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index b5dcc4a1d03e..d989a052fc7b 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -920,6 +920,54 @@ paths: description: Invalid validator address 500: description: Internal Server Error + /stake/validators/{validatorAddr}/unbonding_delegations: + parameters: + - in: path + name: validatorAddr + description: Bech32 OperatorAddress of validator + required: true + type: string + get: + summary: Get all unbonding delegations from a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/UnbondingDelegation" + 400: + description: Invalid validator address + 500: + description: Internal Server Error + /stake/validators/{validatorAddr}/redelegations: + parameters: + - in: path + name: validatorAddr + description: Bech32 OperatorAddress of validator + required: true + type: string + get: + summary: Get all outgoing redelegations from a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/Redelegation" + 400: + description: Invalid validator address + 500: + description: Internal Server Error /stake/pool: get: summary: Get the current state of the staking pool From fb04cfbd762c0814f637bb9aa29ff79ac78f680d Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Wed, 24 Oct 2018 14:22:01 +0800 Subject: [PATCH 22/22] Add change to about split issue 2258 to swagger.yaml --- client/lcd/swagger-ui/swagger.yaml | 68 +++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index d989a052fc7b..86b6ec6813fa 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -710,7 +710,25 @@ paths: description: Key password is wrong 500: description: Internal Server Error - /stake/delegators/{delegatorAddr}: + get: + summary: Get all delegations from a delegator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + type: object + "$ref": "#/definitions/Delegation" + 400: + description: Invalid delegator address + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/unbonding_delegations: parameters: - in: path name: delegatorAddr @@ -718,7 +736,7 @@ paths: required: true type: string get: - summary: Get all delegations (delegation, undelegation) from a delegator + summary: Get all unbonding delegations from a delegator tags: - ICS21 produces: @@ -727,23 +745,35 @@ paths: 200: description: OK schema: - type: object - properties: - redelegations: - type: array - items: - type: object - "$ref": "#/definitions/Redelegation" - unbonding_delegations: - type: array - items: - type: object - "$ref": "#/definitions/UnbondingDelegation" - delegations: - type: array - items: - type: object - "$ref": "#/definitions/Delegation" + type: array + items: + type: object + "$ref": "#/definitions/UnbondingDelegation" + 400: + description: Invalid delegator address + 500: + description: Internal Server Error + /stake/delegators/{delegatorAddr}/redelegations: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string + get: + summary: Get all redelegations from a delegator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + type: object + "$ref": "#/definitions/Redelegation" 400: description: Invalid delegator address 500: