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  }