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 }