github.com/cosmos/cosmos-sdk@v0.50.10/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  	"cosmossdk.io/store/prefix"
    11  	storetypes "cosmossdk.io/store/types"
    12  
    13  	"github.com/cosmos/cosmos-sdk/runtime"
    14  	sdk "github.com/cosmos/cosmos-sdk/types"
    15  	"github.com/cosmos/cosmos-sdk/types/query"
    16  	"github.com/cosmos/cosmos-sdk/x/staking/types"
    17  )
    18  
    19  // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper
    20  type Querier struct {
    21  	*Keeper
    22  }
    23  
    24  var _ types.QueryServer = Querier{}
    25  
    26  func NewQuerier(keeper *Keeper) Querier {
    27  	return Querier{Keeper: keeper}
    28  }
    29  
    30  // Validators queries all validators that match the given status
    31  func (k Querier) Validators(ctx context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
    32  	if req == nil {
    33  		return nil, status.Error(codes.InvalidArgument, "empty request")
    34  	}
    35  
    36  	// validate the provided status, return all the validators if the status is empty
    37  	if req.Status != "" && !(req.Status == types.Bonded.String() || req.Status == types.Unbonded.String() || req.Status == types.Unbonding.String()) {
    38  		return nil, status.Errorf(codes.InvalidArgument, "invalid validator status %s", req.Status)
    39  	}
    40  
    41  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
    42  	valStore := prefix.NewStore(store, types.ValidatorsKey)
    43  
    44  	validators, pageRes, err := query.GenericFilteredPaginate(k.cdc, valStore, req.Pagination, func(key []byte, val *types.Validator) (*types.Validator, error) {
    45  		if req.Status != "" && !strings.EqualFold(val.GetStatus().String(), req.Status) {
    46  			return nil, nil
    47  		}
    48  
    49  		return val, nil
    50  	}, func() *types.Validator {
    51  		return &types.Validator{}
    52  	})
    53  	if err != nil {
    54  		return nil, status.Error(codes.Internal, err.Error())
    55  	}
    56  
    57  	vals := types.Validators{}
    58  	for _, val := range validators {
    59  		vals.Validators = append(vals.Validators, *val)
    60  	}
    61  
    62  	return &types.QueryValidatorsResponse{Validators: vals.Validators, Pagination: pageRes}, nil
    63  }
    64  
    65  // Validator queries validator info for given validator address
    66  func (k Querier) Validator(ctx context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
    67  	if req == nil {
    68  		return nil, status.Error(codes.InvalidArgument, "empty request")
    69  	}
    70  
    71  	if req.ValidatorAddr == "" {
    72  		return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
    73  	}
    74  
    75  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	validator, err := k.GetValidator(ctx, valAddr)
    81  	if err != nil {
    82  		return nil, status.Errorf(codes.NotFound, "validator %s not found", req.ValidatorAddr)
    83  	}
    84  
    85  	return &types.QueryValidatorResponse{Validator: validator}, nil
    86  }
    87  
    88  // ValidatorDelegations queries delegate info for given validator
    89  func (k Querier) ValidatorDelegations(ctx context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) {
    90  	if req == nil {
    91  		return nil, status.Error(codes.InvalidArgument, "empty request")
    92  	}
    93  
    94  	if req.ValidatorAddr == "" {
    95  		return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
    96  	}
    97  
    98  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   104  	delStore := prefix.NewStore(store, types.GetDelegationsByValPrefixKey(valAddr))
   105  
   106  	var (
   107  		dels    types.Delegations
   108  		pageRes *query.PageResponse
   109  	)
   110  	pageRes, err = query.Paginate(delStore, req.Pagination, func(delAddr, value []byte) error {
   111  		bz := store.Get(types.GetDelegationKey(delAddr, valAddr))
   112  
   113  		var delegation types.Delegation
   114  		err = k.cdc.Unmarshal(bz, &delegation)
   115  		if err != nil {
   116  			return err
   117  		}
   118  
   119  		dels = append(dels, delegation)
   120  		return nil
   121  	})
   122  	if err != nil {
   123  		delegations, pageResponse, err := k.getValidatorDelegationsLegacy(ctx, req)
   124  		if err != nil {
   125  			return nil, status.Error(codes.Internal, err.Error())
   126  		}
   127  
   128  		dels = types.Delegations{}
   129  		for _, d := range delegations {
   130  			dels = append(dels, *d)
   131  		}
   132  
   133  		pageRes = pageResponse
   134  	}
   135  
   136  	delResponses, err := delegationsToDelegationResponses(ctx, k.Keeper, dels)
   137  	if err != nil {
   138  		return nil, status.Error(codes.Internal, err.Error())
   139  	}
   140  
   141  	return &types.QueryValidatorDelegationsResponse{
   142  		DelegationResponses: delResponses, Pagination: pageRes,
   143  	}, nil
   144  }
   145  
   146  func (k Querier) getValidatorDelegationsLegacy(ctx context.Context, req *types.QueryValidatorDelegationsRequest) ([]*types.Delegation, *query.PageResponse, error) {
   147  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   148  
   149  	valStore := prefix.NewStore(store, types.DelegationKey)
   150  	return query.GenericFilteredPaginate(k.cdc, valStore, req.Pagination, func(key []byte, delegation *types.Delegation) (*types.Delegation, error) {
   151  		_, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
   152  		if err != nil {
   153  			return nil, err
   154  		}
   155  
   156  		if !strings.EqualFold(delegation.GetValidatorAddr(), req.ValidatorAddr) {
   157  			return nil, nil
   158  		}
   159  
   160  		return delegation, nil
   161  	}, func() *types.Delegation {
   162  		return &types.Delegation{}
   163  	})
   164  }
   165  
   166  // ValidatorUnbondingDelegations queries unbonding delegations of a validator
   167  func (k Querier) ValidatorUnbondingDelegations(ctx context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) {
   168  	if req == nil {
   169  		return nil, status.Error(codes.InvalidArgument, "empty request")
   170  	}
   171  
   172  	if req.ValidatorAddr == "" {
   173  		return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
   174  	}
   175  	var ubds types.UnbondingDelegations
   176  
   177  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  
   182  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   183  	srcValPrefix := types.GetUBDsByValIndexKey(valAddr)
   184  	ubdStore := prefix.NewStore(store, srcValPrefix)
   185  	pageRes, err := query.Paginate(ubdStore, req.Pagination, func(key, value []byte) error {
   186  		storeKey := types.GetUBDKeyFromValIndexKey(append(srcValPrefix, key...))
   187  		storeValue := store.Get(storeKey)
   188  
   189  		ubd, err := types.UnmarshalUBD(k.cdc, storeValue)
   190  		if err != nil {
   191  			return err
   192  		}
   193  		ubds = append(ubds, ubd)
   194  		return nil
   195  	})
   196  	if err != nil {
   197  		return nil, status.Error(codes.Internal, err.Error())
   198  	}
   199  
   200  	return &types.QueryValidatorUnbondingDelegationsResponse{
   201  		UnbondingResponses: ubds,
   202  		Pagination:         pageRes,
   203  	}, nil
   204  }
   205  
   206  // Delegation queries delegate info for given validator delegator pair
   207  func (k Querier) Delegation(ctx context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) {
   208  	if req == nil {
   209  		return nil, status.Error(codes.InvalidArgument, "empty request")
   210  	}
   211  
   212  	if req.DelegatorAddr == "" {
   213  		return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
   214  	}
   215  	if req.ValidatorAddr == "" {
   216  		return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
   217  	}
   218  
   219  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   220  	if err != nil {
   221  		return nil, err
   222  	}
   223  
   224  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  
   229  	delegation, err := k.GetDelegation(ctx, delAddr, valAddr)
   230  	if err != nil {
   231  		return nil, status.Errorf(
   232  			codes.NotFound,
   233  			"delegation with delegator %s not found for validator %s",
   234  			req.DelegatorAddr, req.ValidatorAddr)
   235  	}
   236  
   237  	delResponse, err := delegationToDelegationResponse(ctx, k.Keeper, delegation)
   238  	if err != nil {
   239  		return nil, status.Error(codes.Internal, err.Error())
   240  	}
   241  
   242  	return &types.QueryDelegationResponse{DelegationResponse: &delResponse}, nil
   243  }
   244  
   245  // UnbondingDelegation queries unbonding info for given validator delegator pair
   246  func (k Querier) UnbondingDelegation(ctx context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) {
   247  	if req == nil {
   248  		return nil, status.Errorf(codes.InvalidArgument, "empty request")
   249  	}
   250  
   251  	if req.DelegatorAddr == "" {
   252  		return nil, status.Errorf(codes.InvalidArgument, "delegator address cannot be empty")
   253  	}
   254  	if req.ValidatorAddr == "" {
   255  		return nil, status.Errorf(codes.InvalidArgument, "validator address cannot be empty")
   256  	}
   257  
   258  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  
   263  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
   264  	if err != nil {
   265  		return nil, err
   266  	}
   267  
   268  	unbond, err := k.GetUnbondingDelegation(ctx, delAddr, valAddr)
   269  	if err != nil {
   270  		return nil, status.Errorf(
   271  			codes.NotFound,
   272  			"unbonding delegation with delegator %s not found for validator %s",
   273  			req.DelegatorAddr, req.ValidatorAddr)
   274  	}
   275  
   276  	return &types.QueryUnbondingDelegationResponse{Unbond: unbond}, nil
   277  }
   278  
   279  // DelegatorDelegations queries all delegations of a given delegator address
   280  func (k Querier) DelegatorDelegations(ctx context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) {
   281  	if req == nil {
   282  		return nil, status.Errorf(codes.InvalidArgument, "empty request")
   283  	}
   284  
   285  	if req.DelegatorAddr == "" {
   286  		return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
   287  	}
   288  	var delegations types.Delegations
   289  
   290  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   291  	if err != nil {
   292  		return nil, err
   293  	}
   294  
   295  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   296  	delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
   297  	pageRes, err := query.Paginate(delStore, req.Pagination, func(key, value []byte) error {
   298  		delegation, err := types.UnmarshalDelegation(k.cdc, value)
   299  		if err != nil {
   300  			return err
   301  		}
   302  		delegations = append(delegations, delegation)
   303  		return nil
   304  	})
   305  	if err != nil {
   306  		return nil, status.Error(codes.Internal, err.Error())
   307  	}
   308  
   309  	delegationResps, err := delegationsToDelegationResponses(ctx, k.Keeper, delegations)
   310  	if err != nil {
   311  		return nil, status.Error(codes.Internal, err.Error())
   312  	}
   313  
   314  	return &types.QueryDelegatorDelegationsResponse{DelegationResponses: delegationResps, Pagination: pageRes}, nil
   315  }
   316  
   317  // DelegatorValidator queries validator info for given delegator validator pair
   318  func (k Querier) DelegatorValidator(ctx context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) {
   319  	if req == nil {
   320  		return nil, status.Error(codes.InvalidArgument, "empty request")
   321  	}
   322  
   323  	if req.DelegatorAddr == "" {
   324  		return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
   325  	}
   326  	if req.ValidatorAddr == "" {
   327  		return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
   328  	}
   329  
   330  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   331  	if err != nil {
   332  		return nil, err
   333  	}
   334  
   335  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
   336  	if err != nil {
   337  		return nil, err
   338  	}
   339  
   340  	validator, err := k.GetDelegatorValidator(ctx, delAddr, valAddr)
   341  	if err != nil {
   342  		return nil, status.Error(codes.Internal, err.Error())
   343  	}
   344  
   345  	return &types.QueryDelegatorValidatorResponse{Validator: validator}, nil
   346  }
   347  
   348  // DelegatorUnbondingDelegations queries all unbonding delegations of a given delegator address
   349  func (k Querier) DelegatorUnbondingDelegations(ctx context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) {
   350  	if req == nil {
   351  		return nil, status.Error(codes.InvalidArgument, "empty request")
   352  	}
   353  
   354  	if req.DelegatorAddr == "" {
   355  		return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
   356  	}
   357  	var unbondingDelegations types.UnbondingDelegations
   358  
   359  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   360  	if err != nil {
   361  		return nil, err
   362  	}
   363  
   364  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   365  	unbStore := prefix.NewStore(store, types.GetUBDsKey(delAddr))
   366  	pageRes, err := query.Paginate(unbStore, req.Pagination, func(key, value []byte) error {
   367  		unbond, err := types.UnmarshalUBD(k.cdc, value)
   368  		if err != nil {
   369  			return err
   370  		}
   371  		unbondingDelegations = append(unbondingDelegations, unbond)
   372  		return nil
   373  	})
   374  	if err != nil {
   375  		return nil, status.Error(codes.Internal, err.Error())
   376  	}
   377  
   378  	return &types.QueryDelegatorUnbondingDelegationsResponse{
   379  		UnbondingResponses: unbondingDelegations, Pagination: pageRes,
   380  	}, nil
   381  }
   382  
   383  // HistoricalInfo queries the historical info for given height
   384  func (k Querier) HistoricalInfo(ctx context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) {
   385  	if req == nil {
   386  		return nil, status.Error(codes.InvalidArgument, "empty request")
   387  	}
   388  
   389  	if req.Height < 0 {
   390  		return nil, status.Error(codes.InvalidArgument, "height cannot be negative")
   391  	}
   392  
   393  	hi, err := k.GetHistoricalInfo(ctx, req.Height)
   394  	if err != nil {
   395  		return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height)
   396  	}
   397  
   398  	return &types.QueryHistoricalInfoResponse{Hist: &hi}, nil
   399  }
   400  
   401  // Redelegations queries redelegations of given address
   402  func (k Querier) Redelegations(ctx context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
   403  	if req == nil {
   404  		return nil, status.Error(codes.InvalidArgument, "empty request")
   405  	}
   406  
   407  	var redels types.Redelegations
   408  	var pageRes *query.PageResponse
   409  	var err error
   410  
   411  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   412  	switch {
   413  	case req.DelegatorAddr != "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr != "":
   414  		redels, err = queryRedelegation(ctx, k, req)
   415  	case req.DelegatorAddr == "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr == "":
   416  		redels, pageRes, err = queryRedelegationsFromSrcValidator(store, k, req)
   417  	default:
   418  		redels, pageRes, err = queryAllRedelegations(store, k, req)
   419  	}
   420  	if err != nil {
   421  		return nil, status.Error(codes.Internal, err.Error())
   422  	}
   423  	redelResponses, err := redelegationsToRedelegationResponses(ctx, k.Keeper, redels)
   424  	if err != nil {
   425  		return nil, status.Error(codes.Internal, err.Error())
   426  	}
   427  
   428  	return &types.QueryRedelegationsResponse{RedelegationResponses: redelResponses, Pagination: pageRes}, nil
   429  }
   430  
   431  // DelegatorValidators queries all validators info for given delegator address
   432  func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
   433  	if req == nil {
   434  		return nil, status.Error(codes.InvalidArgument, "empty request")
   435  	}
   436  
   437  	if req.DelegatorAddr == "" {
   438  		return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
   439  	}
   440  	var validators types.Validators
   441  
   442  	store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
   443  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   444  	if err != nil {
   445  		return nil, err
   446  	}
   447  
   448  	delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
   449  	pageRes, err := query.Paginate(delStore, req.Pagination, func(key, value []byte) error {
   450  		delegation, err := types.UnmarshalDelegation(k.cdc, value)
   451  		if err != nil {
   452  			return err
   453  		}
   454  
   455  		valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr())
   456  		if err != nil {
   457  			return err
   458  		}
   459  
   460  		validator, err := k.GetValidator(ctx, valAddr)
   461  		if err != nil {
   462  			return err
   463  		}
   464  
   465  		validators.Validators = append(validators.Validators, validator)
   466  		return nil
   467  	})
   468  	if err != nil {
   469  		return nil, status.Error(codes.Internal, err.Error())
   470  	}
   471  
   472  	return &types.QueryDelegatorValidatorsResponse{Validators: validators.Validators, Pagination: pageRes}, nil
   473  }
   474  
   475  // Pool queries the pool info
   476  func (k Querier) Pool(ctx context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
   477  	bondDenom, err := k.BondDenom(ctx)
   478  	if err != nil {
   479  		return nil, err
   480  	}
   481  	bondedPool := k.GetBondedPool(ctx)
   482  	notBondedPool := k.GetNotBondedPool(ctx)
   483  
   484  	pool := types.NewPool(
   485  		k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount,
   486  		k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount,
   487  	)
   488  
   489  	return &types.QueryPoolResponse{Pool: pool}, nil
   490  }
   491  
   492  // Params queries the staking parameters
   493  func (k Querier) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
   494  	params, err := k.GetParams(ctx)
   495  	if err != nil {
   496  		return nil, err
   497  	}
   498  	return &types.QueryParamsResponse{Params: params}, nil
   499  }
   500  
   501  func queryRedelegation(ctx context.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) {
   502  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   503  	if err != nil {
   504  		return nil, err
   505  	}
   506  
   507  	srcValAddr, err := k.validatorAddressCodec.StringToBytes(req.SrcValidatorAddr)
   508  	if err != nil {
   509  		return nil, err
   510  	}
   511  
   512  	dstValAddr, err := k.validatorAddressCodec.StringToBytes(req.DstValidatorAddr)
   513  	if err != nil {
   514  		return nil, err
   515  	}
   516  
   517  	redel, err := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr)
   518  	if err != nil {
   519  		return nil, status.Errorf(
   520  			codes.NotFound,
   521  			"redelegation not found for delegator address %s from validator address %s",
   522  			req.DelegatorAddr, req.SrcValidatorAddr)
   523  	}
   524  	redels = []types.Redelegation{redel}
   525  
   526  	return redels, nil
   527  }
   528  
   529  func queryRedelegationsFromSrcValidator(store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
   530  	valAddr, err := k.validatorAddressCodec.StringToBytes(req.SrcValidatorAddr)
   531  	if err != nil {
   532  		return nil, nil, err
   533  	}
   534  
   535  	srcValPrefix := types.GetREDsFromValSrcIndexKey(valAddr)
   536  	redStore := prefix.NewStore(store, srcValPrefix)
   537  	res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error {
   538  		storeKey := types.GetREDKeyFromValSrcIndexKey(append(srcValPrefix, key...))
   539  		storeValue := store.Get(storeKey)
   540  		red, err := types.UnmarshalRED(k.cdc, storeValue)
   541  		if err != nil {
   542  			return err
   543  		}
   544  		redels = append(redels, red)
   545  		return nil
   546  	})
   547  
   548  	return redels, res, err
   549  }
   550  
   551  func queryAllRedelegations(store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
   552  	delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
   553  	if err != nil {
   554  		return nil, nil, err
   555  	}
   556  
   557  	redStore := prefix.NewStore(store, types.GetREDsKey(delAddr))
   558  	res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error {
   559  		redelegation, err := types.UnmarshalRED(k.cdc, value)
   560  		if err != nil {
   561  			return err
   562  		}
   563  		redels = append(redels, redelegation)
   564  		return nil
   565  	})
   566  
   567  	return redels, res, err
   568  }
   569  
   570  // util
   571  
   572  func delegationToDelegationResponse(ctx context.Context, k *Keeper, del types.Delegation) (types.DelegationResponse, error) {
   573  	valAddr, err := k.validatorAddressCodec.StringToBytes(del.GetValidatorAddr())
   574  	if err != nil {
   575  		return types.DelegationResponse{}, err
   576  	}
   577  
   578  	val, err := k.GetValidator(ctx, valAddr)
   579  	if err != nil {
   580  		return types.DelegationResponse{}, err
   581  	}
   582  
   583  	_, err = k.authKeeper.AddressCodec().StringToBytes(del.DelegatorAddress)
   584  	if err != nil {
   585  		return types.DelegationResponse{}, err
   586  	}
   587  
   588  	bondDenom, err := k.BondDenom(ctx)
   589  	if err != nil {
   590  		return types.DelegationResponse{}, err
   591  	}
   592  
   593  	return types.NewDelegationResp(
   594  		del.DelegatorAddress,
   595  		del.GetValidatorAddr(),
   596  		del.Shares,
   597  		sdk.NewCoin(bondDenom, val.TokensFromShares(del.Shares).TruncateInt()),
   598  	), nil
   599  }
   600  
   601  func delegationsToDelegationResponses(ctx context.Context, k *Keeper, delegations types.Delegations) (types.DelegationResponses, error) {
   602  	resp := make(types.DelegationResponses, len(delegations))
   603  
   604  	for i, del := range delegations {
   605  		delResp, err := delegationToDelegationResponse(ctx, k, del)
   606  		if err != nil {
   607  			return nil, err
   608  		}
   609  
   610  		resp[i] = delResp
   611  	}
   612  
   613  	return resp, nil
   614  }
   615  
   616  func redelegationsToRedelegationResponses(ctx context.Context, k *Keeper, redels types.Redelegations) (types.RedelegationResponses, error) {
   617  	resp := make(types.RedelegationResponses, len(redels))
   618  
   619  	for i, redel := range redels {
   620  		_, err := k.validatorAddressCodec.StringToBytes(redel.ValidatorSrcAddress)
   621  		if err != nil {
   622  			return nil, err
   623  		}
   624  		valDstAddr, err := k.validatorAddressCodec.StringToBytes(redel.ValidatorDstAddress)
   625  		if err != nil {
   626  			return nil, err
   627  		}
   628  
   629  		_, err = k.authKeeper.AddressCodec().StringToBytes(redel.DelegatorAddress)
   630  		if err != nil {
   631  			return nil, err
   632  		}
   633  
   634  		val, err := k.GetValidator(ctx, valDstAddr)
   635  		if err != nil {
   636  			return nil, err
   637  		}
   638  
   639  		entryResponses := make([]types.RedelegationEntryResponse, len(redel.Entries))
   640  		for j, entry := range redel.Entries {
   641  			entryResponses[j] = types.NewRedelegationEntryResponse(
   642  				entry.CreationHeight,
   643  				entry.CompletionTime,
   644  				entry.SharesDst,
   645  				entry.InitialBalance,
   646  				val.TokensFromShares(entry.SharesDst).TruncateInt(),
   647  				entry.UnbondingId,
   648  			)
   649  		}
   650  
   651  		resp[i] = types.NewRedelegationResponse(
   652  			redel.DelegatorAddress,
   653  			redel.ValidatorSrcAddress,
   654  			redel.ValidatorDstAddress,
   655  			entryResponses,
   656  		)
   657  	}
   658  
   659  	return resp, nil
   660  }