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

x/distribution: gRPC query service #6600

Merged
merged 44 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7253a7b
WIP: adding grpc
atheeshp Jun 30, 2020
49ecf4c
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jun 30, 2020
f7d6a3f
added grpc for query withdraw address
atheeshp Jun 30, 2020
18794c8
Fix outstanding rewards query
sahith-narahari Jul 4, 2020
ff9f779
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 4, 2020
028d970
Merge branch 'atheesh/5921-grpc-x-distribution' of github.com:cosmos/…
atheeshp Jul 4, 2020
8cd803d
added inteerface registry
atheeshp Jul 4, 2020
8ad7552
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 5, 2020
73c8260
added gRPC for delegation rewards
atheeshp Jul 5, 2020
f65d0cb
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 5, 2020
c09c661
added remaining commands
atheeshp Jul 6, 2020
a6365be
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 6, 2020
5779013
lint issue
atheeshp Jul 6, 2020
c5d169f
added tests
atheeshp Jul 6, 2020
4827d51
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 6, 2020
c2205b3
added test for community pool
atheeshp Jul 6, 2020
64ed973
fixed error
atheeshp Jul 6, 2020
e46323e
added test for delegator validators
atheeshp Jul 6, 2020
6cce6fd
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 7, 2020
68f6f2e
updated to use test suite
atheeshp Jul 7, 2020
9a81ca4
updated tests
atheeshp Jul 7, 2020
d9cb8e1
more test checks added
atheeshp Jul 7, 2020
4ff5055
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 7, 2020
5a60433
updated tests
atheeshp Jul 7, 2020
beea59e
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 7, 2020
860d861
Add sdk wrap
anilcse Jul 7, 2020
a3ab8b3
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 8, 2020
38968d3
removed pagination for outstanding rewards
atheeshp Jul 8, 2020
47382de
fixed distr tests issue
atheeshp Jul 8, 2020
b7d5c1e
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 8, 2020
5774377
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 9, 2020
ab551f3
fixed slashes issue
atheeshp Jul 9, 2020
fd93254
migrated tests to table driven tests
atheeshp Jul 9, 2020
99a3c16
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 9, 2020
7df5225
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 10, 2020
6ae0dfd
docs updated
atheeshp Jul 10, 2020
d585c88
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 13, 2020
161a89c
review changes
atheeshp Jul 13, 2020
e037e0d
review changes
atheeshp Jul 13, 2020
51a0c2f
Merge branch 'master' of github.com:cosmos/cosmos-sdk into atheesh/59…
atheeshp Jul 13, 2020
3dbee1e
Merge branch 'master' into atheesh/5921-grpc-x-distribution
alexanderbez Jul 13, 2020
f2c8134
review changes
atheeshp Jul 13, 2020
6e124c4
Update x/distribution/keeper/grpc_query.go
fedekunze Jul 13, 2020
37c7455
Merge branch 'master' into atheesh/5921-grpc-x-distribution
fedekunze Jul 13, 2020
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
14 changes: 14 additions & 0 deletions proto/cosmos/distribution/distribution.proto
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,17 @@ message DelegatorStartingInfo {
uint64 height = 3
[(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"];
}

// DelegationDelegatorReward defines the properties
// of a delegator's delegation reward.
message DelegationDelegatorReward {
bytes validator_address = 1 [
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress",
(gogoproto.moretags) = "yaml:\"validator_address\""
];

repeated cosmos.DecCoin reward = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
}
141 changes: 141 additions & 0 deletions proto/cosmos/distribution/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
syntax = "proto3";
package cosmos.distribution;

import "cosmos/query/pagination.proto";
import "gogoproto/gogo.proto";
import "cosmos/cosmos.proto";
import "cosmos/distribution/distribution.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";

// Query defines the gRPC querier service for distribution module
service Query {
// Params queries params of distribution module
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {}

// ValidatorOutstandingRewards queries rewards of a validator address
rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest) returns (QueryValidatorOutstandingRewardsResponse) {}

// ValidatorCommission queries accumulated commission for a validator
rpc ValidatorCommission (QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) {}

// ValidatorSlashes queries slash events of a validator
rpc ValidatorSlashes (QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) {}

// DelegationRewards the total rewards accrued by a delegation
rpc DelegationRewards (QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) {}

// DelegationTotalRewards the total rewards accrued by a each validator
rpc DelegationTotalRewards (QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) {}

// DelegatorValidators queries the validators of a delegator
rpc DelegatorValidators (QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) {}

// DelegatorWithdrawAddress queries withdraw address of a delegator
rpc DelegatorWithdrawAddress (QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) {}

// CommunityPool queries the community pool coins
rpc CommunityPool (QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) {}
}

// QueryParamsRequest is the request type for the Query/Params RPC method
message QueryParamsRequest { }

// QueryParamsResponse is the response type for the Query/Params RPC method
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}

// QueryValidatorOutstandingRewardsRequest is the request type for the Query/ValidatorOutstandingRewards RPC method
message QueryValidatorOutstandingRewardsRequest {
bytes validator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}

// QueryValidatorOutstandingRewardsResponse is the response type for the Query/ValidatorOutstandingRewards RPC method
message QueryValidatorOutstandingRewardsResponse {
ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false];
}

// QueryValidatorCommissionRequest is the request type for the Query/ValidatorCommission RPC method
message QueryValidatorCommissionRequest {
bytes validator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}

// QueryValidatorCommissionResponse is the response type for the Query/ValidatorCommission RPC method
message QueryValidatorCommissionResponse {
ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false];
}

// QueryValidatorSlashesRequest is the request type for the Query/ValidatorSlashes RPC method
message QueryValidatorSlashesRequest {
bytes validator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
uint64 starting_height = 2;
uint64 ending_height = 3;
cosmos.query.PageRequest req = 4;
}

// QueryValidatorSlashesResponse is the response type for the Query/ValidatorSlashes RPC method
message QueryValidatorSlashesResponse {
repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false];

cosmos.query.PageResponse res = 2;
}

// QueryDelegationRewardsRequest is the request type for the Query/DelegationRewards RPC method
message QueryDelegationRewardsRequest {
bytes delegator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
bytes validator_address = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}

// QueryDelegationRewardsResponse is the response type for the Query/DelegationRewards RPC method
message QueryDelegationRewardsResponse {
repeated cosmos.DecCoin rewards = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"
];
}

// QueryDelegationTotalRewardsRequest is the request type for the Query/DelegationTotalRewards RPC method
message QueryDelegationTotalRewardsRequest {
bytes delegator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
}

// QueryDelegationTotalRewardsResponse is the response type for the Query/DelegationTotalRewards RPC method
message QueryDelegationTotalRewardsResponse {
repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false];
repeated cosmos.DecCoin total = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"
];
}

// QueryDelegatorValidatorsRequest is the request type for the Query/DelegatorValidators RPC method
message QueryDelegatorValidatorsRequest {
bytes delegator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
}

// QueryDelegatorValidatorsResponse is the response type for the Query/DelegatorValidators RPC method
message QueryDelegatorValidatorsResponse {
repeated bytes validators = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}

// QueryDelegatorWithdrawAddressRequest is the request type for the Query/DelegatorWithdrawAddress RPC method
message QueryDelegatorWithdrawAddressRequest {
bytes delegator_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
}

// QueryDelegatorWithdrawAddressResponse is the response type for the Query/DelegatorWithdrawAddress RPC method
message QueryDelegatorWithdrawAddressResponse {
bytes withdraw_address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
}

// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC method
message QueryCommunityPoolRequest {}

// QueryCommunityPoolResponse is the response type for the Query/CommunityPool RPC method
message QueryCommunityPoolResponse {
repeated cosmos.DecCoin pool = 1 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
}
178 changes: 178 additions & 0 deletions x/distribution/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package keeper

import (
"context"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/staking/exported"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

var _ types.QueryServer = Keeper{}

// Params queries params of distribution module
func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
var params types.Params
k.paramSpace.GetParamSet(ctx, &params)

return &types.QueryParamsResponse{Params: params}, nil
}

// ValidatorOutstandingRewards queries rewards of a validator address
func (k Keeper) ValidatorOutstandingRewards(c context.Context, req *types.QueryValidatorOutstandingRewardsRequest) (*types.QueryValidatorOutstandingRewardsResponse, error) {
if req.String() == "" || req.ValidatorAddress.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}
atheeshp marked this conversation as resolved.
Show resolved Hide resolved

ctx := sdk.UnwrapSDKContext(c)
rewards := k.GetValidatorOutstandingRewards(ctx, req.ValidatorAddress)

return &types.QueryValidatorOutstandingRewardsResponse{Rewards: rewards}, nil
}

// ValidatorCommission queries accumulated commission for a validator
func (k Keeper) ValidatorCommission(c context.Context, req *types.QueryValidatorCommissionRequest) (*types.QueryValidatorCommissionResponse, error) {
if req.String() == "" || req.ValidatorAddress.Empty() {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)
commission := k.GetValidatorAccumulatedCommission(ctx, req.ValidatorAddress)

return &types.QueryValidatorCommissionResponse{Commission: commission}, nil
}

// ValidatorSlashes queries slash events of a validator
func (k Keeper) ValidatorSlashes(c context.Context, req *types.QueryValidatorSlashesRequest) (*types.QueryValidatorSlashesResponse, error) {
if req.String() == "" || req.ValidatorAddress.Empty() || req.EndingHeight < req.StartingHeight {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
atheeshp marked this conversation as resolved.
Show resolved Hide resolved
}

ctx := sdk.UnwrapSDKContext(c)
events := make([]types.ValidatorSlashEvent, 0)
store := ctx.KVStore(k.storeKey)
slashesStore := prefix.NewStore(store, types.GetValidatorSlashEventPrefix(req.ValidatorAddress))

res, err := query.FilteredPaginate(slashesStore, req.Req, func(key []byte, value []byte, accumulate bool) (bool, error) {
var result types.ValidatorSlashEvent
err := k.cdc.UnmarshalBinaryBare(value, &result)

if err != nil {
return false, err
}

if result.ValidatorPeriod < req.StartingHeight || result.ValidatorPeriod > req.EndingHeight {
return false, nil
}

if accumulate {
events = append(events, result)
}
return true, nil
})

if err != nil {
return &types.QueryValidatorSlashesResponse{}, err
}

return &types.QueryValidatorSlashesResponse{Slashes: events, Res: res}, nil
}

// DelegationRewards the total rewards accrued by a delegation
func (k Keeper) DelegationRewards(c context.Context, req *types.QueryDelegationRewardsRequest) (*types.QueryDelegationRewardsResponse, error) {
if req.String() == "" || req.DelegatorAddress.Empty() || req.ValidatorAddress.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)

val := k.stakingKeeper.Validator(ctx, req.ValidatorAddress)
if val == nil {
return nil, sdkerrors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress.String())
}

del := k.stakingKeeper.Delegation(ctx, req.DelegatorAddress, req.ValidatorAddress)
if del == nil {
return nil, types.ErrNoDelegationExists
}

endingPeriod := k.IncrementValidatorPeriod(ctx, val)
rewards := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)

return &types.QueryDelegationRewardsResponse{Rewards: rewards}, nil
}

// DelegationTotalRewards the total rewards accrued by a each validator
func (k Keeper) DelegationTotalRewards(c context.Context, req *types.QueryDelegationTotalRewardsRequest) (*types.QueryDelegationTotalRewardsResponse, error) {
if req.String() == "" || req.DelegatorAddress.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)

total := sdk.DecCoins{}
var delRewards []types.DelegationDelegatorReward

k.stakingKeeper.IterateDelegations(
ctx, req.DelegatorAddress,
func(_ int64, del exported.DelegationI) (stop bool) {
valAddr := del.GetValidatorAddr()
val := k.stakingKeeper.Validator(ctx, valAddr)
endingPeriod := k.IncrementValidatorPeriod(ctx, val)
delReward := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)

delRewards = append(delRewards, types.NewDelegationDelegatorReward(valAddr, delReward))
total = total.Add(delReward...)
return false
},
)

return &types.QueryDelegationTotalRewardsResponse{Rewards: delRewards, Total: total}, nil
}

// DelegatorValidators queries the validators list of a delegator
func (k Keeper) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
if req.String() == "" || req.DelegatorAddress.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)

var validators []sdk.ValAddress

k.stakingKeeper.IterateDelegations(
ctx, req.DelegatorAddress,
func(_ int64, del exported.DelegationI) (stop bool) {
validators = append(validators, del.GetValidatorAddr())
return false
},
)

return &types.QueryDelegatorValidatorsResponse{Validators: validators}, nil
}

// DelegatorWithdrawAddress queries Query/delegatorWithdrawAddress
func (k Keeper) DelegatorWithdrawAddress(c context.Context, req *types.QueryDelegatorWithdrawAddressRequest) (*types.QueryDelegatorWithdrawAddressResponse, error) {
if req.String() == "" || req.DelegatorAddress.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, req.DelegatorAddress)

return &types.QueryDelegatorWithdrawAddressResponse{WithdrawAddress: withdrawAddr}, nil
}

// CommunityPool queries the community pool coins
func (k Keeper) CommunityPool(c context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
pool := k.GetFeePoolCommunityCoins(ctx)

return &types.QueryCommunityPoolResponse{Pool: pool}, nil
}
Loading