github.com/Finschia/finschia-sdk@v0.48.1/x/staking/keeper/querier.go (about) 1 package keeper 2 3 import ( 4 "errors" 5 "strings" 6 7 abci "github.com/tendermint/tendermint/abci/types" 8 9 "github.com/Finschia/finschia-sdk/client" 10 "github.com/Finschia/finschia-sdk/codec" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 13 "github.com/Finschia/finschia-sdk/x/staking/types" 14 ) 15 16 // creates a querier for staking REST endpoints 17 func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { 18 return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { 19 switch path[0] { 20 case types.QueryValidators: 21 return queryValidators(ctx, req, k, legacyQuerierCdc) 22 23 case types.QueryValidator: 24 return queryValidator(ctx, req, k, legacyQuerierCdc) 25 26 case types.QueryValidatorDelegations: 27 return queryValidatorDelegations(ctx, req, k, legacyQuerierCdc) 28 29 case types.QueryValidatorUnbondingDelegations: 30 return queryValidatorUnbondingDelegations(ctx, req, k, legacyQuerierCdc) 31 32 case types.QueryDelegation: 33 return queryDelegation(ctx, req, k, legacyQuerierCdc) 34 35 case types.QueryUnbondingDelegation: 36 return queryUnbondingDelegation(ctx, req, k, legacyQuerierCdc) 37 38 case types.QueryDelegatorDelegations: 39 return queryDelegatorDelegations(ctx, req, k, legacyQuerierCdc) 40 41 case types.QueryDelegatorUnbondingDelegations: 42 return queryDelegatorUnbondingDelegations(ctx, req, k, legacyQuerierCdc) 43 44 case types.QueryRedelegations: 45 return queryRedelegations(ctx, req, k, legacyQuerierCdc) 46 47 case types.QueryDelegatorValidators: 48 return queryDelegatorValidators(ctx, req, k, legacyQuerierCdc) 49 50 case types.QueryDelegatorValidator: 51 return queryDelegatorValidator(ctx, req, k, legacyQuerierCdc) 52 53 case types.QueryHistoricalInfo: 54 return queryHistoricalInfo(ctx, req, k, legacyQuerierCdc) 55 56 case types.QueryPool: 57 return queryPool(ctx, k, legacyQuerierCdc) 58 59 case types.QueryParameters: 60 return queryParameters(ctx, k, legacyQuerierCdc) 61 62 default: 63 return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) 64 } 65 } 66 } 67 68 func queryValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 69 var params types.QueryValidatorsParams 70 71 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 72 if err != nil { 73 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 74 } 75 76 validators := k.GetAllValidators(ctx) 77 filteredVals := make(types.Validators, 0, len(validators)) 78 79 for _, val := range validators { 80 if strings.EqualFold(val.GetStatus().String(), params.Status) { 81 filteredVals = append(filteredVals, val) 82 } 83 } 84 85 start, end := client.Paginate(len(filteredVals), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators)) 86 if start < 0 || end < 0 { 87 filteredVals = []types.Validator{} 88 } else { 89 filteredVals = filteredVals[start:end] 90 } 91 92 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, filteredVals) 93 if err != nil { 94 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 95 } 96 97 return res, nil 98 } 99 100 func queryValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 101 var params types.QueryValidatorParams 102 103 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 104 if err != nil { 105 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 106 } 107 108 validator, found := k.GetValidator(ctx, params.ValidatorAddr) 109 if !found { 110 return nil, types.ErrNoValidatorFound 111 } 112 113 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, validator) 114 if err != nil { 115 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 116 } 117 118 return res, nil 119 } 120 121 func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 122 var params types.QueryValidatorParams 123 124 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 125 if err != nil { 126 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 127 } 128 129 delegations := k.GetValidatorDelegations(ctx, params.ValidatorAddr) 130 131 start, end := client.Paginate(len(delegations), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators)) 132 if start < 0 || end < 0 { 133 delegations = []types.Delegation{} 134 } else { 135 delegations = delegations[start:end] 136 } 137 138 delegationResps, err := DelegationsToDelegationResponses(ctx, k, delegations) 139 if err != nil { 140 return nil, err 141 } 142 143 if delegationResps == nil { 144 delegationResps = types.DelegationResponses{} 145 } 146 147 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, delegationResps) 148 if err != nil { 149 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 150 } 151 152 return res, nil 153 } 154 155 func queryValidatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 156 var params types.QueryValidatorParams 157 158 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 159 if err != nil { 160 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 161 } 162 163 unbonds := k.GetUnbondingDelegationsFromValidator(ctx, params.ValidatorAddr) 164 if unbonds == nil { 165 unbonds = types.UnbondingDelegations{} 166 } 167 168 start, end := client.Paginate(len(unbonds), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators)) 169 if start < 0 || end < 0 { 170 unbonds = types.UnbondingDelegations{} 171 } else { 172 unbonds = unbonds[start:end] 173 } 174 175 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, unbonds) 176 if err != nil { 177 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 178 } 179 180 return res, nil 181 } 182 183 func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 184 var params types.QueryDelegatorParams 185 186 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 187 if err != nil { 188 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 189 } 190 191 delegations := k.GetAllDelegatorDelegations(ctx, params.DelegatorAddr) 192 delegationResps, err := DelegationsToDelegationResponses(ctx, k, delegations) 193 if err != nil { 194 return nil, err 195 } 196 197 if delegationResps == nil { 198 delegationResps = types.DelegationResponses{} 199 } 200 201 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, delegationResps) 202 if err != nil { 203 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 204 } 205 206 return res, nil 207 } 208 209 func queryDelegatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 210 var params types.QueryDelegatorParams 211 212 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 213 if err != nil { 214 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 215 } 216 217 unbondingDelegations := k.GetAllUnbondingDelegations(ctx, params.DelegatorAddr) 218 if unbondingDelegations == nil { 219 unbondingDelegations = types.UnbondingDelegations{} 220 } 221 222 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, unbondingDelegations) 223 if err != nil { 224 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 225 } 226 227 return res, nil 228 } 229 230 func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 231 var params types.QueryDelegatorParams 232 233 stakingParams := k.GetParams(ctx) 234 235 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 236 if err != nil { 237 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 238 } 239 240 validators := k.GetDelegatorValidators(ctx, params.DelegatorAddr, stakingParams.MaxValidators) 241 if validators == nil { 242 validators = types.Validators{} 243 } 244 245 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, validators) 246 if err != nil { 247 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 248 } 249 250 return res, nil 251 } 252 253 func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 254 var params types.QueryDelegatorValidatorRequest 255 256 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 257 if err != nil { 258 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 259 } 260 261 delAddr, err := sdk.AccAddressFromBech32(params.DelegatorAddr) 262 if err != nil { 263 return nil, err 264 } 265 266 valAddr, err := sdk.ValAddressFromBech32(params.ValidatorAddr) 267 if err != nil { 268 return nil, err 269 } 270 271 validator, err := k.GetDelegatorValidator(ctx, delAddr, valAddr) 272 if err != nil { 273 return nil, err 274 } 275 276 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, validator) 277 if err != nil { 278 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 279 } 280 281 return res, nil 282 } 283 284 func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 285 var params types.QueryDelegatorValidatorRequest 286 287 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 288 if err != nil { 289 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 290 } 291 292 delAddr, err := sdk.AccAddressFromBech32(params.DelegatorAddr) 293 if err != nil { 294 return nil, err 295 } 296 297 valAddr, err := sdk.ValAddressFromBech32(params.ValidatorAddr) 298 if err != nil { 299 return nil, err 300 } 301 302 delegation, found := k.GetDelegation(ctx, delAddr, valAddr) 303 if !found { 304 return nil, types.ErrNoDelegation 305 } 306 307 delegationResp, err := DelegationToDelegationResponse(ctx, k, delegation) 308 if err != nil { 309 return nil, err 310 } 311 312 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, delegationResp) 313 if err != nil { 314 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 315 } 316 317 return res, nil 318 } 319 320 func queryUnbondingDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 321 var params types.QueryDelegatorValidatorRequest 322 323 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 324 if err != nil { 325 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 326 } 327 328 delAddr, err := sdk.AccAddressFromBech32(params.DelegatorAddr) 329 if err != nil { 330 return nil, err 331 } 332 333 valAddr, err := sdk.ValAddressFromBech32(params.ValidatorAddr) 334 if err != nil { 335 return nil, err 336 } 337 338 unbond, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) 339 if !found { 340 return nil, types.ErrNoUnbondingDelegation 341 } 342 343 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, unbond) 344 if err != nil { 345 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 346 } 347 348 return res, nil 349 } 350 351 func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 352 var params types.QueryRedelegationParams 353 354 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 355 if err != nil { 356 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 357 } 358 359 var redels []types.Redelegation 360 361 switch { 362 case !params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && !params.DstValidatorAddr.Empty(): 363 redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) 364 if !found { 365 return nil, types.ErrNoRedelegation 366 } 367 368 redels = []types.Redelegation{redel} 369 case params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && params.DstValidatorAddr.Empty(): 370 redels = k.GetRedelegationsFromSrcValidator(ctx, params.SrcValidatorAddr) 371 default: 372 redels = k.GetAllRedelegations(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) 373 } 374 375 redelResponses, err := RedelegationsToRedelegationResponses(ctx, k, redels) 376 if err != nil { 377 return nil, err 378 } 379 380 if redelResponses == nil { 381 redelResponses = types.RedelegationResponses{} 382 } 383 384 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, redelResponses) 385 if err != nil { 386 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 387 } 388 389 return res, nil 390 } 391 392 func queryHistoricalInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 393 var params types.QueryHistoricalInfoRequest 394 395 err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms) 396 if err != nil { 397 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 398 } 399 400 hi, found := k.GetHistoricalInfo(ctx, params.Height) 401 if !found { 402 return nil, types.ErrNoHistoricalInfo 403 } 404 405 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, hi) 406 if err != nil { 407 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 408 } 409 410 return res, nil 411 } 412 413 func queryPool(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 414 bondDenom := k.BondDenom(ctx) 415 bondedPool := k.GetBondedPool(ctx) 416 notBondedPool := k.GetNotBondedPool(ctx) 417 418 if bondedPool == nil || notBondedPool == nil { 419 return nil, errors.New("pool accounts haven't been set") 420 } 421 422 pool := types.NewPool( 423 k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, 424 k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, 425 ) 426 427 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, pool) 428 if err != nil { 429 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 430 } 431 432 return res, nil 433 } 434 435 func queryParameters(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { 436 params := k.GetParams(ctx) 437 438 res, err := codec.MarshalJSONIndent(legacyQuerierCdc, params) 439 if err != nil { 440 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 441 } 442 443 return res, nil 444 } 445 446 // util 447 448 func DelegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, error) { 449 val, found := k.GetValidator(ctx, del.GetValidatorAddr()) 450 if !found { 451 return types.DelegationResponse{}, types.ErrNoValidatorFound 452 } 453 454 delegatorAddress, err := sdk.AccAddressFromBech32(del.DelegatorAddress) 455 if err != nil { 456 return types.DelegationResponse{}, err 457 } 458 459 return types.NewDelegationResp( 460 delegatorAddress, 461 del.GetValidatorAddr(), 462 del.Shares, 463 sdk.NewCoin(k.BondDenom(ctx), val.TokensFromShares(del.Shares).TruncateInt()), 464 ), nil 465 } 466 467 func DelegationsToDelegationResponses( 468 ctx sdk.Context, k Keeper, delegations types.Delegations, 469 ) (types.DelegationResponses, error) { 470 resp := make(types.DelegationResponses, len(delegations)) 471 472 for i, del := range delegations { 473 delResp, err := DelegationToDelegationResponse(ctx, k, del) 474 if err != nil { 475 return nil, err 476 } 477 478 resp[i] = delResp 479 } 480 481 return resp, nil 482 } 483 484 func RedelegationsToRedelegationResponses( 485 ctx sdk.Context, k Keeper, redels types.Redelegations, 486 ) (types.RedelegationResponses, error) { 487 resp := make(types.RedelegationResponses, len(redels)) 488 489 for i, redel := range redels { 490 valSrcAddr, err := sdk.ValAddressFromBech32(redel.ValidatorSrcAddress) 491 if err != nil { 492 panic(err) 493 } 494 valDstAddr, err := sdk.ValAddressFromBech32(redel.ValidatorDstAddress) 495 if err != nil { 496 panic(err) 497 } 498 499 delegatorAddress := sdk.MustAccAddressFromBech32(redel.DelegatorAddress) 500 501 val, found := k.GetValidator(ctx, valDstAddr) 502 if !found { 503 return nil, types.ErrNoValidatorFound 504 } 505 506 entryResponses := make([]types.RedelegationEntryResponse, len(redel.Entries)) 507 for j, entry := range redel.Entries { 508 entryResponses[j] = types.NewRedelegationEntryResponse( 509 entry.CreationHeight, 510 entry.CompletionTime, 511 entry.SharesDst, 512 entry.InitialBalance, 513 val.TokensFromShares(entry.SharesDst).TruncateInt(), 514 ) 515 } 516 517 resp[i] = types.NewRedelegationResponse( 518 delegatorAddress, 519 valSrcAddr, 520 valDstAddr, 521 entryResponses, 522 ) 523 } 524 525 return resp, nil 526 }