2020-07-14 10:41:30 -07:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/types/query"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper
|
|
|
|
type Querier struct {
|
|
|
|
Keeper
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ types.QueryServer = Querier{}
|
|
|
|
|
|
|
|
// Validators queries all validators that match the given status
|
|
|
|
func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-08-26 00:42:25 -07:00
|
|
|
// validate the provided status, return all the validators if the status is empty
|
2020-10-12 06:56:02 -07:00
|
|
|
if req.Status != "" && !(req.Status == types.Bonded.String() || req.Status == types.Unbonded.String() || req.Status == types.Unbonding.String()) {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "invalid validator status %s", req.Status)
|
|
|
|
}
|
2020-08-26 00:42:25 -07:00
|
|
|
|
2020-07-14 10:41:30 -07:00
|
|
|
var validators types.Validators
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
valStore := prefix.NewStore(store, types.ValidatorsKey)
|
|
|
|
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.FilteredPaginate(valStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
2020-07-14 10:41:30 -07:00
|
|
|
val, err := types.UnmarshalValidator(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.Status != "" && !strings.EqualFold(val.GetStatus().String(), req.Status) {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if accumulate {
|
|
|
|
validators = append(validators, val)
|
|
|
|
}
|
2020-08-26 00:42:25 -07:00
|
|
|
|
2020-07-14 10:41:30 -07:00
|
|
|
return true, nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
2020-07-20 09:51:16 -07:00
|
|
|
return &types.QueryValidatorsResponse{Validators: validators, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
|
2021-05-10 05:41:24 -07:00
|
|
|
// Validator queries validator info for given validator address
|
2020-07-14 10:41:30 -07:00
|
|
|
func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
2020-09-25 03:25:37 -07:00
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-07-14 10:41:30 -07:00
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
2020-09-25 03:25:37 -07:00
|
|
|
validator, found := k.GetValidator(ctx, valAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
if !found {
|
|
|
|
return nil, status.Errorf(codes.NotFound, "validator %s not found", req.ValidatorAddr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryValidatorResponse{Validator: validator}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorDelegations queries delegate info for given validator
|
|
|
|
func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
|
|
|
var delegations []types.Delegation
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
valStore := prefix.NewStore(store, types.DelegationKey)
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.FilteredPaginate(valStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
2020-07-14 10:41:30 -07:00
|
|
|
delegation, err := types.UnmarshalDelegation(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
2020-09-25 03:25:37 -07:00
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !delegation.GetValidatorAddr().Equals(valAddr) {
|
2020-07-14 10:41:30 -07:00
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if accumulate {
|
|
|
|
delegations = append(delegations, delegation)
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
delResponses, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryValidatorDelegationsResponse{
|
2020-07-20 09:51:16 -07:00
|
|
|
DelegationResponses: delResponses, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorUnbondingDelegations queries unbonding delegations of a validator
|
|
|
|
func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
|
|
|
var ubds types.UnbondingDelegations
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
2020-09-25 03:25:37 -07:00
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
srcValPrefix := types.GetUBDsByValIndexKey(valAddr)
|
2020-09-02 09:47:29 -07:00
|
|
|
ubdStore := prefix.NewStore(store, srcValPrefix)
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.Paginate(ubdStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-09-02 09:47:29 -07:00
|
|
|
storeKey := types.GetUBDKeyFromValIndexKey(append(srcValPrefix, key...))
|
|
|
|
storeValue := store.Get(storeKey)
|
|
|
|
|
|
|
|
ubd, err := types.UnmarshalUBD(k.cdc, storeValue)
|
2020-07-14 10:41:30 -07:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
ubds = append(ubds, ubd)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryValidatorUnbondingDelegationsResponse{
|
|
|
|
UnbondingResponses: ubds,
|
2020-07-20 09:51:16 -07:00
|
|
|
Pagination: pageRes,
|
2020-07-14 10:41:30 -07:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delegation queries delegate info for given validator delegator pair
|
|
|
|
func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
delegation, found := k.GetDelegation(ctx, delAddr, valAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
if !found {
|
|
|
|
return nil, status.Errorf(
|
|
|
|
codes.NotFound,
|
|
|
|
"delegation with delegator %s not found for validator %s",
|
|
|
|
req.DelegatorAddr, req.ValidatorAddr)
|
|
|
|
}
|
|
|
|
|
|
|
|
delResponse, err := DelegationToDelegationResponse(ctx, k.Keeper, delegation)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryDelegationResponse{DelegationResponse: &delResponse}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnbondingDelegation queries unbonding info for give validator delegator pair
|
|
|
|
func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
2020-09-25 03:25:37 -07:00
|
|
|
|
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
unbond, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
if !found {
|
|
|
|
return nil, status.Errorf(
|
|
|
|
codes.NotFound,
|
|
|
|
"unbonding delegation with delegator %s not found for validator %s",
|
|
|
|
req.DelegatorAddr, req.ValidatorAddr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryUnbondingDelegationResponse{Unbond: unbond}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// DelegatorDelegations queries all delegations of a give delegator address
|
|
|
|
func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
|
|
|
var delegations types.Delegations
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-07-14 10:41:30 -07:00
|
|
|
store := ctx.KVStore(k.storeKey)
|
2020-09-25 03:25:37 -07:00
|
|
|
delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.Paginate(delStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-07-14 10:41:30 -07:00
|
|
|
delegation, err := types.UnmarshalDelegation(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
delegations = append(delegations, delegation)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
delegationResps, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
2020-07-20 09:51:16 -07:00
|
|
|
return &types.QueryDelegatorDelegationsResponse{DelegationResponses: delegationResps, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// DelegatorValidator queries validator info for given delegator validator pair
|
|
|
|
func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.ValidatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
validator, err := k.GetDelegatorValidator(ctx, delAddr, valAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryDelegatorValidatorResponse{Validator: validator}, nil
|
|
|
|
}
|
|
|
|
|
2020-08-14 03:05:35 -07:00
|
|
|
// DelegatorUnbondingDelegations queries all unbonding delegations of a given delegator address
|
2020-07-14 10:41:30 -07:00
|
|
|
func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
|
|
|
var unbondingDelegations types.UnbondingDelegations
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
unbStore := prefix.NewStore(store, types.GetUBDsKey(delAddr))
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.Paginate(unbStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-07-14 10:41:30 -07:00
|
|
|
unbond, err := types.UnmarshalUBD(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
unbondingDelegations = append(unbondingDelegations, unbond)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryDelegatorUnbondingDelegationsResponse{
|
2020-07-20 09:51:16 -07:00
|
|
|
UnbondingResponses: unbondingDelegations, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// HistoricalInfo queries the historical info for given height
|
|
|
|
func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.Height < 0 {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "height cannot be negative")
|
|
|
|
}
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
hi, found := k.GetHistoricalInfo(ctx, req.Height)
|
|
|
|
if !found {
|
|
|
|
return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryHistoricalInfoResponse{Hist: &hi}, nil
|
|
|
|
}
|
|
|
|
|
2021-05-10 05:41:24 -07:00
|
|
|
// Redelegations queries redelegations of given address
|
2020-07-14 10:41:30 -07:00
|
|
|
func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
|
|
|
var redels types.Redelegations
|
2020-07-20 09:51:16 -07:00
|
|
|
var pageRes *query.PageResponse
|
2020-07-14 10:41:30 -07:00
|
|
|
var err error
|
|
|
|
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
switch {
|
2020-09-25 03:25:37 -07:00
|
|
|
case req.DelegatorAddr != "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr != "":
|
2020-07-14 10:41:30 -07:00
|
|
|
redels, err = queryRedelegation(ctx, k, req)
|
2020-09-25 03:25:37 -07:00
|
|
|
case req.DelegatorAddr == "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr == "":
|
2020-07-20 09:51:16 -07:00
|
|
|
redels, pageRes, err = queryRedelegationsFromSrcValidator(store, k, req)
|
2020-07-14 10:41:30 -07:00
|
|
|
default:
|
2020-07-20 09:51:16 -07:00
|
|
|
redels, pageRes, err = queryAllRedelegations(store, k, req)
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
redelResponses, err := RedelegationsToRedelegationResponses(ctx, k.Keeper, redels)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
2020-07-20 09:51:16 -07:00
|
|
|
return &types.QueryRedelegationsResponse{RedelegationResponses: redelResponses, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
|
2021-05-10 05:41:24 -07:00
|
|
|
// DelegatorValidators queries all validators info for given delegator address
|
2020-07-14 10:41:30 -07:00
|
|
|
func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
|
|
|
if req == nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
if req.DelegatorAddr == "" {
|
2020-07-14 10:41:30 -07:00
|
|
|
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
|
|
|
|
}
|
|
|
|
var validators types.Validators
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
|
2020-07-20 09:51:16 -07:00
|
|
|
pageRes, err := query.Paginate(delStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-07-14 10:41:30 -07:00
|
|
|
delegation, err := types.UnmarshalDelegation(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-09-25 03:25:37 -07:00
|
|
|
validator, found := k.GetValidator(ctx, delegation.GetValidatorAddr())
|
2020-07-14 10:41:30 -07:00
|
|
|
if !found {
|
|
|
|
return types.ErrNoValidatorFound
|
|
|
|
}
|
|
|
|
|
|
|
|
validators = append(validators, validator)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
|
|
|
|
2020-07-20 09:51:16 -07:00
|
|
|
return &types.QueryDelegatorValidatorsResponse{Validators: validators, Pagination: pageRes}, nil
|
2020-07-14 10:41:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Pool queries the pool info
|
|
|
|
func (k Querier) Pool(c context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
bondDenom := k.BondDenom(ctx)
|
|
|
|
bondedPool := k.GetBondedPool(ctx)
|
|
|
|
notBondedPool := k.GetNotBondedPool(ctx)
|
|
|
|
|
|
|
|
pool := types.NewPool(
|
|
|
|
k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount,
|
|
|
|
k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount,
|
|
|
|
)
|
|
|
|
|
|
|
|
return &types.QueryPoolResponse{Pool: pool}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Params queries the staking parameters
|
|
|
|
func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(c)
|
|
|
|
params := k.GetParams(ctx)
|
|
|
|
|
|
|
|
return &types.QueryParamsResponse{Params: params}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) {
|
2020-09-25 03:25:37 -07:00
|
|
|
|
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
srcValAddr, err := sdk.ValAddressFromBech32(req.SrcValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
dstValAddr, err := sdk.ValAddressFromBech32(req.DstValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
redel, found := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
if !found {
|
|
|
|
return nil, status.Errorf(
|
|
|
|
codes.NotFound,
|
|
|
|
"redelegation not found for delegator address %s from validator address %s",
|
|
|
|
req.DelegatorAddr, req.SrcValidatorAddr)
|
|
|
|
}
|
|
|
|
redels = []types.Redelegation{redel}
|
|
|
|
|
|
|
|
return redels, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func queryRedelegationsFromSrcValidator(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
|
2020-09-25 03:25:37 -07:00
|
|
|
valAddr, err := sdk.ValAddressFromBech32(req.SrcValidatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
srcValPrefix := types.GetREDsFromValSrcIndexKey(valAddr)
|
2020-07-14 10:41:30 -07:00
|
|
|
redStore := prefix.NewStore(store, srcValPrefix)
|
2020-07-20 09:51:16 -07:00
|
|
|
res, err = query.Paginate(redStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-07-14 10:41:30 -07:00
|
|
|
storeKey := types.GetREDKeyFromValSrcIndexKey(append(srcValPrefix, key...))
|
|
|
|
storeValue := store.Get(storeKey)
|
|
|
|
red, err := types.UnmarshalRED(k.cdc, storeValue)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
redels = append(redels, red)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return redels, res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func queryAllRedelegations(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
|
2020-09-25 03:25:37 -07:00
|
|
|
delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
redStore := prefix.NewStore(store, types.GetREDsKey(delAddr))
|
2020-07-20 09:51:16 -07:00
|
|
|
res, err = query.Paginate(redStore, req.Pagination, func(key []byte, value []byte) error {
|
2020-07-14 10:41:30 -07:00
|
|
|
redelegation, err := types.UnmarshalRED(k.cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
redels = append(redels, redelegation)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return redels, res, err
|
|
|
|
}
|