github.com/Finschia/finschia-sdk@v0.48.1/x/staking/keeper/grpc_query_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	gocontext "context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/Finschia/finschia-sdk/simapp"
    11  	sdk "github.com/Finschia/finschia-sdk/types"
    12  	"github.com/Finschia/finschia-sdk/types/query"
    13  	"github.com/Finschia/finschia-sdk/x/staking/keeper"
    14  	"github.com/Finschia/finschia-sdk/x/staking/teststaking"
    15  	"github.com/Finschia/finschia-sdk/x/staking/types"
    16  )
    17  
    18  func (suite *KeeperTestSuite) TestGRPCQueryValidators() {
    19  	queryClient, vals := suite.queryClient, suite.vals
    20  	var req *types.QueryValidatorsRequest
    21  	testCases := []struct {
    22  		msg      string
    23  		malleate func()
    24  		expPass  bool
    25  		numVals  int
    26  		hasNext  bool
    27  	}{
    28  		{
    29  			"empty request",
    30  			func() {
    31  				req = &types.QueryValidatorsRequest{}
    32  			},
    33  			true,
    34  
    35  			len(vals),
    36  			false,
    37  		},
    38  		{
    39  			"empty status returns all the validators",
    40  			func() {
    41  				req = &types.QueryValidatorsRequest{Status: ""}
    42  			},
    43  			true,
    44  			len(vals),
    45  			false,
    46  		},
    47  		{
    48  			"invalid request",
    49  			func() {
    50  				req = &types.QueryValidatorsRequest{Status: "test"}
    51  			},
    52  			false,
    53  			0,
    54  			false,
    55  		},
    56  		{
    57  			"valid request",
    58  			func() {
    59  				req = &types.QueryValidatorsRequest{
    60  					Status:     types.Bonded.String(),
    61  					Pagination: &query.PageRequest{Limit: 1, CountTotal: true},
    62  				}
    63  			},
    64  			true,
    65  			1,
    66  			true,
    67  		},
    68  	}
    69  	for _, tc := range testCases {
    70  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
    71  			tc.malleate()
    72  			valsResp, err := queryClient.Validators(gocontext.Background(), req)
    73  			if tc.expPass {
    74  				suite.NoError(err)
    75  				suite.NotNil(valsResp)
    76  				suite.Equal(tc.numVals, len(valsResp.Validators))
    77  				suite.Equal(uint64(len(vals)), valsResp.Pagination.Total)
    78  
    79  				if tc.hasNext {
    80  					suite.NotNil(valsResp.Pagination.NextKey)
    81  				} else {
    82  					suite.Nil(valsResp.Pagination.NextKey)
    83  				}
    84  			} else {
    85  				suite.Require().Error(err)
    86  			}
    87  		})
    88  	}
    89  }
    90  
    91  func (suite *KeeperTestSuite) TestGRPCQueryValidator() {
    92  	app, ctx, queryClient, vals := suite.app, suite.ctx, suite.queryClient, suite.vals
    93  	validator, found := app.StakingKeeper.GetValidator(ctx, vals[0].GetOperator())
    94  	suite.True(found)
    95  	var req *types.QueryValidatorRequest
    96  	testCases := []struct {
    97  		msg      string
    98  		malleate func()
    99  		expPass  bool
   100  	}{
   101  		{
   102  			"empty request",
   103  			func() {
   104  				req = &types.QueryValidatorRequest{}
   105  			},
   106  			false,
   107  		},
   108  		{
   109  			"valid request",
   110  			func() {
   111  				req = &types.QueryValidatorRequest{ValidatorAddr: vals[0].OperatorAddress}
   112  			},
   113  			true,
   114  		},
   115  	}
   116  
   117  	for _, tc := range testCases {
   118  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   119  			tc.malleate()
   120  			res, err := queryClient.Validator(gocontext.Background(), req)
   121  			if tc.expPass {
   122  				suite.NoError(err)
   123  				suite.True(validator.Equal(&res.Validator))
   124  			} else {
   125  				suite.Error(err)
   126  				suite.Nil(res)
   127  			}
   128  		})
   129  	}
   130  }
   131  
   132  func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidators() {
   133  	app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
   134  	params := app.StakingKeeper.GetParams(ctx)
   135  	delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
   136  	var req *types.QueryDelegatorValidatorsRequest
   137  	testCases := []struct {
   138  		msg      string
   139  		malleate func()
   140  		expPass  bool
   141  	}{
   142  		{
   143  			"empty request",
   144  			func() {
   145  				req = &types.QueryDelegatorValidatorsRequest{}
   146  			},
   147  			false,
   148  		},
   149  		{
   150  			"valid request",
   151  			func() {
   152  				req = &types.QueryDelegatorValidatorsRequest{
   153  					DelegatorAddr: addrs[0].String(),
   154  					Pagination:    &query.PageRequest{Limit: 1, CountTotal: true},
   155  				}
   156  			},
   157  			true,
   158  		},
   159  	}
   160  
   161  	for _, tc := range testCases {
   162  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   163  			tc.malleate()
   164  			res, err := queryClient.DelegatorValidators(gocontext.Background(), req)
   165  			if tc.expPass {
   166  				suite.NoError(err)
   167  				suite.Equal(1, len(res.Validators))
   168  				suite.NotNil(res.Pagination.NextKey)
   169  				suite.Equal(uint64(len(delValidators)), res.Pagination.Total)
   170  			} else {
   171  				suite.Error(err)
   172  				suite.Nil(res)
   173  			}
   174  		})
   175  	}
   176  }
   177  
   178  func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidator() {
   179  	queryClient, addrs, vals := suite.queryClient, suite.addrs, suite.vals
   180  	addr := addrs[1]
   181  	addrVal, addrVal1 := vals[0].OperatorAddress, vals[1].OperatorAddress
   182  	var req *types.QueryDelegatorValidatorRequest
   183  	testCases := []struct {
   184  		msg      string
   185  		malleate func()
   186  		expPass  bool
   187  	}{
   188  		{
   189  			"empty request",
   190  			func() {
   191  				req = &types.QueryDelegatorValidatorRequest{}
   192  			},
   193  			false,
   194  		},
   195  		{
   196  			"invalid delegator, validator pair",
   197  			func() {
   198  				req = &types.QueryDelegatorValidatorRequest{
   199  					DelegatorAddr: addr.String(),
   200  					ValidatorAddr: addrVal,
   201  				}
   202  			},
   203  			false,
   204  		},
   205  		{
   206  			"valid request",
   207  			func() {
   208  				req = &types.QueryDelegatorValidatorRequest{
   209  					DelegatorAddr: addr.String(),
   210  					ValidatorAddr: addrVal1,
   211  				}
   212  			},
   213  			true,
   214  		},
   215  	}
   216  
   217  	for _, tc := range testCases {
   218  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   219  			tc.malleate()
   220  			res, err := queryClient.DelegatorValidator(gocontext.Background(), req)
   221  			if tc.expPass {
   222  				suite.NoError(err)
   223  				suite.Equal(addrVal1, res.Validator.OperatorAddress)
   224  			} else {
   225  				suite.Error(err)
   226  				suite.Nil(res)
   227  			}
   228  		})
   229  	}
   230  }
   231  
   232  func (suite *KeeperTestSuite) TestGRPCQueryDelegation() {
   233  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   234  	addrAcc, addrAcc1 := addrs[0], addrs[1]
   235  	addrVal := vals[0].OperatorAddress
   236  	valAddr, err := sdk.ValAddressFromBech32(addrVal)
   237  	suite.NoError(err)
   238  	delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
   239  	suite.True(found)
   240  	var req *types.QueryDelegationRequest
   241  
   242  	testCases := []struct {
   243  		msg      string
   244  		malleate func()
   245  		expPass  bool
   246  	}{
   247  		{
   248  			"empty request",
   249  			func() {
   250  				req = &types.QueryDelegationRequest{}
   251  			},
   252  			false,
   253  		},
   254  		{
   255  			"invalid validator, delegator pair",
   256  			func() {
   257  				req = &types.QueryDelegationRequest{
   258  					DelegatorAddr: addrAcc1.String(),
   259  					ValidatorAddr: addrVal,
   260  				}
   261  			},
   262  			false,
   263  		},
   264  		{
   265  			"valid request",
   266  			func() {
   267  				req = &types.QueryDelegationRequest{DelegatorAddr: addrAcc.String(), ValidatorAddr: addrVal}
   268  			},
   269  			true,
   270  		},
   271  	}
   272  
   273  	for _, tc := range testCases {
   274  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   275  			tc.malleate()
   276  			res, err := queryClient.Delegation(gocontext.Background(), req)
   277  			if tc.expPass {
   278  				suite.Equal(delegation.ValidatorAddress, res.DelegationResponse.Delegation.ValidatorAddress)
   279  				suite.Equal(delegation.DelegatorAddress, res.DelegationResponse.Delegation.DelegatorAddress)
   280  				suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponse.Balance)
   281  			} else {
   282  				suite.Error(err)
   283  				suite.Nil(res)
   284  			}
   285  		})
   286  	}
   287  }
   288  
   289  func (suite *KeeperTestSuite) TestGRPCQueryDelegatorDelegations() {
   290  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   291  	addrAcc := addrs[0]
   292  	addrVal1 := vals[0].OperatorAddress
   293  	valAddr, err := sdk.ValAddressFromBech32(addrVal1)
   294  	suite.NoError(err)
   295  	delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
   296  	suite.True(found)
   297  	var req *types.QueryDelegatorDelegationsRequest
   298  
   299  	testCases := []struct {
   300  		msg       string
   301  		malleate  func()
   302  		onSuccess func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse)
   303  		expErr    bool
   304  	}{
   305  		{
   306  			"empty request",
   307  			func() {
   308  				req = &types.QueryDelegatorDelegationsRequest{}
   309  			},
   310  			func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {},
   311  			true,
   312  		},
   313  		{
   314  			"valid request with no delegations",
   315  			func() {
   316  				req = &types.QueryDelegatorDelegationsRequest{DelegatorAddr: addrs[4].String()}
   317  			},
   318  			func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {
   319  				suite.Equal(uint64(0), response.Pagination.Total)
   320  				suite.Len(response.DelegationResponses, 0)
   321  			},
   322  			false,
   323  		},
   324  		{
   325  			"valid request",
   326  			func() {
   327  				req = &types.QueryDelegatorDelegationsRequest{
   328  					DelegatorAddr: addrAcc.String(),
   329  					Pagination:    &query.PageRequest{Limit: 1, CountTotal: true},
   330  				}
   331  			},
   332  			func(suite *KeeperTestSuite, response *types.QueryDelegatorDelegationsResponse) {
   333  				suite.Equal(uint64(2), response.Pagination.Total)
   334  				suite.Len(response.DelegationResponses, 1)
   335  				suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), response.DelegationResponses[0].Balance)
   336  			},
   337  			false,
   338  		},
   339  	}
   340  
   341  	for _, tc := range testCases {
   342  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   343  			tc.malleate()
   344  			res, err := queryClient.DelegatorDelegations(gocontext.Background(), req)
   345  			if tc.expErr {
   346  				suite.Error(err)
   347  			} else {
   348  				suite.NoError(err)
   349  				tc.onSuccess(suite, res)
   350  			}
   351  		})
   352  	}
   353  }
   354  
   355  func (suite *KeeperTestSuite) TestGRPCQueryValidatorDelegations() {
   356  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   357  	addrAcc := addrs[0]
   358  	addrVal1 := vals[1].OperatorAddress
   359  	valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
   360  	addrVal2 := valAddrs[4]
   361  	valAddr, err := sdk.ValAddressFromBech32(addrVal1)
   362  	suite.NoError(err)
   363  	delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
   364  	suite.True(found)
   365  
   366  	var req *types.QueryValidatorDelegationsRequest
   367  	testCases := []struct {
   368  		msg      string
   369  		malleate func()
   370  		expPass  bool
   371  		expErr   bool
   372  	}{
   373  		{
   374  			"empty request",
   375  			func() {
   376  				req = &types.QueryValidatorDelegationsRequest{}
   377  			},
   378  			false,
   379  			true,
   380  		},
   381  		{
   382  			"invalid validator delegator pair",
   383  			func() {
   384  				req = &types.QueryValidatorDelegationsRequest{ValidatorAddr: addrVal2.String()}
   385  			},
   386  			false,
   387  			false,
   388  		},
   389  		{
   390  			"valid request",
   391  			func() {
   392  				req = &types.QueryValidatorDelegationsRequest{
   393  					ValidatorAddr: addrVal1,
   394  					Pagination:    &query.PageRequest{Limit: 1, CountTotal: true},
   395  				}
   396  			},
   397  			true,
   398  			false,
   399  		},
   400  	}
   401  
   402  	for _, tc := range testCases {
   403  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   404  			tc.malleate()
   405  			res, err := queryClient.ValidatorDelegations(gocontext.Background(), req)
   406  			if tc.expPass && !tc.expErr {
   407  				suite.NoError(err)
   408  				suite.Len(res.DelegationResponses, 1)
   409  				suite.NotNil(res.Pagination.NextKey)
   410  				suite.Equal(uint64(2), res.Pagination.Total)
   411  				suite.Equal(addrVal1, res.DelegationResponses[0].Delegation.ValidatorAddress)
   412  				suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponses[0].Balance)
   413  			} else if !tc.expPass && !tc.expErr {
   414  				suite.NoError(err)
   415  				suite.Nil(res.DelegationResponses)
   416  			} else {
   417  				suite.Error(err)
   418  				suite.Nil(res)
   419  			}
   420  		})
   421  	}
   422  }
   423  
   424  func (suite *KeeperTestSuite) TestGRPCQueryUnbondingDelegation() {
   425  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   426  	addrAcc2 := addrs[1]
   427  	addrVal2 := vals[1].OperatorAddress
   428  
   429  	unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
   430  	valAddr, err1 := sdk.ValAddressFromBech32(addrVal2)
   431  	suite.NoError(err1)
   432  	_, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, unbondingTokens.ToDec())
   433  	suite.NoError(err)
   434  
   435  	unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr)
   436  	suite.True(found)
   437  	var req *types.QueryUnbondingDelegationRequest
   438  	testCases := []struct {
   439  		msg      string
   440  		malleate func()
   441  		expPass  bool
   442  	}{
   443  		{
   444  			"empty request",
   445  			func() {
   446  				req = &types.QueryUnbondingDelegationRequest{}
   447  			},
   448  			false,
   449  		},
   450  		{
   451  			"invalid request",
   452  			func() {
   453  				req = &types.QueryUnbondingDelegationRequest{}
   454  			},
   455  			false,
   456  		},
   457  		{
   458  			"valid request",
   459  			func() {
   460  				req = &types.QueryUnbondingDelegationRequest{
   461  					DelegatorAddr: addrAcc2.String(), ValidatorAddr: addrVal2,
   462  				}
   463  			},
   464  			true,
   465  		},
   466  	}
   467  
   468  	for _, tc := range testCases {
   469  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   470  			tc.malleate()
   471  			res, err := queryClient.UnbondingDelegation(gocontext.Background(), req)
   472  			if tc.expPass {
   473  				suite.NotNil(res)
   474  				suite.Equal(unbond, res.Unbond)
   475  			} else {
   476  				suite.Error(err)
   477  				suite.Nil(res)
   478  			}
   479  		})
   480  	}
   481  }
   482  
   483  func (suite *KeeperTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() {
   484  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   485  	addrAcc, addrAcc1 := addrs[0], addrs[1]
   486  	addrVal, addrVal2 := vals[0].OperatorAddress, vals[1].OperatorAddress
   487  
   488  	unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
   489  	valAddr1, err1 := sdk.ValAddressFromBech32(addrVal)
   490  	suite.NoError(err1)
   491  	_, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, unbondingTokens.ToDec())
   492  	suite.NoError(err)
   493  	valAddr2, err1 := sdk.ValAddressFromBech32(addrVal2)
   494  	suite.NoError(err1)
   495  	_, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, unbondingTokens.ToDec())
   496  	suite.NoError(err)
   497  
   498  	unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1)
   499  	suite.True(found)
   500  	var req *types.QueryDelegatorUnbondingDelegationsRequest
   501  	testCases := []struct {
   502  		msg      string
   503  		malleate func()
   504  		expPass  bool
   505  		expErr   bool
   506  	}{
   507  		{
   508  			"empty request",
   509  			func() {
   510  				req = &types.QueryDelegatorUnbondingDelegationsRequest{}
   511  			},
   512  			false,
   513  			true,
   514  		},
   515  		{
   516  			"invalid request",
   517  			func() {
   518  				req = &types.QueryDelegatorUnbondingDelegationsRequest{DelegatorAddr: addrAcc1.String()}
   519  			},
   520  			false,
   521  			false,
   522  		},
   523  		{
   524  			"valid request",
   525  			func() {
   526  				req = &types.QueryDelegatorUnbondingDelegationsRequest{
   527  					DelegatorAddr: addrAcc.String(),
   528  					Pagination:    &query.PageRequest{Limit: 1, CountTotal: true},
   529  				}
   530  			},
   531  			true,
   532  			false,
   533  		},
   534  	}
   535  
   536  	for _, tc := range testCases {
   537  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   538  			tc.malleate()
   539  			res, err := queryClient.DelegatorUnbondingDelegations(gocontext.Background(), req)
   540  			if tc.expPass && !tc.expErr {
   541  				suite.NoError(err)
   542  				suite.NotNil(res.Pagination.NextKey)
   543  				suite.Equal(uint64(2), res.Pagination.Total)
   544  				suite.Len(res.UnbondingResponses, 1)
   545  				suite.Equal(unbond, res.UnbondingResponses[0])
   546  			} else if !tc.expPass && !tc.expErr {
   547  				suite.NoError(err)
   548  				suite.Nil(res.UnbondingResponses)
   549  			} else {
   550  				suite.Error(err)
   551  				suite.Nil(res)
   552  			}
   553  		})
   554  	}
   555  }
   556  
   557  func (suite *KeeperTestSuite) TestGRPCQueryPoolParameters() {
   558  	app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
   559  	bondDenom := sdk.DefaultBondDenom
   560  
   561  	// Query pool
   562  	res, err := queryClient.Pool(gocontext.Background(), &types.QueryPoolRequest{})
   563  	suite.NoError(err)
   564  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   565  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   566  	suite.Equal(app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, res.Pool.NotBondedTokens)
   567  	suite.Equal(app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, res.Pool.BondedTokens)
   568  
   569  	// Query Params
   570  	resp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
   571  	suite.NoError(err)
   572  	suite.Equal(app.StakingKeeper.GetParams(ctx), resp.Params)
   573  }
   574  
   575  func (suite *KeeperTestSuite) TestGRPCQueryHistoricalInfo() {
   576  	app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
   577  
   578  	hi, found := app.StakingKeeper.GetHistoricalInfo(ctx, 5)
   579  	suite.True(found)
   580  
   581  	var req *types.QueryHistoricalInfoRequest
   582  	testCases := []struct {
   583  		msg      string
   584  		malleate func()
   585  		expPass  bool
   586  	}{
   587  		{
   588  			"empty request",
   589  			func() {
   590  				req = &types.QueryHistoricalInfoRequest{}
   591  			},
   592  			false,
   593  		},
   594  		{
   595  			"invalid request with negative height",
   596  			func() {
   597  				req = &types.QueryHistoricalInfoRequest{Height: -1}
   598  			},
   599  			false,
   600  		},
   601  		{
   602  			"valid request with old height",
   603  			func() {
   604  				req = &types.QueryHistoricalInfoRequest{Height: 4}
   605  			},
   606  			false,
   607  		},
   608  		{
   609  			"valid request with current height",
   610  			func() {
   611  				req = &types.QueryHistoricalInfoRequest{Height: 5}
   612  			},
   613  			true,
   614  		},
   615  	}
   616  
   617  	for _, tc := range testCases {
   618  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   619  			tc.malleate()
   620  			res, err := queryClient.HistoricalInfo(gocontext.Background(), req)
   621  			if tc.expPass {
   622  				suite.NoError(err)
   623  				suite.NotNil(res)
   624  				suite.True(hi.Equal(res.Hist))
   625  			} else {
   626  				suite.Error(err)
   627  				suite.Nil(res)
   628  			}
   629  		})
   630  	}
   631  }
   632  
   633  func (suite *KeeperTestSuite) TestGRPCQueryRedelegations() {
   634  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   635  
   636  	addrAcc, addrAcc1 := addrs[0], addrs[1]
   637  	valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
   638  	val1, val2, val3, val4 := vals[0], vals[1], valAddrs[3], valAddrs[4]
   639  	delAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
   640  	_, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, types.Unbonded, val1, true)
   641  	suite.NoError(err)
   642  	applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
   643  
   644  	rdAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
   645  	_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
   646  	suite.NoError(err)
   647  	applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
   648  
   649  	redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator())
   650  	suite.True(found)
   651  
   652  	var req *types.QueryRedelegationsRequest
   653  	testCases := []struct {
   654  		msg      string
   655  		malleate func()
   656  		expPass  bool
   657  		expErr   bool
   658  	}{
   659  		{
   660  			"request redelegations for non existent addr",
   661  			func() {
   662  				req = &types.QueryRedelegationsRequest{DelegatorAddr: addrAcc.String()}
   663  			},
   664  			false,
   665  			false,
   666  		},
   667  		{
   668  			"request redelegations with non existent pairs",
   669  			func() {
   670  				req = &types.QueryRedelegationsRequest{
   671  					DelegatorAddr: addrAcc.String(), SrcValidatorAddr: val3.String(),
   672  					DstValidatorAddr: val4.String(),
   673  				}
   674  			},
   675  			false,
   676  			true,
   677  		},
   678  		{
   679  			"request redelegations with delegatoraddr, sourceValAddr, destValAddr",
   680  			func() {
   681  				req = &types.QueryRedelegationsRequest{
   682  					DelegatorAddr: addrAcc1.String(), SrcValidatorAddr: val1.OperatorAddress,
   683  					DstValidatorAddr: val2.OperatorAddress, Pagination: &query.PageRequest{},
   684  				}
   685  			},
   686  			true,
   687  			false,
   688  		},
   689  		{
   690  			"request redelegations with delegatoraddr and sourceValAddr",
   691  			func() {
   692  				req = &types.QueryRedelegationsRequest{
   693  					DelegatorAddr: addrAcc1.String(), SrcValidatorAddr: val1.OperatorAddress,
   694  					Pagination: &query.PageRequest{},
   695  				}
   696  			},
   697  			true,
   698  			false,
   699  		},
   700  		{
   701  			"query redelegations with sourceValAddr only",
   702  			func() {
   703  				req = &types.QueryRedelegationsRequest{
   704  					SrcValidatorAddr: val1.GetOperator().String(),
   705  					Pagination:       &query.PageRequest{Limit: 1, CountTotal: true},
   706  				}
   707  			},
   708  			true,
   709  			false,
   710  		},
   711  	}
   712  
   713  	for _, tc := range testCases {
   714  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   715  			tc.malleate()
   716  			res, err := queryClient.Redelegations(gocontext.Background(), req)
   717  			if tc.expPass && !tc.expErr {
   718  				suite.NoError(err)
   719  				suite.Len(res.RedelegationResponses, len(redel.Entries))
   720  				suite.Equal(redel.DelegatorAddress, res.RedelegationResponses[0].Redelegation.DelegatorAddress)
   721  				suite.Equal(redel.ValidatorSrcAddress, res.RedelegationResponses[0].Redelegation.ValidatorSrcAddress)
   722  				suite.Equal(redel.ValidatorDstAddress, res.RedelegationResponses[0].Redelegation.ValidatorDstAddress)
   723  				suite.Len(redel.Entries, len(res.RedelegationResponses[0].Entries))
   724  			} else if !tc.expPass && !tc.expErr {
   725  				suite.NoError(err)
   726  				suite.Nil(res.RedelegationResponses)
   727  			} else {
   728  				suite.Error(err)
   729  				suite.Nil(res)
   730  			}
   731  		})
   732  	}
   733  }
   734  
   735  func (suite *KeeperTestSuite) TestGRPCQueryValidatorUnbondingDelegations() {
   736  	app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
   737  	addrAcc1, _ := addrs[0], addrs[1]
   738  	val1 := vals[0]
   739  
   740  	// undelegate
   741  	undelAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
   742  	_, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
   743  	suite.NoError(err)
   744  	applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1)
   745  
   746  	var req *types.QueryValidatorUnbondingDelegationsRequest
   747  	testCases := []struct {
   748  		msg      string
   749  		malleate func()
   750  		expPass  bool
   751  	}{
   752  		{
   753  			"empty request",
   754  			func() {
   755  				req = &types.QueryValidatorUnbondingDelegationsRequest{}
   756  			},
   757  			false,
   758  		},
   759  		{
   760  			"valid request",
   761  			func() {
   762  				req = &types.QueryValidatorUnbondingDelegationsRequest{
   763  					ValidatorAddr: val1.GetOperator().String(),
   764  					Pagination:    &query.PageRequest{Limit: 1, CountTotal: true},
   765  				}
   766  			},
   767  			true,
   768  		},
   769  	}
   770  
   771  	for _, tc := range testCases {
   772  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   773  			tc.malleate()
   774  			res, err := queryClient.ValidatorUnbondingDelegations(gocontext.Background(), req)
   775  			if tc.expPass {
   776  				suite.NoError(err)
   777  				suite.Equal(uint64(1), res.Pagination.Total)
   778  				suite.Equal(1, len(res.UnbondingResponses))
   779  				suite.Equal(res.UnbondingResponses[0].ValidatorAddress, val1.OperatorAddress)
   780  			} else {
   781  				suite.Error(err)
   782  				suite.Nil(res)
   783  			}
   784  		})
   785  	}
   786  }
   787  
   788  func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
   789  	addrs := simapp.AddTestAddrsIncremental(app, ctx, 5, app.StakingKeeper.TokensFromConsensusPower(ctx, 300))
   790  	valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
   791  	pks := simapp.CreateTestPubKeys(5)
   792  	cdc := simapp.MakeTestEncodingConfig().Marshaler
   793  	app.StakingKeeper = keeper.NewKeeper(
   794  		cdc,
   795  		app.GetKey(types.StoreKey),
   796  		app.AccountKeeper,
   797  		app.BankKeeper,
   798  		app.GetSubspace(types.ModuleName),
   799  	)
   800  
   801  	val1 := teststaking.NewValidator(t, valAddrs[0], pks[0])
   802  	val2 := teststaking.NewValidator(t, valAddrs[1], pks[1])
   803  	vals := []types.Validator{val1, val2}
   804  
   805  	app.StakingKeeper.SetValidator(ctx, val1)
   806  	app.StakingKeeper.SetValidator(ctx, val2)
   807  	app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)
   808  	app.StakingKeeper.SetValidatorByConsAddr(ctx, val2)
   809  	app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1)
   810  	app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2)
   811  
   812  	_, err := app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[0]), types.Unbonded, val1, true)
   813  	require.NoError(t, err)
   814  	_, err = app.StakingKeeper.Delegate(ctx, addrs[1], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[1]), types.Unbonded, val2, true)
   815  	require.NoError(t, err)
   816  	_, err = app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[2]), types.Unbonded, val2, true)
   817  	require.NoError(t, err)
   818  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
   819  
   820  	return addrs, valAddrs, vals
   821  }