Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Add rewards query #1360

Merged
merged 4 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions client/distribution/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,32 @@ func GetValidatorDistInfo(storeName string, cdc *codec.Codec) *cobra.Command {
}
return cmd
}

// GetRewards returns the all the rewards of validator or delegator
func GetRewards(distrStoreName string, stakeStoreName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "rewards",
Short: "Query all the rewards of validator or delegator",
Example: "iriscli distribution rewards <address>",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {

addrString := args[0]
delAddr, err := sdk.AccAddressFromBech32(addrString)
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)

rewards := distributionclient.GetRewards(distrStoreName, stakeStoreName, cliCtx, delAddr)

output, err := codec.MarshalJSONIndent(cdc, rewards)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
},
}
return cmd
}
22 changes: 19 additions & 3 deletions client/distribution/lcd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package lcd
import (
"net/http"

sdk "github.com/irisnet/irishub/types"
"github.com/irisnet/irishub/modules/distribution"
"github.com/irisnet/irishub/modules/distribution/types"
"github.com/gorilla/mux"
"github.com/irisnet/irishub/client/context"
distributionclient "github.com/irisnet/irishub/client/distribution"
"github.com/irisnet/irishub/client/utils"
"github.com/irisnet/irishub/modules/distribution"
"github.com/irisnet/irishub/modules/distribution/types"
sdk "github.com/irisnet/irishub/types"
)

// QueryWithdrawAddressHandlerFn performs withdraw address query
Expand Down Expand Up @@ -154,3 +154,19 @@ func QueryValidatorDistInfoHandlerFn(storeName string, cliCtx context.CLIContext
utils.PostProcessResponse(w, cliCtx.Codec, vdiOutput, cliCtx.Indent)
}
}

// QueryRewardsHandlerFn query the all the rewards of validator or delegator
func QueryRewardsHandlerFn(distrStoreName string, stakeStoreName string, cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)

AddrStr := vars["address"]
accAddress, err := sdk.AccAddressFromBech32(AddrStr)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.PostProcessResponse(w, cliCtx.Codec,
distributionclient.GetRewards(distrStoreName, stakeStoreName, cliCtx, accAddress), cliCtx.Indent)
}
}
5 changes: 4 additions & 1 deletion client/distribution/lcd/rest.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package lcd

import (
"github.com/irisnet/irishub/codec"
"github.com/gorilla/mux"
"github.com/irisnet/irishub/client/context"
"github.com/irisnet/irishub/codec"
)

const storeName = "distr"
const stakeStoreName = "stake"

// RegisterRoutes - Central function to define routes that get registered by the main application
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) {
Expand All @@ -21,4 +22,6 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec)
QueryDelegatorDistInfoHandlerFn(storeName, cliCtx)).Methods("GET")
r.HandleFunc("/distribution/{validatorAddr}/valDistrInfo",
QueryValidatorDistInfoHandlerFn(storeName, cliCtx)).Methods("GET")
r.HandleFunc("/distribution/{address}/rewards",
QueryRewardsHandlerFn(storeName, stakeStoreName, cliCtx)).Methods("GET")
}
129 changes: 127 additions & 2 deletions client/distribution/utils.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package distribution

import (
sdk "github.com/irisnet/irishub/types"
"github.com/irisnet/irishub/modules/distribution"
"github.com/irisnet/irishub/client/context"
tendermint "github.com/irisnet/irishub/client/tendermint/rpc"
"github.com/irisnet/irishub/client/utils"
"github.com/irisnet/irishub/modules/distribution"
distrKeeper "github.com/irisnet/irishub/modules/distribution/keeper"
"github.com/irisnet/irishub/modules/distribution/types"
"github.com/irisnet/irishub/modules/stake"
stakeKeeper "github.com/irisnet/irishub/modules/stake/keeper"
stakeTypes "github.com/irisnet/irishub/modules/stake/types"
sdk "github.com/irisnet/irishub/types"
"github.com/tendermint/tendermint/libs/log"
)

// distribution info for a particular validator
Expand All @@ -17,6 +23,17 @@ type ValidatorDistInfoOutput struct {
ValCommission string `json:"val_commission"`
}

type RewardsOutput struct {
Total sdk.Coins `json:"total"`
Delegations []DelegationsReward `json:"delegations"`
Commission sdk.Coins `json:"commission"`
}

type DelegationsReward struct {
Validator sdk.ValAddress `json:"validator"`
Reward sdk.Coins `json:"reward"`
}

func ConvertToValidatorDistInfoOutput(cliCtx context.CLIContext, vdi distribution.ValidatorDistInfo) ValidatorDistInfoOutput {
exRate := utils.ExRateFromStakeTokenToMainUnit(cliCtx)
delPool := utils.ConvertDecToRat(vdi.DelPool.AmountOf(stakeTypes.StakeDenom)).Mul(exRate).FloatString() + stakeTypes.StakeTokenName
Expand All @@ -29,3 +46,111 @@ func ConvertToValidatorDistInfoOutput(cliCtx context.CLIContext, vdi distributio
ValCommission: valCommission,
}
}

func GetRewards(distrStoreName string, stakeStoreName string, cliCtx context.CLIContext, account sdk.AccAddress) RewardsOutput {
totalWithdraw := types.DecCoins{}
rewardsOutput := RewardsOutput{}

// get all delegator rewards
res, err := cliCtx.QuerySubspace(stakeKeeper.GetDelegationsKey(account), stakeStoreName)
if err != nil {
return RewardsOutput{}
}

feePool := GetFeePool(distrStoreName, cliCtx)
chainHeight, err := tendermint.GetChainHeight(cliCtx)
for _, re := range res {
del := stakeTypes.MustUnmarshalDelegation(cliCtx.Codec, re.Key, re.Value)
valAddr := del.GetValidatorAddr()
validator := GetValidator(stakeStoreName, cliCtx, valAddr)
if !validator.OperatorAddr.Equals(valAddr) {
continue
}
vdi := GetValidatorDistInfo(distrStoreName, cliCtx, valAddr)
ddi := GetDelegationDistInfo(distrStoreName, cliCtx, del.DelegatorAddr, del.ValidatorAddr)
wc := GetWithdrawContext(stakeStoreName, cliCtx, feePool, chainHeight, validator)
_, _, newFeePool, diWithdraw := ddi.WithdrawRewards(log.NewNopLogger(), wc, vdi, validator.GetDelegatorShares(), del.GetShares())
totalWithdraw = totalWithdraw.Plus(diWithdraw)
rewardTruncate, _ := diWithdraw.TruncateDecimal()
rewardsOutput.Delegations = append(rewardsOutput.Delegations, DelegationsReward{valAddr, rewardTruncate})
feePool = newFeePool
}

// get all validator rewards
validator := GetValidator(stakeStoreName, cliCtx, sdk.ValAddress(account))
if validator.OperatorAddr.Equals(sdk.ValAddress(account)) {
wc := GetWithdrawContext(stakeStoreName, cliCtx, feePool, chainHeight, validator)
valInfo := GetValidatorDistInfo(distrStoreName, cliCtx, validator.GetOperator())
valInfo, _, commission := valInfo.WithdrawCommission(log.NewNopLogger(), wc)
totalWithdraw = totalWithdraw.Plus(commission)
rewardTruncate, _ := commission.TruncateDecimal()
rewardsOutput.Commission = rewardTruncate
}

rewardTruncate, _ := totalWithdraw.TruncateDecimal()
rewardsOutput.Total = rewardTruncate
return rewardsOutput
}

func GetFeePool(storeName string, cliCtx context.CLIContext) (feePool types.FeePool) {
res, err := cliCtx.QueryStore(distribution.FeePoolKey, storeName)
if err != nil {
return
}
if res == nil {
panic("Stored fee pool should not have been nil")
}
cliCtx.Codec.MustUnmarshalBinaryLengthPrefixed(res, &feePool)
return
}

func GetValidatorDistInfo(storeName string, cliCtx context.CLIContext,
operatorAddr sdk.ValAddress) (vdi types.ValidatorDistInfo) {
res, err := cliCtx.QueryStore(distrKeeper.GetValidatorDistInfoKey(operatorAddr), storeName)
if err != nil || len(res) == 0 {
return
}
cliCtx.Codec.MustUnmarshalBinaryLengthPrefixed(res, &vdi)
return
}

func GetDelegationDistInfo(storeName string, cliCtx context.CLIContext, delAddr sdk.AccAddress,
valOperatorAddr sdk.ValAddress) (ddi types.DelegationDistInfo) {
res, err := cliCtx.QueryStore(distrKeeper.GetDelegationDistInfoKey(delAddr, valOperatorAddr), storeName)
if err != nil || len(res) == 0 {
return
}
cliCtx.Codec.MustUnmarshalBinaryLengthPrefixed(res, &ddi)
return
}

func GetValidator(storeName string, cliCtx context.CLIContext, addr sdk.ValAddress) (validator stake.Validator) {
key := stake.GetValidatorKey(addr)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil || len(res) == 0 {
return
}

validator = stakeTypes.MustUnmarshalValidator(cliCtx.Codec, addr, res)
return
}

func GetWithdrawContext(storeName string, cliCtx context.CLIContext, feePool types.FeePool, height int64, validator stakeTypes.Validator) types.WithdrawContext {
key := stakeKeeper.GetLastValidatorPowerKey(validator.OperatorAddr)
res, err := cliCtx.QueryStore(key, storeName)
lastValPower := sdk.ZeroInt()
if err == nil && len(res) != 0 {
cliCtx.Codec.MustUnmarshalBinaryLengthPrefixed(res, &lastValPower)
}

key1 := stakeKeeper.LastTotalPowerKey
res, err = cliCtx.QueryStore(key1, storeName)
lastTotalPower := sdk.ZeroInt()
if err == nil && len(res) != 0 {
cliCtx.Codec.MustUnmarshalBinaryLengthPrefixed(res, &lastTotalPower)
}

return types.NewWithdrawContext(
feePool, height, sdk.NewDecFromInt(lastTotalPower), sdk.NewDecFromInt(lastValPower),
validator.GetCommission())
}
1 change: 1 addition & 0 deletions cmd/iriscli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func main() {
distributioncmd.GetDelegationDistInfo("distr", cdc),
distributioncmd.GetValidatorDistInfo("distr", cdc),
distributioncmd.GetAllDelegationDistInfo("distr", cdc),
distributioncmd.GetRewards("distr", "stake", cdc),
)...)
distributionCmd.AddCommand(
client.PostCommands(
Expand Down
3 changes: 2 additions & 1 deletion docs/cli-client/distribution/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ iriscli distribution --help
| [delegator-distr-info](delegator-distr-info.md) | Query delegator distribution information |
| [validator-distr-info](validator-distr-info.md) | Query validator distribution information |
| [withdraw-address](withdraw-address.md) | Query withdraw address |
| [rewards](rewards.md) | Query all the rewards of validator or delegator |
| [set-withdraw-address](set-withdraw-address.md) | change the default withdraw address for rewards associated with an address |
| [withdraw-rewards](withdraw-rewards.md) | withdraw rewards for either: all-delegations, a delegation, or a validator |
| [withdraw-rewards](withdraw-rewards.md) | withdraw rewards for either: all-delegations, a delegation, or a validator |
50 changes: 50 additions & 0 deletions docs/cli-client/distribution/rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# iriscli distribution rewards

## Description

Query all the rewards of validator or delegator

## Usage

```
iriscli distribution rewards <address> [flags]
```

Print help messages:
```
iriscli distribution rewards --help
```

## Examples

```
iriscli distribution rewards <address>
```
Example response:
```json
{
"total_rewards": [
{
"denom": "iris-atto",
"amount": "235492744310548933957"
}
],
"delegations": [
{
"validator": "iva1q7602ujxxx0urfw7twm0uk5m7n6l9gqsgw4pqy",
"reward": [
{
"denom": "iris-atto",
"amount": "2148801198916275"
}
]
}
],
"commission": [
{
"denom": "iris-atto",
"amount": "235490595509350017682"
}
]
}
```
1 change: 1 addition & 0 deletions docs/zh/cli-client/distribution/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ iriscli distribution --help
| [delegator-distr-info](delegator-distr-info.md) | 查询委托人所有的委托(delegation)的收益分配记录 |
| [validator-distr-info](validator-distr-info.md) | 查询验证人收益分配记录 |
| [withdraw-address](withdraw-address.md) | 查询收益取回地址 |
| [rewards](rewards.md) | 查询验证人或者委托人的所有收益 |
| [set-withdraw-address](set-withdraw-address.md) | 设置收益取回地址 |
| [withdraw-rewards](withdraw-rewards.md) | 发起取回收益的交易 |
50 changes: 50 additions & 0 deletions docs/zh/cli-client/distribution/rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# iriscli distribution rewards

## 介绍

查询验证人或委托人的所有收益

## 用法

```
iriscli distribution rewards <address> [flags]
```

打印帮助信息:
```
iriscli distribution rewards --help
```

## 示例

```
iriscli distribution rewards <address>
```
执行结果示例:
```json
{
"total_rewards": [
{
"denom": "iris-atto",
"amount": "235492744310548933957"
}
],
"delegations": [
{
"validator": "iva1q7602ujxxx0urfw7twm0uk5m7n6l9gqsgw4pqy",
"reward": [
{
"denom": "iris-atto",
"amount": "2148801198916275"
}
]
}
],
"commission": [
{
"denom": "iris-atto",
"amount": "235490595509350017682"
}
]
}
```
Loading