Skip to content

Commit

Permalink
feat(cli/api): add validator distribution info grpc gateway get endpo…
Browse files Browse the repository at this point in the history
…int (cosmos#13144)
  • Loading branch information
gsk967 authored and Wryhder committed Oct 26, 2022
1 parent 8e8f17e commit edb9f92
Show file tree
Hide file tree
Showing 10 changed files with 2,647 additions and 515 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13101](https://github.com/cosmos/cosmos-sdk/pull/13101) Remove weights from `simapp/params` and `testutil/sims`. They are now in their respective modules.
* (simapp) [#13107](https://github.com/cosmos/cosmos-sdk/pull/13107) Call `SetIAVLCacheSize` with the configured value in simapp.
* [#12398](https://github.com/cosmos/cosmos-sdk/issues/12398) Refactor all `x` modules to unit-test via mocks and decouple `simapp`.
* [#13144](https://github.com/cosmos/cosmos-sdk/pull/13144) Add validator distribution info grpc gateway get endpoint.

### State Machine Breaking

Expand Down
2,136 changes: 1,709 additions & 427 deletions api/cosmos/distribution/v1beta1/query.pulsar.go

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions api/cosmos/distribution/v1beta1/query_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions proto/cosmos/distribution/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ service Query {
option (google.api.http).get = "/cosmos/distribution/v1beta1/params";
}

// ValidatorDistributionInfo queries validator commision and self-delegation rewards for validator
rpc ValidatorDistributionInfo(QueryValidatorDistributionInfoRequest)
returns (QueryValidatorDistributionInfoResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}";
}

// ValidatorOutstandingRewards queries rewards of a validator address.
rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest)
returns (QueryValidatorOutstandingRewardsResponse) {
Expand Down Expand Up @@ -74,6 +80,26 @@ message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}

// QueryValidatorDistributionInfoRequest is the request type for the Query/ValidatorDistributionInfo RPC method.
message QueryValidatorDistributionInfoRequest {
// validator_address defines the validator address to query for.
string validator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// QueryValidatorDistributionInfoResponse is the response type for the Query/ValidatorDistributionInfo RPC method.
message QueryValidatorDistributionInfoResponse {
// operator_address defines the validator operator address.
string operator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// self_bond_rewards defines the self delegations rewards.
repeated cosmos.base.v1beta1.DecCoin self_bond_rewards = 2
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"];
// commission defines the commision the validator received.
repeated cosmos.base.v1beta1.DecCoin commission = 3 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
}

// QueryValidatorOutstandingRewardsRequest is the request type for the
// Query/ValidatorOutstandingRewards RPC method.
message QueryValidatorOutstandingRewardsRequest {
Expand Down
45 changes: 45 additions & 0 deletions x/distribution/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func GetQueryCmd() *cobra.Command {

distQueryCmd.AddCommand(
GetCmdQueryParams(),
GetCmdQueryValidatorDistributionInfo(),
GetCmdQueryValidatorOutstandingRewards(),
GetCmdQueryValidatorCommission(),
GetCmdQueryValidatorSlashes(),
Expand Down Expand Up @@ -62,6 +63,50 @@ func GetCmdQueryParams() *cobra.Command {
return cmd
}

// GetCmdQueryValidatorDistributionInfo implements the query validator distribution info command.
func GetCmdQueryValidatorDistributionInfo() *cobra.Command {
bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix()

cmd := &cobra.Command{
Use: "validator-distribution-info [validator]",
Args: cobra.ExactArgs(1),
Short: "Query validator distribution info",
Long: strings.TrimSpace(
fmt.Sprintf(`Query validator distribution info.
Example:
$ %s query distribution validator-distribution-info %s1lwjmdnks33xwnmfayc64ycprww49n33mtm92ne
`,
version.AppName, bech32PrefixValAddr,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

validatorAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ValidatorDistributionInfo(cmd.Context(), &types.QueryValidatorDistributionInfoRequest{
ValidatorAddress: validatorAddr.String(),
})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)
return cmd
}

// GetCmdQueryValidatorOutstandingRewards implements the query validator
// outstanding rewards command.
func GetCmdQueryValidatorOutstandingRewards() *cobra.Command {
Expand Down
38 changes: 38 additions & 0 deletions x/distribution/client/testutil/grpc_query_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,44 @@ func (s *GRPCQueryTestSuite) TestQueryParamsGRPC() {
}
}

func (s *GRPCQueryTestSuite) TestQueryValidatorDistributionInfoGRPC() {
val := s.network.Validators[0]
baseURL := val.APIAddress

testCases := []struct {
name string
url string
expErr bool
respType proto.Message
}{
{
"gRPC request with wrong validator address",
fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, "wrongAddress"),
true,
&types.QueryValidatorDistributionInfoResponse{},
},
{
"gRPC request with valid validator address ",
fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, val.ValAddress.String()),
false,
&types.QueryValidatorDistributionInfoResponse{},
},
}

for _, tc := range testCases {
tc := tc
resp, err := rest.GetRequest(tc.url)
s.Run(tc.name, func() {
if tc.expErr {
s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
} else {
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
}
})
}
}

func (s *GRPCQueryTestSuite) TestQueryOutstandingRewardsGRPC() {
val := s.network.Validators[0]
baseURL := val.APIAddress
Expand Down
42 changes: 42 additions & 0 deletions x/distribution/client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,48 @@ withdraw_addr_enabled: true`,
}
}

func (s *IntegrationTestSuite) TestGetCmdQueryValidatorDistributionInfo() {
val := s.network.Validators[0]

testCases := []struct {
name string
args []string
expErr bool
}{
{
"invalid val address",
[]string{"invalid address", fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
true,
},
{
"json output",
[]string{val.ValAddress.String(), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
false,
},
{
"text output",
[]string{val.ValAddress.String(), fmt.Sprintf("--%s=text", tmcli.OutputFlag)},
false,
},
}

for _, tc := range testCases {
tc := tc

s.Run(tc.name, func() {
cmd := cli.GetCmdQueryValidatorDistributionInfo()
clientCtx := val.ClientCtx

_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
}
})
}
}

func (s *IntegrationTestSuite) TestGetCmdQueryValidatorOutstandingRewards() {
val := s.network.Validators[0]

Expand Down
43 changes: 43 additions & 0 deletions x/distribution/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,49 @@ func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*type
return &types.QueryParamsResponse{Params: params}, nil
}

// ValidatorDistributionInfo query validator's commission and self-delegation rewards
func (k Querier) ValidatorDistributionInfo(c context.Context, req *types.QueryValidatorDistributionInfoRequest) (*types.QueryValidatorDistributionInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

if req.ValidatorAddress == "" {
return nil, status.Error(codes.InvalidArgument, "empty validator address")
}

ctx := sdk.UnwrapSDKContext(c)

valAdr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
if err != nil {
return nil, err
}

// self-delegation rewards
val := k.stakingKeeper.Validator(ctx, valAdr)
if val == nil {
return nil, sdkerrors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress)
}

delAdr := sdk.AccAddress(valAdr)

del := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
if del == nil {
return nil, types.ErrNoDelegationExists
}

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

// validator's commission
validatorCommission := k.GetValidatorAccumulatedCommission(ctx, valAdr)

return &types.QueryValidatorDistributionInfoResponse{
Commission: validatorCommission.Commission,
OperatorAddress: delAdr.String(),
SelfBondRewards: rewards,
}, nil
}

// ValidatorOutstandingRewards queries rewards of a validator address
func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.QueryValidatorOutstandingRewardsRequest) (*types.QueryValidatorOutstandingRewardsResponse, error) {
if req == nil {
Expand Down
Loading

0 comments on commit edb9f92

Please sign in to comment.