Merge PR #3460: Implement fee distribution RESTful endpoints
This commit is contained in:
parent
254c39a9e2
commit
a2b73c8ab4
|
@ -6,6 +6,7 @@ BREAKING CHANGES
|
|||
* [\#3284](https://github.com/cosmos/cosmos-sdk/issues/3284) Rename the `name`
|
||||
field to `from` in the `base_req` body.
|
||||
* [\#3485](https://github.com/cosmos/cosmos-sdk/pull/3485) Error responses are now JSON objects.
|
||||
* [\#3477][distribution] endpoint changed "all_delegation_rewards" -> "delegator_total_rewards"
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
- [#3399](https://github.com/cosmos/cosmos-sdk/pull/3399) Add `gaiad validate-genesis` command to facilitate checking of genesis files
|
||||
|
@ -19,6 +20,7 @@ BREAKING CHANGES
|
|||
|
||||
* SDK
|
||||
* [\#3487](https://github.com/cosmos/cosmos-sdk/pull/3487) Move HTTP/REST utilities out of client/utils into a new dedicated client/rest package.
|
||||
* [\#3490](https://github.com/cosmos/cosmos-sdk/issues/3490) ReadRESTReq() returns bool to avoid callers to write error responses twice.
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
@ -26,6 +28,7 @@ BREAKING CHANGES
|
|||
FEATURES
|
||||
|
||||
* Gaia REST API
|
||||
* [\#2358](https://github.com/cosmos/cosmos-sdk/issues/2358) Add distribution module REST interface
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [\#3429](https://github.com/cosmos/cosmos-sdk/issues/3429) Support querying
|
||||
|
@ -38,6 +41,7 @@ FEATURES
|
|||
|
||||
* SDK
|
||||
* \#3270 [x/staking] limit number of ongoing unbonding delegations /redelegations per pair/trio
|
||||
* [\#3477][distribution] new query endpoint "delegator_validators"
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
@ -54,6 +58,7 @@ IMPROVEMENTS
|
|||
(auto gas) to work with generate only.
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [\#3476](https://github.com/cosmos/cosmos-sdk/issues/3476) New `withdraw-all-rewards` command to withdraw all delegations rewards for delegators.
|
||||
|
||||
* Gaia
|
||||
* [\#3418](https://github.com/cosmos/cosmos-sdk/issues/3418) Add vesting account
|
||||
|
|
|
@ -26,6 +26,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
dclcommon "github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
||||
distrrest "github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
@ -918,3 +920,99 @@ func TestSlashingGetParams(t *testing.T) {
|
|||
err := cdc.UnmarshalJSON([]byte(body), ¶ms)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDistributionGetParams(t *testing.T) {
|
||||
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
|
||||
defer cleanup()
|
||||
|
||||
res, body := Request(t, port, "GET", "/distribution/parameters", nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &dclcommon.PrettyParams{}))
|
||||
}
|
||||
|
||||
func TestDistributionFlow(t *testing.T) {
|
||||
addr, seed := CreateAddr(t, name1, pw, GetKeyBase(t))
|
||||
//addr2, seed2 = CreateAddr(t, name2, pw, GetKeyBase(t))
|
||||
cleanup, _, valAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
|
||||
defer cleanup()
|
||||
|
||||
valAddr := valAddrs[0]
|
||||
operAddr := sdk.AccAddress(valAddr)
|
||||
|
||||
var rewards sdk.DecCoins
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/distribution/outstanding_rewards"), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, sdk.DecCoins(nil), rewards)
|
||||
|
||||
var valDistInfo distrrest.ValidatorDistInfo
|
||||
res, body = Request(t, port, "GET", "/distribution/validators/"+valAddr.String(), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &valDistInfo))
|
||||
require.Equal(t, valDistInfo.OperatorAddress.String(), sdk.AccAddress(valAddr).String())
|
||||
require.Equal(t, valDistInfo.ValidatorCommission, sdk.DecCoins(nil))
|
||||
require.Equal(t, valDistInfo.SelfBondRewards, sdk.DecCoins(nil))
|
||||
|
||||
// Delegate some coins
|
||||
resultTx := doDelegate(t, port, name1, pw, addr, valAddr, 60, fees)
|
||||
tests.WaitForHeight(resultTx.Height+1, port)
|
||||
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
|
||||
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
|
||||
|
||||
// send some coins
|
||||
_, resultTx = doTransfer(t, port, seed, name1, memo, pw, addr, fees)
|
||||
tests.WaitForHeight(resultTx.Height+5, port)
|
||||
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
|
||||
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
|
||||
|
||||
// Query outstanding rewards changed
|
||||
oustandingRewards := mustParseDecCoins("9.80stake")
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/outstanding_rewards"), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, oustandingRewards, rewards)
|
||||
|
||||
// Query validator distribution info
|
||||
res, body = Request(t, port, "GET", "/distribution/validators/"+valAddr.String(), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
valRewards := mustParseDecCoins("6.125stake")
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &valDistInfo))
|
||||
require.Equal(t, valRewards, valDistInfo.SelfBondRewards)
|
||||
|
||||
// Query validator's rewards
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/validators/%s/rewards", valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, valRewards, rewards)
|
||||
|
||||
// Query self-delegation
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards/%s", operAddr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, valRewards, rewards)
|
||||
|
||||
// Query delegation
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards/%s", addr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, mustParseDecCoins("3.675stake"), rewards)
|
||||
|
||||
// Query delegator's rewards total
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards", operAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
|
||||
require.Equal(t, valRewards, rewards)
|
||||
|
||||
// Query delegator's withdrawal address
|
||||
var withdrawAddr string
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/withdraw_address", operAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &withdrawAddr))
|
||||
require.Equal(t, operAddr.String(), withdrawAddr)
|
||||
|
||||
// Withdraw delegator's rewards
|
||||
resultTx = doWithdrawDelegatorAllRewards(t, port, seed, name1, pw, addr, fees)
|
||||
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
|
||||
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ tags:
|
|||
- name: ICS23
|
||||
description: Slashing module APIs
|
||||
- name: ICS24
|
||||
description: WIP - Fee distribution module APIs
|
||||
description: Fee distribution module APIs
|
||||
- name: version
|
||||
description: Query app version
|
||||
schemes:
|
||||
|
@ -1846,9 +1846,9 @@ paths:
|
|||
type: string
|
||||
500:
|
||||
description: Internal Server Error
|
||||
/distribution/pool:
|
||||
/distribution/outstanding_rewards:
|
||||
get:
|
||||
summary: Fee distribution pool
|
||||
summary: Fee distribution outstanding rewards
|
||||
tags:
|
||||
- ICS24
|
||||
produces:
|
||||
|
@ -1857,7 +1857,9 @@ paths:
|
|||
200:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: "#/definitions/FeePool"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
500:
|
||||
description: Internal Server Error
|
||||
definitions:
|
||||
|
@ -2198,7 +2200,7 @@ definitions:
|
|||
power:
|
||||
type: string
|
||||
example: "1000"
|
||||
accum:
|
||||
proposer_priority:
|
||||
type: string
|
||||
example: "1000"
|
||||
TextProposal:
|
||||
|
@ -2367,36 +2369,12 @@ definitions:
|
|||
type: string
|
||||
shares_dst:
|
||||
type: string
|
||||
FeePool:
|
||||
type: object
|
||||
properties:
|
||||
community_pool:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
val_accum:
|
||||
$ref: "#/definitions/TotalAccum"
|
||||
val_pool:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
TotalAccum:
|
||||
type: object
|
||||
properties:
|
||||
update_height:
|
||||
type: integer
|
||||
accum:
|
||||
type: string
|
||||
ValidatorDistInfo:
|
||||
type: object
|
||||
properties:
|
||||
operator_addr:
|
||||
$ref: "#/definitions/ValidatorAddress"
|
||||
fee_pool_withdrawal_height:
|
||||
type: integer
|
||||
del_accum:
|
||||
$ref: "#/definitions/TotalAccum"
|
||||
del_pool:
|
||||
self_bond_rewards:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
|
|
|
@ -60,6 +60,8 @@ import (
|
|||
|
||||
authRest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
bankRest "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
distrRest "github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
|
||||
govRest "github.com/cosmos/cosmos-sdk/x/gov/client/rest"
|
||||
slashingRest "github.com/cosmos/cosmos-sdk/x/slashing/client/rest"
|
||||
stakingRest "github.com/cosmos/cosmos-sdk/x/staking/client/rest"
|
||||
|
@ -294,6 +296,11 @@ func InitializeTestLCD(
|
|||
genesisState.StakingData.Pool.NotBondedTokens = genesisState.StakingData.Pool.NotBondedTokens.Add(sdk.NewInt(100))
|
||||
}
|
||||
|
||||
inflationMin := sdk.MustNewDecFromStr("10000.0")
|
||||
genesisState.MintData.Minter.Inflation = inflationMin
|
||||
genesisState.MintData.Params.InflationMax = sdk.MustNewDecFromStr("15000.0")
|
||||
genesisState.MintData.Params.InflationMin = inflationMin
|
||||
|
||||
appState, err := codec.MarshalJSONIndent(cdc, genesisState)
|
||||
require.NoError(t, err)
|
||||
genDoc.AppState = appState
|
||||
|
@ -390,6 +397,7 @@ func registerRoutes(rs *RestServer) {
|
|||
tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
|
||||
authRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, auth.StoreKey)
|
||||
bankRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
distrRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distr.StoreKey)
|
||||
stakingRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
slashingRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
govRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
|
||||
|
@ -1382,3 +1390,37 @@ func doUnjail(t *testing.T, port, seed, name, password string,
|
|||
type unjailReq struct {
|
||||
BaseReq rest.BaseReq `json:"base_req"`
|
||||
}
|
||||
|
||||
// ICS24 - fee distribution
|
||||
|
||||
// POST /distribution/delegators/{delgatorAddr}/rewards Withdraw delegator rewards
|
||||
func doWithdrawDelegatorAllRewards(t *testing.T, port, seed, name, password string,
|
||||
delegatorAddr sdk.AccAddress, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
// get the account to get the sequence
|
||||
acc := getAccount(t, port, delegatorAddr)
|
||||
accnum := acc.GetAccountNumber()
|
||||
sequence := acc.GetSequence()
|
||||
chainID := viper.GetString(client.FlagChainID)
|
||||
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
|
||||
|
||||
wr := struct {
|
||||
BaseReq rest.BaseReq `json:"base_req"`
|
||||
}{BaseReq: baseReq}
|
||||
|
||||
req := cdc.MustMarshalJSON(wr)
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/distribution/delegators/%s/rewards", delegatorAddr), req)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var results ctypes.ResultBroadcastTxCommit
|
||||
cdc.MustUnmarshalJSON([]byte(body), &results)
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
func mustParseDecCoins(dcstring string) sdk.DecCoins {
|
||||
dcoins, err := sdk.ParseDecCoins(dcstring)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dcoins
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool {
|
|||
|
||||
/*
|
||||
ReadRESTReq is a simple convenience wrapper that reads the body and
|
||||
unmarshals to the req interface.
|
||||
unmarshals to the req interface. Returns false if errors occurred.
|
||||
|
||||
Usage:
|
||||
type SomeReq struct {
|
||||
|
@ -107,20 +107,22 @@ unmarshals to the req interface.
|
|||
}
|
||||
|
||||
req := new(SomeReq)
|
||||
err := ReadRESTReq(w, r, cdc, req)
|
||||
if ok := ReadRESTReq(w, r, cdc, req); !ok {
|
||||
return
|
||||
}
|
||||
*/
|
||||
func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req interface{}) error {
|
||||
func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req interface{}) bool {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return err
|
||||
return false
|
||||
}
|
||||
|
||||
err = cdc.UnmarshalJSON(body, req)
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to decode JSON payload: %s", err))
|
||||
return err
|
||||
return false
|
||||
}
|
||||
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
at "github.com/cosmos/cosmos-sdk/x/auth"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||
dist "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
dist "github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
|
||||
gv "github.com/cosmos/cosmos-sdk/x/gov"
|
||||
gov "github.com/cosmos/cosmos-sdk/x/gov/client/rest"
|
||||
sl "github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
|
@ -35,6 +35,7 @@ import (
|
|||
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
||||
distcmd "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
distClient "github.com/cosmos/cosmos-sdk/x/distribution/client"
|
||||
govClient "github.com/cosmos/cosmos-sdk/x/gov/client"
|
||||
slashingClient "github.com/cosmos/cosmos-sdk/x/slashing/client"
|
||||
|
@ -65,7 +66,7 @@ func main() {
|
|||
// TODO: Make the lcd command take a list of ModuleClient
|
||||
mc := []sdk.ModuleClients{
|
||||
govClient.NewModuleClient(gv.StoreKey, cdc),
|
||||
distClient.NewModuleClient(dist.StoreKey, cdc),
|
||||
distClient.NewModuleClient(distcmd.StoreKey, cdc),
|
||||
stakingClient.NewModuleClient(st.StoreKey, cdc),
|
||||
slashingClient.NewModuleClient(sl.StoreKey, cdc),
|
||||
}
|
||||
|
@ -161,6 +162,7 @@ func registerRoutes(rs *lcd.RestServer) {
|
|||
tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
|
||||
auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, at.StoreKey)
|
||||
bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
dist.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distcmd.StoreKey)
|
||||
staking.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
|
||||
gov.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
|
||||
|
|
|
@ -26,8 +26,7 @@ func SignTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var m SignBody
|
||||
|
||||
if err := rest.ReadRESTReq(w, r, cdc, &m); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
if !rest.ReadRESTReq(w, r, cdc, &m) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC
|
|||
}
|
||||
|
||||
var req sendReq
|
||||
err = rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,10 @@ type (
|
|||
FeeCollectionKeeper = types.FeeCollectionKeeper
|
||||
|
||||
// querier param types
|
||||
QueryValidatorCommissionParams = keeper.QueryValidatorCommissionParams
|
||||
QueryValidatorSlashesParams = keeper.QueryValidatorSlashesParams
|
||||
QueryDelegationRewardsParams = keeper.QueryDelegationRewardsParams
|
||||
QueryValidatorCommissionParams = keeper.QueryValidatorCommissionParams
|
||||
QueryValidatorSlashesParams = keeper.QueryValidatorSlashesParams
|
||||
QueryDelegationRewardsParams = keeper.QueryDelegationRewardsParams
|
||||
QueryDelegatorWithdrawAddrParams = keeper.QueryDelegatorWithdrawAddrParams
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -49,12 +50,14 @@ var (
|
|||
NewMsgWithdrawDelegatorReward = types.NewMsgWithdrawDelegatorReward
|
||||
NewMsgWithdrawValidatorCommission = types.NewMsgWithdrawValidatorCommission
|
||||
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
NewQueryValidatorCommissionParams = keeper.NewQueryValidatorCommissionParams
|
||||
NewQueryValidatorSlashesParams = keeper.NewQueryValidatorSlashesParams
|
||||
NewQueryDelegationRewardsParams = keeper.NewQueryDelegationRewardsParams
|
||||
DefaultParamspace = keeper.DefaultParamspace
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
NewQueryValidatorCommissionParams = keeper.NewQueryValidatorCommissionParams
|
||||
NewQueryValidatorSlashesParams = keeper.NewQueryValidatorSlashesParams
|
||||
NewQueryDelegationRewardsParams = keeper.NewQueryDelegationRewardsParams
|
||||
NewQueryDelegatorParams = keeper.NewQueryDelegatorParams
|
||||
NewQueryDelegatorWithdrawAddrParams = keeper.NewQueryDelegatorWithdrawAddrParams
|
||||
DefaultParamspace = keeper.DefaultParamspace
|
||||
|
||||
RegisterCodec = types.RegisterCodec
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
|
@ -21,34 +22,10 @@ func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
|||
Short: "Query distribution params",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
route := fmt.Sprintf("custom/%s/params/community_tax", queryRoute)
|
||||
retCommunityTax, err := cliCtx.QueryWithData(route, []byte{})
|
||||
params, err := common.QueryParams(cliCtx, queryRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/base_proposer_reward", queryRoute)
|
||||
retBaseProposerReward, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/bonus_proposer_reward", queryRoute)
|
||||
retBonusProposerReward, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/withdraw_addr_enabled", queryRoute)
|
||||
retWithdrawAddrEnabled, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := NewPrettyParams(retCommunityTax, retBaseProposerReward,
|
||||
retBonusProposerReward, retWithdrawAddrEnabled)
|
||||
|
||||
return cliCtx.PrintOutput(params)
|
||||
},
|
||||
}
|
||||
|
@ -90,13 +67,7 @@ func GetCmdQueryValidatorCommission(queryRoute string, cdc *codec.Codec) *cobra.
|
|||
return err
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(distr.NewQueryValidatorCommissionParams(validatorAddr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/validator_commission", queryRoute)
|
||||
res, err := cliCtx.QueryWithData(route, bz)
|
||||
res, err := common.QueryValidatorCommission(cliCtx, cdc, queryRoute, validatorAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -159,42 +130,20 @@ func GetCmdQueryDelegatorRewards(queryRoute string, cdc *codec.Codec) *cobra.Com
|
|||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
route string
|
||||
params distr.QueryDelegationRewardsParams
|
||||
result sdk.DecCoins
|
||||
)
|
||||
|
||||
if len(args) == 1 {
|
||||
// query for all rewards
|
||||
params = distr.NewQueryDelegationRewardsParams(delegatorAddr, nil)
|
||||
route = fmt.Sprintf("custom/%s/all_delegation_rewards", queryRoute)
|
||||
var resp []byte
|
||||
var err error
|
||||
if len(args) == 2 {
|
||||
// query for rewards from a particular delegation
|
||||
resp, err = common.QueryDelegationRewards(cliCtx, cdc, queryRoute, args[0], args[1])
|
||||
} else {
|
||||
// query for rewards from a particular validator
|
||||
validatorAddr, err := sdk.ValAddressFromBech32(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params = distr.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr)
|
||||
route = fmt.Sprintf("custom/%s/delegation_rewards", queryRoute)
|
||||
// query for delegator total rewards
|
||||
resp, err = common.QueryDelegatorTotalRewards(cliCtx, cdc, queryRoute, args[0])
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var result sdk.DecCoins
|
||||
cdc.MustUnmarshalJSON(resp, &result)
|
||||
return cliCtx.PrintOutput(result)
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
|
@ -89,7 +90,39 @@ func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdDelegate implements the delegate command.
|
||||
// command to withdraw all rewards
|
||||
func GetCmdWithdrawAllRewards(cdc *codec.Codec, queryRoute string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "withdraw-all-rewards [delegator-addr]",
|
||||
Short: "withdraw all delegations rewards for a delegator",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithAccountDecoder(cdc)
|
||||
|
||||
delAddr := cliCtx.GetFromAddress()
|
||||
msgs, err := common.WithdrawAllDelegatorRewards(cliCtx, cdc, queryRoute, delAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, msgs, false)
|
||||
}
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, msgs)
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagOnlyFromValidator, "", "only withdraw from this validator address (in bech)")
|
||||
cmd.Flags().Bool(flagIsValidator, false, "also withdraw validator's commission")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// command to replace a delegator's withdrawal address
|
||||
func GetCmdSetWithdrawAddr(cdc *codec.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "set-withdraw-addr [withdraw-addr]",
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
)
|
||||
|
||||
// QueryParams actually queries distribution params.
|
||||
func QueryParams(cliCtx context.CLIContext, queryRoute string) (PrettyParams, error) {
|
||||
route := fmt.Sprintf("custom/%s/params/community_tax", queryRoute)
|
||||
|
||||
retCommunityTax, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return PrettyParams{}, err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/base_proposer_reward", queryRoute)
|
||||
retBaseProposerReward, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return PrettyParams{}, err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/bonus_proposer_reward", queryRoute)
|
||||
retBonusProposerReward, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return PrettyParams{}, err
|
||||
}
|
||||
|
||||
route = fmt.Sprintf("custom/%s/params/withdraw_addr_enabled", queryRoute)
|
||||
retWithdrawAddrEnabled, err := cliCtx.QueryWithData(route, []byte{})
|
||||
if err != nil {
|
||||
return PrettyParams{}, err
|
||||
}
|
||||
|
||||
return NewPrettyParams(retCommunityTax, retBaseProposerReward,
|
||||
retBonusProposerReward, retWithdrawAddrEnabled), nil
|
||||
}
|
||||
|
||||
// QueryDelegatorTotalRewards queries delegator total rewards.
|
||||
func QueryDelegatorTotalRewards(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute, delAddr string) ([]byte, error) {
|
||||
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(delAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cliCtx.QueryWithData(
|
||||
fmt.Sprintf("custom/%s/delegator_total_rewards", queryRoute),
|
||||
cdc.MustMarshalJSON(distr.NewQueryDelegatorParams(delegatorAddr)),
|
||||
)
|
||||
}
|
||||
|
||||
// QueryDelegationRewards queries a delegation rewards.
|
||||
func QueryDelegationRewards(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute, delAddr, valAddr string) ([]byte, error) {
|
||||
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(delAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatorAddr, err := sdk.ValAddressFromBech32(valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cliCtx.QueryWithData(
|
||||
fmt.Sprintf("custom/%s/delegation_rewards", queryRoute),
|
||||
cdc.MustMarshalJSON(distr.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr)),
|
||||
)
|
||||
}
|
||||
|
||||
// QueryDelegatorValidators returns delegator's list of validators
|
||||
// it submitted delegations to.
|
||||
func QueryDelegatorValidators(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string, delegatorAddr sdk.AccAddress) ([]byte, error) {
|
||||
|
||||
return cliCtx.QueryWithData(
|
||||
fmt.Sprintf("custom/%s/delegator_validators", queryRoute),
|
||||
cdc.MustMarshalJSON(distr.NewQueryDelegatorParams(delegatorAddr)),
|
||||
)
|
||||
}
|
||||
|
||||
// QueryValidatorCommission returns a validator's commission.
|
||||
func QueryValidatorCommission(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string, validatorAddr sdk.ValAddress) ([]byte, error) {
|
||||
|
||||
return cliCtx.QueryWithData(
|
||||
fmt.Sprintf("custom/%s/validator_commission", queryRoute),
|
||||
cdc.MustMarshalJSON(distr.NewQueryValidatorCommissionParams(validatorAddr)),
|
||||
)
|
||||
}
|
||||
|
||||
// WithdrawAllDelegatorRewards builds a multi-message slice to be used
|
||||
// to withdraw all delegations rewards for the given delegator.
|
||||
func WithdrawAllDelegatorRewards(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string, delegatorAddr sdk.AccAddress) ([]sdk.Msg, error) {
|
||||
|
||||
// retrieve the comprehensive list of all validators which the
|
||||
// delegator had submitted delegations to
|
||||
bz, err := QueryDelegatorValidators(cliCtx, cdc, queryRoute, delegatorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var validators []sdk.ValAddress
|
||||
if err := cdc.UnmarshalJSON(bz, &validators); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// build multi-message transaction
|
||||
var msgs []sdk.Msg
|
||||
for _, valAddr := range validators {
|
||||
msg := distr.NewMsgWithdrawDelegatorReward(delegatorAddr, valAddr)
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
// WithdrawValidatorRewardsAndCommission builds a two-message message slice to be
|
||||
// used to withdraw both validation's commission and self-delegation reward.
|
||||
func WithdrawValidatorRewardsAndCommission(validatorAddr sdk.ValAddress) ([]sdk.Msg, error) {
|
||||
|
||||
commissionMsg := distr.NewMsgWithdrawValidatorCommission(validatorAddr)
|
||||
if err := commissionMsg.ValidateBasic(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// build and validate MsgWithdrawDelegatorReward
|
||||
rewardMsg := distr.NewMsgWithdrawDelegatorReward(
|
||||
sdk.AccAddress(validatorAddr.Bytes()), validatorAddr)
|
||||
if err := rewardMsg.ValidateBasic(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []sdk.Msg{commissionMsg, rewardMsg}, nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestQueryDelegationRewardsAddrValidation(t *testing.T) {
|
||||
cdc := codec.New()
|
||||
ctx := context.NewCLIContext().WithCodec(cdc)
|
||||
type args struct {
|
||||
delAddr string
|
||||
valAddr string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []byte
|
||||
wantErr bool
|
||||
}{
|
||||
{"invalid delegator address", args{"invalid", ""}, nil, true},
|
||||
{"empty delegator address", args{"", ""}, nil, true},
|
||||
{"invalid validator address", args{"cosmos1zxcsu7l5qxs53lvp0fqgd09a9r2g6kqrk2cdpa", "invalid"}, nil, true},
|
||||
{"empty validator address", args{"cosmos1zxcsu7l5qxs53lvp0fqgd09a9r2g6kqrk2cdpa", ""}, nil, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := QueryDelegationRewards(ctx, cdc, "", tt.args.delAddr, tt.args.valAddr)
|
||||
require.True(t, err != nil, tt.wantErr)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cli
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
|
@ -46,6 +46,7 @@ func (mc ModuleClient) GetTxCmd() *cobra.Command {
|
|||
distTxCmd.AddCommand(client.PostCommands(
|
||||
distCmds.GetCmdWithdrawRewards(mc.cdc),
|
||||
distCmds.GetCmdSetWithdrawAddr(mc.cdc),
|
||||
distCmds.GetCmdWithdrawAllRewards(mc.cdc, mc.storeKey),
|
||||
)...)
|
||||
|
||||
return distTxCmd
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router,
|
||||
cdc *codec.Codec, queryRoute string) {
|
||||
|
||||
// Get the total rewards balance from all delegations
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/rewards",
|
||||
delegatorRewardsHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Query a delegation reward
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}",
|
||||
delegationRewardsHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Get the rewards withdrawal address
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/withdraw_address",
|
||||
delegatorWithdrawalAddrHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Validator distribution information
|
||||
r.HandleFunc(
|
||||
"/distribution/validators/{validatorAddr}",
|
||||
validatorInfoHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Commission and self-delegation rewards of a single a validator
|
||||
r.HandleFunc(
|
||||
"/distribution/validators/{validatorAddr}/rewards",
|
||||
validatorRewardsHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Get the current distribution parameter values
|
||||
r.HandleFunc(
|
||||
"/distribution/parameters",
|
||||
paramsHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
|
||||
// Get the current distribution pool
|
||||
r.HandleFunc(
|
||||
"/distribution/outstanding_rewards",
|
||||
outstandingRewardsHandlerFn(cliCtx, cdc, queryRoute),
|
||||
).Methods("GET")
|
||||
}
|
||||
|
||||
// HTTP request handler to query the total rewards balance from all delegations
|
||||
func delegatorRewardsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// query for rewards from a particular delegator
|
||||
res, ok := checkResponseQueryDelegatorTotalRewards(w, cliCtx, cdc, queryRoute,
|
||||
mux.Vars(r)["delegatorAddr"])
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query a delegation rewards
|
||||
func delegationRewardsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// query for rewards from a particular delegation
|
||||
res, ok := checkResponseQueryDelegationRewards(w, cliCtx, cdc, queryRoute,
|
||||
mux.Vars(r)["delegatorAddr"], mux.Vars(r)["validatorAddr"])
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query a delegation rewards
|
||||
func delegatorWithdrawalAddrHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
delegatorAddr, ok := checkDelegatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
bz := cdc.MustMarshalJSON(distribution.NewQueryDelegatorWithdrawAddrParams(delegatorAddr))
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/withdraw_addr", queryRoute), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// ValidatorDistInfo defines the properties of
|
||||
// validator distribution information response.
|
||||
type ValidatorDistInfo struct {
|
||||
OperatorAddress sdk.AccAddress `json:"operator_addr"`
|
||||
SelfBondRewards sdk.DecCoins `json:"self_bond_rewards"`
|
||||
ValidatorCommission types.ValidatorAccumulatedCommission `json:"val_commission"`
|
||||
}
|
||||
|
||||
// NewValidatorDistInfo creates a new instance of ValidatorDistInfo.
|
||||
func NewValidatorDistInfo(operatorAddr sdk.AccAddress, rewards sdk.DecCoins,
|
||||
commission types.ValidatorAccumulatedCommission) ValidatorDistInfo {
|
||||
return ValidatorDistInfo{
|
||||
OperatorAddress: operatorAddr,
|
||||
SelfBondRewards: rewards,
|
||||
ValidatorCommission: commission,
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query validator's distribution information
|
||||
func validatorInfoHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
valAddr := mux.Vars(r)["validatorAddr"]
|
||||
validatorAddr, ok := checkValidatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// query commission
|
||||
commissionRes, err := common.QueryValidatorCommission(cliCtx, cdc, queryRoute, validatorAddr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var valCom types.ValidatorAccumulatedCommission
|
||||
cdc.MustUnmarshalJSON(commissionRes, &valCom)
|
||||
|
||||
// self bond rewards
|
||||
delAddr := sdk.AccAddress(validatorAddr)
|
||||
rewardsRes, ok := checkResponseQueryDelegationRewards(w, cliCtx, cdc, queryRoute,
|
||||
delAddr.String(), valAddr)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var rewards sdk.DecCoins
|
||||
cdc.MustUnmarshalJSON(rewardsRes, &rewards)
|
||||
|
||||
// Prepare response
|
||||
res := cdc.MustMarshalJSON(NewValidatorDistInfo(delAddr, rewards, valCom))
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query validator's commission and self-delegation rewards
|
||||
func validatorRewardsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
valAddr := mux.Vars(r)["validatorAddr"]
|
||||
validatorAddr, ok := checkValidatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delAddr := sdk.AccAddress(validatorAddr).String()
|
||||
res, ok := checkResponseQueryDelegationRewards(w, cliCtx, cdc, queryRoute, delAddr, valAddr)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query the distribution params values
|
||||
func paramsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
params, err := common.QueryParams(cliCtx, queryRoute)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
rest.PostProcessResponse(w, cdc, params, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP request handler to query the outstanding rewards
|
||||
func outstandingRewardsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/outstanding_rewards", queryRoute), []byte{})
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
rest.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
func checkResponseQueryDelegatorTotalRewards(w http.ResponseWriter, cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute, delAddr string) (res []byte, ok bool) {
|
||||
|
||||
res, err := common.QueryDelegatorTotalRewards(cliCtx, cdc, queryRoute, delAddr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
||||
|
||||
func checkResponseQueryDelegationRewards(w http.ResponseWriter, cliCtx context.CLIContext, cdc *codec.Codec,
|
||||
queryRoute, delAddr, valAddr string) (res []byte, ok bool) {
|
||||
|
||||
res, err := common.QueryDelegationRewards(cliCtx, cdc, queryRoute, delAddr, valAddr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// RegisterRoutes register distribution REST routes.
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, queryRoute string) {
|
||||
registerQueryRoutes(cliCtx, r, cdc, queryRoute)
|
||||
registerTxRoutes(cliCtx, r, cdc, queryRoute)
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/rest"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router,
|
||||
cdc *codec.Codec, queryRoute string) {
|
||||
|
||||
// Withdraw all delegator rewards
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/rewards",
|
||||
withdrawDelegatorRewardsHandlerFn(cdc, cliCtx, queryRoute),
|
||||
).Methods("POST")
|
||||
|
||||
// Withdraw delegation rewards
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}",
|
||||
withdrawDelegationRewardsHandlerFn(cdc, cliCtx),
|
||||
).Methods("POST")
|
||||
|
||||
// Replace the rewards withdrawal address
|
||||
r.HandleFunc(
|
||||
"/distribution/delegators/{delegatorAddr}/withdraw_address",
|
||||
setDelegatorWithdrawalAddrHandlerFn(cdc, cliCtx),
|
||||
).Methods("POST")
|
||||
|
||||
// Withdraw validator rewards and commission
|
||||
r.HandleFunc(
|
||||
"/distribution/validators/{validatorAddr}/rewards",
|
||||
withdrawValidatorRewardsHandlerFn(cdc, cliCtx),
|
||||
).Methods("POST")
|
||||
|
||||
}
|
||||
|
||||
type (
|
||||
withdrawRewardsReq struct {
|
||||
BaseReq rest.BaseReq `json:"base_req"`
|
||||
}
|
||||
|
||||
setWithdrawalAddrReq struct {
|
||||
BaseReq rest.BaseReq `json:"base_req"`
|
||||
WithdrawAddress sdk.AccAddress `json:"withdraw_address"`
|
||||
}
|
||||
)
|
||||
|
||||
// Withdraw delegator rewards
|
||||
func withdrawDelegatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
queryRoute string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req withdrawRewardsReq
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.BaseReq = req.BaseReq.Sanitize()
|
||||
if !req.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
// read and validate URL's variables
|
||||
delAddr, ok := checkDelegatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
msgs, err := common.WithdrawAllDelegatorRewards(cliCtx, cdc, queryRoute, delAddr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.BaseReq.GenerateOnly {
|
||||
rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs)
|
||||
return
|
||||
}
|
||||
|
||||
rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, msgs, cdc)
|
||||
}
|
||||
}
|
||||
|
||||
// Withdraw delegation rewards
|
||||
func withdrawDelegationRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req withdrawRewardsReq
|
||||
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.BaseReq = req.BaseReq.Sanitize()
|
||||
if !req.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
// read and validate URL's variables
|
||||
delAddr, ok := checkDelegatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
valAddr, ok := checkValidatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
msg := types.NewMsgWithdrawDelegatorReward(delAddr, valAddr)
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.BaseReq.GenerateOnly {
|
||||
rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the rewards withdrawal address
|
||||
func setDelegatorWithdrawalAddrHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req setWithdrawalAddrReq
|
||||
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.BaseReq = req.BaseReq.Sanitize()
|
||||
if !req.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
// read and validate URL's variables
|
||||
delAddr, ok := checkDelegatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
msg := types.NewMsgSetWithdrawAddress(delAddr, req.WithdrawAddress)
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.BaseReq.GenerateOnly {
|
||||
rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
|
||||
}
|
||||
}
|
||||
|
||||
// Withdraw validator rewards and commission
|
||||
func withdrawValidatorRewardsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req withdrawRewardsReq
|
||||
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.BaseReq = req.BaseReq.Sanitize()
|
||||
if !req.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
// read and validate URL's variable
|
||||
valAddr, ok := checkValidatorAddressVar(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// prepare multi-message transaction
|
||||
msgs, err := common.WithdrawValidatorRewardsAndCommission(valAddr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.BaseReq.GenerateOnly {
|
||||
rest.WriteGenerateStdTxResponse(w, cdc, cliCtx, req.BaseReq, msgs)
|
||||
return
|
||||
}
|
||||
|
||||
rest.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, msgs, cdc)
|
||||
}
|
||||
}
|
||||
|
||||
// Auxiliary
|
||||
|
||||
func checkDelegatorAddressVar(w http.ResponseWriter, r *http.Request) (sdk.AccAddress, bool) {
|
||||
addr, err := sdk.AccAddressFromBech32(mux.Vars(r)["delegatorAddr"])
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return nil, false
|
||||
}
|
||||
return addr, true
|
||||
}
|
||||
|
||||
func checkValidatorAddressVar(w http.ResponseWriter, r *http.Request) (sdk.ValAddress, bool) {
|
||||
addr, err := sdk.ValAddressFromBech32(mux.Vars(r)["validatorAddr"])
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return nil, false
|
||||
}
|
||||
return addr, true
|
||||
}
|
|
@ -12,12 +12,14 @@ import (
|
|||
|
||||
// nolint
|
||||
const (
|
||||
QueryParams = "params"
|
||||
QueryOutstandingRewards = "outstanding_rewards"
|
||||
QueryValidatorCommission = "validator_commission"
|
||||
QueryValidatorSlashes = "validator_slashes"
|
||||
QueryDelegationRewards = "delegation_rewards"
|
||||
QueryAllDelegationRewards = "all_delegation_rewards"
|
||||
QueryParams = "params"
|
||||
QueryOutstandingRewards = "outstanding_rewards"
|
||||
QueryValidatorCommission = "validator_commission"
|
||||
QueryValidatorSlashes = "validator_slashes"
|
||||
QueryDelegationRewards = "delegation_rewards"
|
||||
QueryDelegatorTotalRewards = "delegator_total_rewards"
|
||||
QueryDelegatorValidators = "delegator_validators"
|
||||
QueryWithdrawAddr = "withdraw_addr"
|
||||
|
||||
ParamCommunityTax = "community_tax"
|
||||
ParamBaseProposerReward = "base_proposer_reward"
|
||||
|
@ -43,8 +45,14 @@ func NewQuerier(k Keeper) sdk.Querier {
|
|||
case QueryDelegationRewards:
|
||||
return queryDelegationRewards(ctx, path[1:], req, k)
|
||||
|
||||
case QueryAllDelegationRewards:
|
||||
return queryAllDelegationRewards(ctx, path[1:], req, k)
|
||||
case QueryDelegatorTotalRewards:
|
||||
return queryDelegatorTotalRewards(ctx, path[1:], req, k)
|
||||
|
||||
case QueryDelegatorValidators:
|
||||
return queryDelegatorValidators(ctx, path[1:], req, k)
|
||||
|
||||
case QueryWithdrawAddr:
|
||||
return queryDelegatorWithdrawAddress(ctx, path[1:], req, k)
|
||||
|
||||
default:
|
||||
return nil, sdk.ErrUnknownRequest("unknown distr query endpoint")
|
||||
|
@ -190,8 +198,20 @@ func queryDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery,
|
|||
return bz, nil
|
||||
}
|
||||
|
||||
func queryAllDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) {
|
||||
var params QueryDelegationRewardsParams
|
||||
// params for query 'custom/distr/delegator_total_rewards' and 'custom/distr/delegator_validators'
|
||||
type QueryDelegatorParams struct {
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
||||
}
|
||||
|
||||
// creates a new instance of QueryDelegationRewardsParams
|
||||
func NewQueryDelegatorParams(delegatorAddr sdk.AccAddress) QueryDelegatorParams {
|
||||
return QueryDelegatorParams{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
}
|
||||
}
|
||||
|
||||
func queryDelegatorTotalRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) {
|
||||
var params QueryDelegatorParams
|
||||
err := k.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
|
||||
|
@ -221,3 +241,59 @@ func queryAllDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuer
|
|||
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryDelegatorValidators(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) {
|
||||
var params QueryDelegatorParams
|
||||
err := k.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
|
||||
}
|
||||
|
||||
// cache-wrap context as to not persist state changes during querying
|
||||
ctx, _ = ctx.CacheContext()
|
||||
|
||||
var validators []sdk.ValAddress
|
||||
|
||||
k.stakingKeeper.IterateDelegations(
|
||||
ctx, params.DelegatorAddr,
|
||||
func(_ int64, del sdk.Delegation) (stop bool) {
|
||||
validators = append(validators[:], del.GetValidatorAddr())
|
||||
return false
|
||||
},
|
||||
)
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, validators)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
// params for query 'custom/distr/withdraw_addr'
|
||||
type QueryDelegatorWithdrawAddrParams struct {
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
||||
}
|
||||
|
||||
// NewQueryDelegatorWithdrawAddrParams creates a new instance of QueryDelegatorWithdrawAddrParams.
|
||||
func NewQueryDelegatorWithdrawAddrParams(delegatorAddr sdk.AccAddress) QueryDelegatorWithdrawAddrParams {
|
||||
return QueryDelegatorWithdrawAddrParams{DelegatorAddr: delegatorAddr}
|
||||
}
|
||||
|
||||
func queryDelegatorWithdrawAddress(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) {
|
||||
var params QueryDelegatorWithdrawAddrParams
|
||||
err := k.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
|
||||
}
|
||||
|
||||
// cache-wrap context as to not persist state changes during querying
|
||||
ctx, _ = ctx.CacheContext()
|
||||
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, params.DelegatorAddr)
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, withdrawAddr)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
|
||||
return bz, nil
|
||||
}
|
||||
|
|
|
@ -77,9 +77,7 @@ type voteReq struct {
|
|||
func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req postProposalReq
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -96,8 +94,7 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han
|
|||
|
||||
// create the message
|
||||
msg := gov.NewMsgSubmitProposal(req.Title, req.Description, proposalType, req.Proposer, req.InitialDeposit)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -128,8 +125,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF
|
|||
}
|
||||
|
||||
var req depositReq
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -140,8 +136,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF
|
|||
|
||||
// create the message
|
||||
msg := gov.NewMsgDeposit(req.Depositor, proposalID, req.Amount)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -172,8 +167,7 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc
|
|||
}
|
||||
|
||||
var req voteReq
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -190,8 +184,7 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc
|
|||
|
||||
// create the message
|
||||
msg := gov.NewMsgVote(req.Voter, proposalID, voteOption)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
|
|||
}
|
||||
|
||||
var req transferReq
|
||||
err = rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,7 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL
|
|||
bech32validator := vars["validatorAddr"]
|
||||
|
||||
var req UnjailReq
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,7 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req msgDelegationsInput
|
||||
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -70,8 +68,7 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
|
|||
}
|
||||
|
||||
msg := staking.NewMsgDelegate(req.DelegatorAddr, req.ValidatorAddr, req.Delegation)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -103,9 +100,7 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req msgBeginRedelegateInput
|
||||
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -115,8 +110,7 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex
|
|||
}
|
||||
|
||||
msg := staking.NewMsgBeginRedelegate(req.DelegatorAddr, req.ValidatorSrcAddr, req.ValidatorDstAddr, req.SharesAmount)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -148,9 +142,7 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req msgUndelegateInput
|
||||
|
||||
err := rest.ReadRESTReq(w, r, cdc, &req)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
if !rest.ReadRESTReq(w, r, cdc, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -160,8 +152,7 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx
|
|||
}
|
||||
|
||||
msg := staking.NewMsgUndelegate(req.DelegatorAddr, req.ValidatorAddr, req.SharesAmount)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue