github.com/Finschia/finschia-sdk@v0.48.1/x/staking/keeper/grpc_query.go (about) 1 package keeper 2 3 import ( 4 "context" 5 "strings" 6 7 "google.golang.org/grpc/codes" 8 "google.golang.org/grpc/status" 9 10 "github.com/Finschia/finschia-sdk/store/prefix" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 "github.com/Finschia/finschia-sdk/types/query" 13 "github.com/Finschia/finschia-sdk/x/staking/types" 14 ) 15 16 // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper 17 type Querier struct { 18 Keeper 19 } 20 21 var _ types.QueryServer = Querier{} 22 23 // Validators queries all validators that match the given status 24 func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) { 25 if req == nil { 26 return nil, status.Error(codes.InvalidArgument, "empty request") 27 } 28 29 // validate the provided status, return all the validators if the status is empty 30 if req.Status != "" && !(req.Status == types.Bonded.String() || req.Status == types.Unbonded.String() || req.Status == types.Unbonding.String()) { 31 return nil, status.Errorf(codes.InvalidArgument, "invalid validator status %s", req.Status) 32 } 33 34 var validators types.Validators 35 ctx := sdk.UnwrapSDKContext(c) 36 37 store := ctx.KVStore(k.storeKey) 38 valStore := prefix.NewStore(store, types.ValidatorsKey) 39 40 pageRes, err := query.FilteredPaginate(valStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { 41 val, err := types.UnmarshalValidator(k.cdc, value) 42 if err != nil { 43 return false, err 44 } 45 46 if req.Status != "" && !strings.EqualFold(val.GetStatus().String(), req.Status) { 47 return false, nil 48 } 49 50 if accumulate { 51 validators = append(validators, val) 52 } 53 54 return true, nil 55 }) 56 if err != nil { 57 return nil, status.Error(codes.Internal, err.Error()) 58 } 59 60 return &types.QueryValidatorsResponse{Validators: validators, Pagination: pageRes}, nil 61 } 62 63 // Validator queries validator info for given validator address 64 func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) { 65 if req == nil { 66 return nil, status.Error(codes.InvalidArgument, "empty request") 67 } 68 69 if req.ValidatorAddr == "" { 70 return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty") 71 } 72 73 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 74 if err != nil { 75 return nil, err 76 } 77 78 ctx := sdk.UnwrapSDKContext(c) 79 validator, found := k.GetValidator(ctx, valAddr) 80 if !found { 81 return nil, status.Errorf(codes.NotFound, "validator %s not found", req.ValidatorAddr) 82 } 83 84 return &types.QueryValidatorResponse{Validator: validator}, nil 85 } 86 87 // ValidatorDelegations queries delegate info for given validator 88 func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) { 89 if req == nil { 90 return nil, status.Error(codes.InvalidArgument, "empty request") 91 } 92 93 if req.ValidatorAddr == "" { 94 return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty") 95 } 96 var delegations []types.Delegation 97 ctx := sdk.UnwrapSDKContext(c) 98 99 store := ctx.KVStore(k.storeKey) 100 valStore := prefix.NewStore(store, types.DelegationKey) 101 pageRes, err := query.FilteredPaginate(valStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { 102 delegation, err := types.UnmarshalDelegation(k.cdc, value) 103 if err != nil { 104 return false, err 105 } 106 107 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 108 if err != nil { 109 return false, err 110 } 111 112 if !delegation.GetValidatorAddr().Equals(valAddr) { 113 return false, nil 114 } 115 116 if accumulate { 117 delegations = append(delegations, delegation) 118 } 119 return true, nil 120 }) 121 if err != nil { 122 return nil, status.Error(codes.Internal, err.Error()) 123 } 124 125 delResponses, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations) 126 if err != nil { 127 return nil, status.Error(codes.Internal, err.Error()) 128 } 129 130 return &types.QueryValidatorDelegationsResponse{ 131 DelegationResponses: delResponses, Pagination: pageRes, 132 }, nil 133 } 134 135 // ValidatorUnbondingDelegations queries unbonding delegations of a validator 136 func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) { 137 if req == nil { 138 return nil, status.Error(codes.InvalidArgument, "empty request") 139 } 140 141 if req.ValidatorAddr == "" { 142 return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty") 143 } 144 var ubds types.UnbondingDelegations 145 ctx := sdk.UnwrapSDKContext(c) 146 147 store := ctx.KVStore(k.storeKey) 148 149 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 150 if err != nil { 151 return nil, err 152 } 153 154 srcValPrefix := types.GetUBDsByValIndexKey(valAddr) 155 ubdStore := prefix.NewStore(store, srcValPrefix) 156 pageRes, err := query.Paginate(ubdStore, req.Pagination, func(key []byte, value []byte) error { 157 storeKey := types.GetUBDKeyFromValIndexKey(append(srcValPrefix, key...)) 158 storeValue := store.Get(storeKey) 159 160 ubd, err := types.UnmarshalUBD(k.cdc, storeValue) 161 if err != nil { 162 return err 163 } 164 ubds = append(ubds, ubd) 165 return nil 166 }) 167 if err != nil { 168 return nil, status.Error(codes.Internal, err.Error()) 169 } 170 171 return &types.QueryValidatorUnbondingDelegationsResponse{ 172 UnbondingResponses: ubds, 173 Pagination: pageRes, 174 }, nil 175 } 176 177 // Delegation queries delegate info for given validator delegator pair 178 func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) { 179 if req == nil { 180 return nil, status.Error(codes.InvalidArgument, "empty request") 181 } 182 183 if req.DelegatorAddr == "" { 184 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 185 } 186 if req.ValidatorAddr == "" { 187 return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty") 188 } 189 190 ctx := sdk.UnwrapSDKContext(c) 191 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 192 if err != nil { 193 return nil, err 194 } 195 196 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 197 if err != nil { 198 return nil, err 199 } 200 201 delegation, found := k.GetDelegation(ctx, delAddr, valAddr) 202 if !found { 203 return nil, status.Errorf( 204 codes.NotFound, 205 "delegation with delegator %s not found for validator %s", 206 req.DelegatorAddr, req.ValidatorAddr) 207 } 208 209 delResponse, err := DelegationToDelegationResponse(ctx, k.Keeper, delegation) 210 if err != nil { 211 return nil, status.Error(codes.Internal, err.Error()) 212 } 213 214 return &types.QueryDelegationResponse{DelegationResponse: &delResponse}, nil 215 } 216 217 // UnbondingDelegation queries unbonding info for give validator delegator pair 218 func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) { 219 if req == nil { 220 return nil, status.Errorf(codes.InvalidArgument, "empty request") 221 } 222 223 if req.DelegatorAddr == "" { 224 return nil, status.Errorf(codes.InvalidArgument, "delegator address cannot be empty") 225 } 226 if req.ValidatorAddr == "" { 227 return nil, status.Errorf(codes.InvalidArgument, "validator address cannot be empty") 228 } 229 230 ctx := sdk.UnwrapSDKContext(c) 231 232 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 233 if err != nil { 234 return nil, err 235 } 236 237 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 238 if err != nil { 239 return nil, err 240 } 241 242 unbond, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) 243 if !found { 244 return nil, status.Errorf( 245 codes.NotFound, 246 "unbonding delegation with delegator %s not found for validator %s", 247 req.DelegatorAddr, req.ValidatorAddr) 248 } 249 250 return &types.QueryUnbondingDelegationResponse{Unbond: unbond}, nil 251 } 252 253 // DelegatorDelegations queries all delegations of a give delegator address 254 func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) { 255 if req == nil { 256 return nil, status.Errorf(codes.InvalidArgument, "empty request") 257 } 258 259 if req.DelegatorAddr == "" { 260 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 261 } 262 var delegations types.Delegations 263 ctx := sdk.UnwrapSDKContext(c) 264 265 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 266 if err != nil { 267 return nil, err 268 } 269 270 store := ctx.KVStore(k.storeKey) 271 delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr)) 272 pageRes, err := query.Paginate(delStore, req.Pagination, func(key []byte, value []byte) error { 273 delegation, err := types.UnmarshalDelegation(k.cdc, value) 274 if err != nil { 275 return err 276 } 277 delegations = append(delegations, delegation) 278 return nil 279 }) 280 if err != nil { 281 return nil, status.Error(codes.Internal, err.Error()) 282 } 283 284 delegationResps, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations) 285 if err != nil { 286 return nil, status.Error(codes.Internal, err.Error()) 287 } 288 289 return &types.QueryDelegatorDelegationsResponse{DelegationResponses: delegationResps, Pagination: pageRes}, nil 290 } 291 292 // DelegatorValidator queries validator info for given delegator validator pair 293 func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) { 294 if req == nil { 295 return nil, status.Error(codes.InvalidArgument, "empty request") 296 } 297 298 if req.DelegatorAddr == "" { 299 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 300 } 301 if req.ValidatorAddr == "" { 302 return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty") 303 } 304 305 ctx := sdk.UnwrapSDKContext(c) 306 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 307 if err != nil { 308 return nil, err 309 } 310 311 valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) 312 if err != nil { 313 return nil, err 314 } 315 316 validator, err := k.GetDelegatorValidator(ctx, delAddr, valAddr) 317 if err != nil { 318 return nil, status.Error(codes.Internal, err.Error()) 319 } 320 321 return &types.QueryDelegatorValidatorResponse{Validator: validator}, nil 322 } 323 324 // DelegatorUnbondingDelegations queries all unbonding delegations of a given delegator address 325 func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) { 326 if req == nil { 327 return nil, status.Error(codes.InvalidArgument, "empty request") 328 } 329 330 if req.DelegatorAddr == "" { 331 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 332 } 333 var unbondingDelegations types.UnbondingDelegations 334 ctx := sdk.UnwrapSDKContext(c) 335 336 store := ctx.KVStore(k.storeKey) 337 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 338 if err != nil { 339 return nil, err 340 } 341 342 unbStore := prefix.NewStore(store, types.GetUBDsKey(delAddr)) 343 pageRes, err := query.Paginate(unbStore, req.Pagination, func(key []byte, value []byte) error { 344 unbond, err := types.UnmarshalUBD(k.cdc, value) 345 if err != nil { 346 return err 347 } 348 unbondingDelegations = append(unbondingDelegations, unbond) 349 return nil 350 }) 351 if err != nil { 352 return nil, status.Error(codes.Internal, err.Error()) 353 } 354 355 return &types.QueryDelegatorUnbondingDelegationsResponse{ 356 UnbondingResponses: unbondingDelegations, Pagination: pageRes, 357 }, nil 358 } 359 360 // HistoricalInfo queries the historical info for given height 361 func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) { 362 if req == nil { 363 return nil, status.Error(codes.InvalidArgument, "empty request") 364 } 365 366 if req.Height < 0 { 367 return nil, status.Error(codes.InvalidArgument, "height cannot be negative") 368 } 369 ctx := sdk.UnwrapSDKContext(c) 370 hi, found := k.GetHistoricalInfo(ctx, req.Height) 371 if !found { 372 return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height) 373 } 374 375 return &types.QueryHistoricalInfoResponse{Hist: &hi}, nil 376 } 377 378 // Redelegations queries redelegations of given address 379 func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) { 380 if req == nil { 381 return nil, status.Error(codes.InvalidArgument, "empty request") 382 } 383 384 var redels types.Redelegations 385 var pageRes *query.PageResponse 386 var err error 387 388 ctx := sdk.UnwrapSDKContext(c) 389 store := ctx.KVStore(k.storeKey) 390 switch { 391 case req.DelegatorAddr != "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr != "": 392 redels, err = queryRedelegation(ctx, k, req) 393 case req.DelegatorAddr == "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr == "": 394 redels, pageRes, err = queryRedelegationsFromSrcValidator(store, k, req) 395 default: 396 redels, pageRes, err = queryAllRedelegations(store, k, req) 397 } 398 if err != nil { 399 return nil, status.Error(codes.Internal, err.Error()) 400 } 401 redelResponses, err := RedelegationsToRedelegationResponses(ctx, k.Keeper, redels) 402 if err != nil { 403 return nil, status.Error(codes.Internal, err.Error()) 404 } 405 406 return &types.QueryRedelegationsResponse{RedelegationResponses: redelResponses, Pagination: pageRes}, nil 407 } 408 409 // DelegatorValidators queries all validators info for given delegator address 410 func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) { 411 if req == nil { 412 return nil, status.Error(codes.InvalidArgument, "empty request") 413 } 414 415 if req.DelegatorAddr == "" { 416 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 417 } 418 var validators types.Validators 419 ctx := sdk.UnwrapSDKContext(c) 420 421 store := ctx.KVStore(k.storeKey) 422 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 423 if err != nil { 424 return nil, err 425 } 426 427 delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr)) 428 pageRes, err := query.Paginate(delStore, req.Pagination, func(key []byte, value []byte) error { 429 delegation, err := types.UnmarshalDelegation(k.cdc, value) 430 if err != nil { 431 return err 432 } 433 434 validator, found := k.GetValidator(ctx, delegation.GetValidatorAddr()) 435 if !found { 436 return types.ErrNoValidatorFound 437 } 438 439 validators = append(validators, validator) 440 return nil 441 }) 442 if err != nil { 443 return nil, status.Error(codes.Internal, err.Error()) 444 } 445 446 return &types.QueryDelegatorValidatorsResponse{Validators: validators, Pagination: pageRes}, nil 447 } 448 449 // Pool queries the pool info 450 func (k Querier) Pool(c context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) { 451 ctx := sdk.UnwrapSDKContext(c) 452 bondDenom := k.BondDenom(ctx) 453 bondedPool := k.GetBondedPool(ctx) 454 notBondedPool := k.GetNotBondedPool(ctx) 455 456 pool := types.NewPool( 457 k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, 458 k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, 459 ) 460 461 return &types.QueryPoolResponse{Pool: pool}, nil 462 } 463 464 // Params queries the staking parameters 465 func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { 466 ctx := sdk.UnwrapSDKContext(c) 467 params := k.GetParams(ctx) 468 469 return &types.QueryParamsResponse{Params: params}, nil 470 } 471 472 func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) { 473 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 474 if err != nil { 475 return nil, err 476 } 477 478 srcValAddr, err := sdk.ValAddressFromBech32(req.SrcValidatorAddr) 479 if err != nil { 480 return nil, err 481 } 482 483 dstValAddr, err := sdk.ValAddressFromBech32(req.DstValidatorAddr) 484 if err != nil { 485 return nil, err 486 } 487 488 redel, found := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr) 489 if !found { 490 return nil, status.Errorf( 491 codes.NotFound, 492 "redelegation not found for delegator address %s from validator address %s", 493 req.DelegatorAddr, req.SrcValidatorAddr) 494 } 495 redels = []types.Redelegation{redel} 496 497 return redels, err 498 } 499 500 func queryRedelegationsFromSrcValidator(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { 501 valAddr, err := sdk.ValAddressFromBech32(req.SrcValidatorAddr) 502 if err != nil { 503 return nil, nil, err 504 } 505 506 srcValPrefix := types.GetREDsFromValSrcIndexKey(valAddr) 507 redStore := prefix.NewStore(store, srcValPrefix) 508 res, err = query.Paginate(redStore, req.Pagination, func(key []byte, value []byte) error { 509 storeKey := types.GetREDKeyFromValSrcIndexKey(append(srcValPrefix, key...)) 510 storeValue := store.Get(storeKey) 511 red, err := types.UnmarshalRED(k.cdc, storeValue) 512 if err != nil { 513 return err 514 } 515 redels = append(redels, red) 516 return nil 517 }) 518 519 return redels, res, err 520 } 521 522 func queryAllRedelegations(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { 523 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 524 if err != nil { 525 return nil, nil, err 526 } 527 528 redStore := prefix.NewStore(store, types.GetREDsKey(delAddr)) 529 res, err = query.Paginate(redStore, req.Pagination, func(key []byte, value []byte) error { 530 redelegation, err := types.UnmarshalRED(k.cdc, value) 531 if err != nil { 532 return err 533 } 534 redels = append(redels, redelegation) 535 return nil 536 }) 537 538 return redels, res, err 539 }