github.com/cosmos/cosmos-sdk@v0.50.10/x/distribution/keeper/grpc_query.go (about)

     1  package keeper
     2  
     3  import (
     4  	"context"
     5  
     6  	"google.golang.org/grpc/codes"
     7  	"google.golang.org/grpc/status"
     8  
     9  	"cosmossdk.io/errors"
    10  	"cosmossdk.io/store/prefix"
    11  
    12  	"github.com/cosmos/cosmos-sdk/runtime"
    13  	sdk "github.com/cosmos/cosmos-sdk/types"
    14  	"github.com/cosmos/cosmos-sdk/types/query"
    15  	"github.com/cosmos/cosmos-sdk/x/distribution/types"
    16  	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    17  )
    18  
    19  var _ types.QueryServer = Querier{}
    20  
    21  type Querier struct {
    22  	Keeper
    23  }
    24  
    25  func NewQuerier(keeper Keeper) Querier {
    26  	return Querier{Keeper: keeper}
    27  }
    28  
    29  // Params queries params of distribution module
    30  func (k Querier) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
    31  	params, err := k.Keeper.Params.Get(ctx)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	return &types.QueryParamsResponse{Params: params}, nil
    37  }
    38  
    39  // ValidatorDistributionInfo query validator's commission and self-delegation rewards
    40  func (k Querier) ValidatorDistributionInfo(ctx context.Context, req *types.QueryValidatorDistributionInfoRequest) (*types.QueryValidatorDistributionInfoResponse, error) {
    41  	if req == nil {
    42  		return nil, status.Error(codes.InvalidArgument, "invalid request")
    43  	}
    44  
    45  	if req.ValidatorAddress == "" {
    46  		return nil, status.Error(codes.InvalidArgument, "empty validator address")
    47  	}
    48  
    49  	valAdr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(req.ValidatorAddress)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	// self-delegation rewards
    55  	val, err := k.stakingKeeper.Validator(ctx, valAdr)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	if val == nil {
    61  		return nil, errors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress)
    62  	}
    63  
    64  	delAdr := sdk.AccAddress(valAdr)
    65  
    66  	del, err := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	if del == nil {
    72  		return nil, types.ErrNoDelegationExists
    73  	}
    74  
    75  	endingPeriod, err := k.IncrementValidatorPeriod(ctx, val)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	rewards, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	// validator's commission
    86  	validatorCommission, err := k.GetValidatorAccumulatedCommission(ctx, valAdr)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	return &types.QueryValidatorDistributionInfoResponse{
    92  		Commission:      validatorCommission.Commission,
    93  		OperatorAddress: delAdr.String(),
    94  		SelfBondRewards: rewards,
    95  	}, nil
    96  }
    97  
    98  // ValidatorOutstandingRewards queries rewards of a validator address
    99  func (k Querier) ValidatorOutstandingRewards(ctx context.Context, req *types.QueryValidatorOutstandingRewardsRequest) (*types.QueryValidatorOutstandingRewardsResponse, error) {
   100  	if req == nil {
   101  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   102  	}
   103  
   104  	if req.ValidatorAddress == "" {
   105  		return nil, status.Error(codes.InvalidArgument, "empty validator address")
   106  	}
   107  
   108  	valAdr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(req.ValidatorAddress)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	validator, err := k.stakingKeeper.Validator(ctx, valAdr)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	if validator == nil {
   119  		return nil, errors.Wrapf(types.ErrNoValidatorExists, req.ValidatorAddress)
   120  	}
   121  
   122  	rewards, err := k.GetValidatorOutstandingRewards(ctx, valAdr)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	return &types.QueryValidatorOutstandingRewardsResponse{Rewards: rewards}, nil
   128  }
   129  
   130  // ValidatorCommission queries accumulated commission for a validator
   131  func (k Querier) ValidatorCommission(ctx context.Context, req *types.QueryValidatorCommissionRequest) (*types.QueryValidatorCommissionResponse, error) {
   132  	if req == nil {
   133  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   134  	}
   135  
   136  	if req.ValidatorAddress == "" {
   137  		return nil, status.Error(codes.InvalidArgument, "empty validator address")
   138  	}
   139  
   140  	valAdr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(req.ValidatorAddress)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	validator, err := k.stakingKeeper.Validator(ctx, valAdr)
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  
   150  	if validator == nil {
   151  		return nil, errors.Wrapf(types.ErrNoValidatorExists, req.ValidatorAddress)
   152  	}
   153  	commission, err := k.GetValidatorAccumulatedCommission(ctx, valAdr)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  
   158  	return &types.QueryValidatorCommissionResponse{Commission: commission}, nil
   159  }
   160  
   161  // ValidatorSlashes queries slash events of a validator
   162  func (k Querier) ValidatorSlashes(ctx context.Context, req *types.QueryValidatorSlashesRequest) (*types.QueryValidatorSlashesResponse, error) {
   163  	if req == nil {
   164  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   165  	}
   166  
   167  	if req.ValidatorAddress == "" {
   168  		return nil, status.Error(codes.InvalidArgument, "empty validator address")
   169  	}
   170  
   171  	if req.EndingHeight < req.StartingHeight {
   172  		return nil, status.Errorf(codes.InvalidArgument, "starting height greater than ending height (%d > %d)", req.StartingHeight, req.EndingHeight)
   173  	}
   174  
   175  	valAddr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(req.ValidatorAddress)
   176  	if err != nil {
   177  		return nil, status.Errorf(codes.InvalidArgument, "invalid validator address")
   178  	}
   179  
   180  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   181  	slashesStore := prefix.NewStore(store, types.GetValidatorSlashEventPrefix(valAddr))
   182  
   183  	events, pageRes, err := query.GenericFilteredPaginate(k.cdc, slashesStore, req.Pagination, func(key []byte, result *types.ValidatorSlashEvent) (*types.ValidatorSlashEvent, error) {
   184  		if result.ValidatorPeriod < req.StartingHeight || result.ValidatorPeriod > req.EndingHeight {
   185  			return nil, nil
   186  		}
   187  
   188  		return result, nil
   189  	}, func() *types.ValidatorSlashEvent {
   190  		return &types.ValidatorSlashEvent{}
   191  	})
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	slashes := []types.ValidatorSlashEvent{}
   197  	for _, event := range events {
   198  		slashes = append(slashes, *event)
   199  	}
   200  
   201  	return &types.QueryValidatorSlashesResponse{Slashes: slashes, Pagination: pageRes}, nil
   202  }
   203  
   204  // DelegationRewards the total rewards accrued by a delegation
   205  func (k Querier) DelegationRewards(ctx context.Context, req *types.QueryDelegationRewardsRequest) (*types.QueryDelegationRewardsResponse, error) {
   206  	if req == nil {
   207  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   208  	}
   209  
   210  	if req.DelegatorAddress == "" {
   211  		return nil, status.Error(codes.InvalidArgument, "empty delegator address")
   212  	}
   213  
   214  	if req.ValidatorAddress == "" {
   215  		return nil, status.Error(codes.InvalidArgument, "empty validator address")
   216  	}
   217  
   218  	valAdr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(req.ValidatorAddress)
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	val, err := k.stakingKeeper.Validator(ctx, valAdr)
   224  	if err != nil {
   225  		return nil, err
   226  	}
   227  
   228  	if val == nil {
   229  		return nil, errors.Wrap(types.ErrNoValidatorExists, req.ValidatorAddress)
   230  	}
   231  
   232  	delAdr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddress)
   233  	if err != nil {
   234  		return nil, err
   235  	}
   236  	del, err := k.stakingKeeper.Delegation(ctx, delAdr, valAdr)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  
   241  	if del == nil {
   242  		return nil, types.ErrNoDelegationExists
   243  	}
   244  
   245  	endingPeriod, err := k.IncrementValidatorPeriod(ctx, val)
   246  	if err != nil {
   247  		return nil, err
   248  	}
   249  
   250  	rewards, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)
   251  	if err != nil {
   252  		return nil, err
   253  	}
   254  
   255  	return &types.QueryDelegationRewardsResponse{Rewards: rewards}, nil
   256  }
   257  
   258  // DelegationTotalRewards the total rewards accrued by a each validator
   259  func (k Querier) DelegationTotalRewards(ctx context.Context, req *types.QueryDelegationTotalRewardsRequest) (*types.QueryDelegationTotalRewardsResponse, error) {
   260  	if req == nil {
   261  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   262  	}
   263  
   264  	if req.DelegatorAddress == "" {
   265  		return nil, status.Error(codes.InvalidArgument, "empty delegator address")
   266  	}
   267  
   268  	total := sdk.DecCoins{}
   269  	var delRewards []types.DelegationDelegatorReward
   270  
   271  	delAdr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddress)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  
   276  	err = k.stakingKeeper.IterateDelegations(
   277  		ctx, delAdr,
   278  		func(_ int64, del stakingtypes.DelegationI) (stop bool) {
   279  			valAddr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(del.GetValidatorAddr())
   280  			if err != nil {
   281  				panic(err)
   282  			}
   283  
   284  			val, err := k.stakingKeeper.Validator(ctx, valAddr)
   285  			if err != nil {
   286  				panic(err)
   287  			}
   288  
   289  			endingPeriod, err := k.IncrementValidatorPeriod(ctx, val)
   290  			if err != nil {
   291  				panic(err)
   292  			}
   293  
   294  			delReward, err := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)
   295  			if err != nil {
   296  				panic(err)
   297  			}
   298  
   299  			delRewards = append(delRewards, types.NewDelegationDelegatorReward(del.GetValidatorAddr(), delReward))
   300  			total = total.Add(delReward...)
   301  			return false
   302  		},
   303  	)
   304  	if err != nil {
   305  		return nil, err
   306  	}
   307  
   308  	return &types.QueryDelegationTotalRewardsResponse{Rewards: delRewards, Total: total}, nil
   309  }
   310  
   311  // DelegatorValidators queries the validators list of a delegator
   312  func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
   313  	if req == nil {
   314  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   315  	}
   316  
   317  	if req.DelegatorAddress == "" {
   318  		return nil, status.Error(codes.InvalidArgument, "empty delegator address")
   319  	}
   320  
   321  	delAdr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddress)
   322  	if err != nil {
   323  		return nil, err
   324  	}
   325  	var validators []string
   326  
   327  	err = k.stakingKeeper.IterateDelegations(
   328  		ctx, delAdr,
   329  		func(_ int64, del stakingtypes.DelegationI) (stop bool) {
   330  			validators = append(validators, del.GetValidatorAddr())
   331  			return false
   332  		},
   333  	)
   334  
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  
   339  	return &types.QueryDelegatorValidatorsResponse{Validators: validators}, nil
   340  }
   341  
   342  // DelegatorWithdrawAddress queries Query/delegatorWithdrawAddress
   343  func (k Querier) DelegatorWithdrawAddress(ctx context.Context, req *types.QueryDelegatorWithdrawAddressRequest) (*types.QueryDelegatorWithdrawAddressResponse, error) {
   344  	if req == nil {
   345  		return nil, status.Error(codes.InvalidArgument, "invalid request")
   346  	}
   347  
   348  	if req.DelegatorAddress == "" {
   349  		return nil, status.Error(codes.InvalidArgument, "empty delegator address")
   350  	}
   351  	delAdr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddress)
   352  	if err != nil {
   353  		return nil, err
   354  	}
   355  
   356  	withdrawAddr, err := k.GetDelegatorWithdrawAddr(ctx, delAdr)
   357  	if err != nil {
   358  		return nil, err
   359  	}
   360  
   361  	return &types.QueryDelegatorWithdrawAddressResponse{WithdrawAddress: withdrawAddr.String()}, nil
   362  }
   363  
   364  // CommunityPool queries the community pool coins
   365  func (k Querier) CommunityPool(ctx context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) {
   366  	pool, err := k.FeePool.Get(ctx)
   367  	if err != nil {
   368  		return nil, err
   369  	}
   370  
   371  	return &types.QueryCommunityPoolResponse{Pool: pool.CommunityPool}, nil
   372  }