github.com/Finschia/finschia-sdk@v0.49.1/x/staking/client/testutil/grpc.go (about)

     1  package testutil
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/gogo/protobuf/proto"
     7  
     8  	"github.com/Finschia/finschia-sdk/crypto/hd"
     9  	"github.com/Finschia/finschia-sdk/crypto/keyring"
    10  	"github.com/Finschia/finschia-sdk/testutil"
    11  	"github.com/Finschia/finschia-sdk/testutil/rest"
    12  	sdk "github.com/Finschia/finschia-sdk/types"
    13  	grpctypes "github.com/Finschia/finschia-sdk/types/grpc"
    14  	"github.com/Finschia/finschia-sdk/types/query"
    15  	"github.com/Finschia/finschia-sdk/x/staking/client/cli"
    16  	"github.com/Finschia/finschia-sdk/x/staking/types"
    17  )
    18  
    19  func (s *IntegrationTestSuite) TestGRPCQueryValidatorsHandler() {
    20  	val := s.network.Validators[0]
    21  	baseURL := val.APIAddress
    22  
    23  	testCases := []struct {
    24  		name  string
    25  		url   string
    26  		error bool
    27  	}{
    28  		{
    29  			"test query validators gRPC route with invalid status",
    30  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=active", baseURL),
    31  			true,
    32  		},
    33  		{
    34  			"test query validators gRPC route without status query param",
    35  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators", baseURL),
    36  			false,
    37  		},
    38  		{
    39  			"test query validators gRPC route with valid status",
    40  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=%s", baseURL, types.Bonded.String()),
    41  			false,
    42  		},
    43  	}
    44  
    45  	for _, tc := range testCases {
    46  		s.Run(tc.name, func() {
    47  			resp, err := rest.GetRequest(tc.url)
    48  			s.Require().NoError(err)
    49  
    50  			var valRes types.QueryValidatorsResponse
    51  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &valRes)
    52  
    53  			if tc.error {
    54  				s.Require().Error(err)
    55  				s.Require().Nil(valRes.Validators)
    56  				s.Require().Equal(0, len(valRes.Validators))
    57  			} else {
    58  				s.Require().NoError(err)
    59  				s.Require().NotNil(valRes.Validators)
    60  				s.Require().Equal(len(s.network.Validators), len(valRes.Validators))
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func (s *IntegrationTestSuite) TestGRPCQueryValidator() {
    67  	val := s.network.Validators[0]
    68  	baseURL := val.APIAddress
    69  
    70  	testCases := []struct {
    71  		name  string
    72  		url   string
    73  		error bool
    74  	}{
    75  		{
    76  			"wrong validator address",
    77  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, "wrongValidatorAddress"),
    78  			true,
    79  		},
    80  		{
    81  			"with no validator address",
    82  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, ""),
    83  			true,
    84  		},
    85  		{
    86  			"valid request",
    87  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", baseURL, val.ValAddress.String()),
    88  			false,
    89  		},
    90  	}
    91  
    92  	for _, tc := range testCases {
    93  		s.Run(tc.name, func() {
    94  			resp, err := rest.GetRequest(tc.url)
    95  			s.Require().NoError(err)
    96  
    97  			var validator types.QueryValidatorResponse
    98  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validator)
    99  
   100  			if tc.error {
   101  				s.Require().Error(err)
   102  			} else {
   103  				s.Require().NoError(err)
   104  				s.Require().NotNil(validator.Validator)
   105  				s.Require().Equal(s.network.Validators[0].ValAddress.String(), validator.Validator.OperatorAddress)
   106  			}
   107  		})
   108  	}
   109  }
   110  
   111  func (s *IntegrationTestSuite) TestGRPCQueryValidatorDelegations() {
   112  	val := s.network.Validators[0]
   113  	baseURL := val.APIAddress
   114  
   115  	testCases := []struct {
   116  		name         string
   117  		url          string
   118  		headers      map[string]string
   119  		error        bool
   120  		respType     proto.Message
   121  		expectedResp proto.Message
   122  	}{
   123  		{
   124  			"wrong validator address",
   125  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, "wrongValAddress"),
   126  			map[string]string{},
   127  			true,
   128  			&types.QueryValidatorDelegationsResponse{},
   129  			nil,
   130  		},
   131  		{
   132  			"with no validator address",
   133  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, ""),
   134  			map[string]string{},
   135  			true,
   136  			&types.QueryValidatorDelegationsResponse{},
   137  			nil,
   138  		},
   139  		{
   140  			"valid request(height specific)",
   141  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations", baseURL, val.ValAddress.String()),
   142  			map[string]string{
   143  				grpctypes.GRPCBlockHeightHeader: "1",
   144  			},
   145  			false,
   146  			&types.QueryValidatorDelegationsResponse{},
   147  			&types.QueryValidatorDelegationsResponse{
   148  				DelegationResponses: types.DelegationResponses{
   149  					types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)),
   150  				},
   151  				Pagination: &query.PageResponse{Total: 1},
   152  			},
   153  		},
   154  	}
   155  
   156  	for _, tc := range testCases {
   157  		s.Run(tc.name, func() {
   158  			resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
   159  			s.Require().NoError(err)
   160  
   161  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
   162  
   163  			if tc.error {
   164  				s.Require().Error(err)
   165  			} else {
   166  				s.Require().NoError(err)
   167  				s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
   168  			}
   169  		})
   170  	}
   171  }
   172  
   173  func (s *IntegrationTestSuite) TestGRPCQueryValidatorUnbondingDelegations() {
   174  	val := s.network.Validators[0]
   175  	baseURL := val.APIAddress
   176  
   177  	testCases := []struct {
   178  		name  string
   179  		url   string
   180  		error bool
   181  	}{
   182  		{
   183  			"wrong validator address",
   184  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, "wrongValAddress"),
   185  			true,
   186  		},
   187  		{
   188  			"with no validator address",
   189  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, ""),
   190  			true,
   191  		},
   192  		{
   193  			"valid request",
   194  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/unbonding_delegations", baseURL, val.ValAddress.String()),
   195  			false,
   196  		},
   197  	}
   198  
   199  	for _, tc := range testCases {
   200  		s.Run(tc.name, func() {
   201  			resp, err := rest.GetRequest(tc.url)
   202  			s.Require().NoError(err)
   203  
   204  			var ubds types.QueryValidatorUnbondingDelegationsResponse
   205  
   206  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubds)
   207  
   208  			if tc.error {
   209  				s.Require().Error(err)
   210  			} else {
   211  				s.Require().NoError(err)
   212  				s.Require().Len(ubds.UnbondingResponses, 1)
   213  				s.Require().Equal(ubds.UnbondingResponses[0].ValidatorAddress, val.ValAddress.String())
   214  			}
   215  		})
   216  	}
   217  }
   218  
   219  func (s *IntegrationTestSuite) TestGRPCQueryDelegation() {
   220  	val := s.network.Validators[0]
   221  	val2 := s.network.Validators[1]
   222  	baseURL := val.APIAddress
   223  
   224  	testCases := []struct {
   225  		name         string
   226  		url          string
   227  		error        bool
   228  		respType     proto.Message
   229  		expectedResp proto.Message
   230  	}{
   231  		{
   232  			"wrong validator address",
   233  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, "wrongValAddress", val.Address.String()),
   234  			true,
   235  			&types.QueryDelegationResponse{},
   236  			nil,
   237  		},
   238  		{
   239  			"wrong account address",
   240  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val.ValAddress.String(), "wrongAccAddress"),
   241  			true,
   242  			&types.QueryDelegationResponse{},
   243  			nil,
   244  		},
   245  		{
   246  			"with no validator address",
   247  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, "", val.Address.String()),
   248  			true,
   249  			&types.QueryDelegationResponse{},
   250  			nil,
   251  		},
   252  		{
   253  			"with no account address",
   254  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val.ValAddress.String(), ""),
   255  			true,
   256  			&types.QueryDelegationResponse{},
   257  			nil,
   258  		},
   259  		{
   260  			"valid request",
   261  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", baseURL, val2.ValAddress.String(), val.Address.String()),
   262  			false,
   263  			&types.QueryDelegationResponse{},
   264  			&types.QueryDelegationResponse{
   265  				DelegationResponse: &types.DelegationResponse{
   266  					Delegation: types.Delegation{
   267  						DelegatorAddress: val.Address.String(),
   268  						ValidatorAddress: val2.ValAddress.String(),
   269  						Shares:           sdk.NewDec(10),
   270  					},
   271  					Balance: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
   272  				},
   273  			},
   274  		},
   275  	}
   276  
   277  	for _, tc := range testCases {
   278  		s.Run(tc.name, func() {
   279  			resp, err := rest.GetRequest(tc.url)
   280  			s.Require().NoError(err)
   281  			s.T().Logf("%s", resp)
   282  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
   283  
   284  			if tc.error {
   285  				s.Require().Error(err)
   286  			} else {
   287  				s.Require().NoError(err)
   288  				s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
   289  			}
   290  		})
   291  	}
   292  }
   293  
   294  func (s *IntegrationTestSuite) TestGRPCQueryUnbondingDelegation() {
   295  	val := s.network.Validators[0]
   296  	baseURL := val.APIAddress
   297  
   298  	testCases := []struct {
   299  		name  string
   300  		url   string
   301  		error bool
   302  	}{
   303  		{
   304  			"wrong validator address",
   305  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, "wrongValAddress", val.Address.String()),
   306  			true,
   307  		},
   308  		{
   309  			"wrong account address",
   310  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), "wrongAccAddress"),
   311  			true,
   312  		},
   313  		{
   314  			"with no validator address",
   315  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, "", val.Address.String()),
   316  			true,
   317  		},
   318  		{
   319  			"with no account address",
   320  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), ""),
   321  			true,
   322  		},
   323  		{
   324  			"valid request",
   325  			fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s/unbonding_delegation", baseURL, val.ValAddress.String(), val.Address.String()),
   326  			false,
   327  		},
   328  	}
   329  
   330  	for _, tc := range testCases {
   331  		s.Run(tc.name, func() {
   332  			resp, err := rest.GetRequest(tc.url)
   333  			s.Require().NoError(err)
   334  
   335  			var ubd types.QueryUnbondingDelegationResponse
   336  
   337  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubd)
   338  
   339  			if tc.error {
   340  				s.Require().Error(err)
   341  			} else {
   342  				s.Require().NoError(err)
   343  				s.Require().Equal(ubd.Unbond.DelegatorAddress, val.Address.String())
   344  				s.Require().Equal(ubd.Unbond.ValidatorAddress, val.ValAddress.String())
   345  				s.Require().Len(ubd.Unbond.Entries, 1)
   346  			}
   347  		})
   348  	}
   349  }
   350  
   351  func (s *IntegrationTestSuite) TestGRPCQueryDelegatorDelegations() {
   352  	val := s.network.Validators[0]
   353  	baseURL := val.APIAddress
   354  
   355  	// Create new account in the keyring for address without delegations.
   356  	info, _, err := val.ClientCtx.Keyring.NewMnemonic("test", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
   357  	s.Require().NoError(err)
   358  	newAddr := sdk.AccAddress(info.GetPubKey().Address())
   359  
   360  	testCases := []struct {
   361  		name         string
   362  		url          string
   363  		headers      map[string]string
   364  		error        bool
   365  		respType     proto.Message
   366  		expectedResp proto.Message
   367  	}{
   368  		{
   369  			"wrong validator address",
   370  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, "wrongValAddress"),
   371  			map[string]string{},
   372  			true,
   373  			&types.QueryDelegatorDelegationsResponse{},
   374  			nil,
   375  		},
   376  		{
   377  			"with no validator address",
   378  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, ""),
   379  			map[string]string{},
   380  			true,
   381  			&types.QueryDelegatorDelegationsResponse{},
   382  			nil,
   383  		},
   384  		{
   385  			"valid request (height specific)",
   386  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, val.Address.String()),
   387  			map[string]string{
   388  				grpctypes.GRPCBlockHeightHeader: "1",
   389  			},
   390  			false,
   391  			&types.QueryDelegatorDelegationsResponse{},
   392  			&types.QueryDelegatorDelegationsResponse{
   393  				DelegationResponses: types.DelegationResponses{
   394  					types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)),
   395  				},
   396  				Pagination: &query.PageResponse{Total: 1},
   397  			},
   398  		},
   399  		{
   400  			"address without delegations",
   401  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", baseURL, newAddr.String()),
   402  			map[string]string{
   403  				grpctypes.GRPCBlockHeightHeader: "1",
   404  			},
   405  			false,
   406  			&types.QueryDelegatorDelegationsResponse{},
   407  			&types.QueryDelegatorDelegationsResponse{
   408  				DelegationResponses: types.DelegationResponses{},
   409  				Pagination:          &query.PageResponse{Total: 0},
   410  			},
   411  		},
   412  	}
   413  
   414  	for _, tc := range testCases {
   415  		s.Run(tc.name, func() {
   416  			resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
   417  			s.Require().NoError(err)
   418  
   419  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)
   420  
   421  			if tc.error {
   422  				s.Require().Error(err)
   423  			} else {
   424  				s.Require().NoError(err)
   425  				s.Require().Equal(tc.expectedResp.String(), tc.respType.String())
   426  			}
   427  		})
   428  	}
   429  }
   430  
   431  func (s *IntegrationTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() {
   432  	val := s.network.Validators[0]
   433  	baseURL := val.APIAddress
   434  
   435  	testCases := []struct {
   436  		name       string
   437  		url        string
   438  		error      bool
   439  		ubdsLength int
   440  	}{
   441  		{
   442  			"wrong validator address",
   443  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, "wrongValAddress"),
   444  			true,
   445  			0,
   446  		},
   447  		{
   448  			"with no validator address",
   449  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, ""),
   450  			true,
   451  			0,
   452  		},
   453  		{
   454  			"valid request",
   455  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/unbonding_delegations", baseURL, val.Address.String()),
   456  			false,
   457  			1,
   458  		},
   459  	}
   460  
   461  	for _, tc := range testCases {
   462  		s.Run(tc.name, func() {
   463  			resp, err := rest.GetRequest(tc.url)
   464  			s.Require().NoError(err)
   465  
   466  			var ubds types.QueryDelegatorUnbondingDelegationsResponse
   467  
   468  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &ubds)
   469  
   470  			if tc.error {
   471  				s.Require().Error(err)
   472  			} else {
   473  				s.Require().NoError(err)
   474  				s.Require().Len(ubds.UnbondingResponses, tc.ubdsLength)
   475  			}
   476  		})
   477  	}
   478  }
   479  
   480  func (s *IntegrationTestSuite) TestGRPCQueryRedelegations() {
   481  	val := s.network.Validators[0]
   482  	val2 := s.network.Validators[1]
   483  	baseURL := val.APIAddress
   484  
   485  	testCases := []struct {
   486  		name  string
   487  		url   string
   488  		error bool
   489  	}{
   490  		{
   491  			"wrong validator address",
   492  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, "wrongValAddress"),
   493  			true,
   494  		},
   495  		{
   496  			"with no validator address",
   497  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, ""),
   498  			true,
   499  		},
   500  		{
   501  			"valid request",
   502  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations", baseURL, val.Address.String()),
   503  			false,
   504  		},
   505  		{
   506  			"valid request with src address",
   507  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?src_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String()),
   508  			false,
   509  		},
   510  		{
   511  			"valid request with dst address",
   512  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?dst_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String()),
   513  			false,
   514  		},
   515  		{
   516  			"valid request with dst address",
   517  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/redelegations?src_validator_addr=%s&dst_validator_addr=%s", baseURL, val.Address.String(), val.ValAddress.String(), val2.ValAddress.String()),
   518  			false,
   519  		},
   520  	}
   521  
   522  	for _, tc := range testCases {
   523  		s.Run(tc.name, func() {
   524  			resp, err := rest.GetRequest(tc.url)
   525  			s.Require().NoError(err)
   526  			var redelegations types.QueryRedelegationsResponse
   527  
   528  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &redelegations)
   529  
   530  			if tc.error {
   531  				s.Require().Error(err)
   532  			} else {
   533  				s.Require().NoError(err)
   534  
   535  				s.Require().Len(redelegations.RedelegationResponses, 1)
   536  				s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.DelegatorAddress, val.Address.String())
   537  				s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorSrcAddress, val.ValAddress.String())
   538  				s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorDstAddress, val2.ValAddress.String())
   539  			}
   540  		})
   541  	}
   542  }
   543  
   544  func (s *IntegrationTestSuite) TestGRPCQueryDelegatorValidators() {
   545  	val := s.network.Validators[0]
   546  	baseURL := val.APIAddress
   547  
   548  	testCases := []struct {
   549  		name  string
   550  		url   string
   551  		error bool
   552  	}{
   553  		{
   554  			"wrong delegator address",
   555  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, "wrongDelAddress"),
   556  			true,
   557  		},
   558  		{
   559  			"with no delegator address",
   560  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, ""),
   561  			true,
   562  		},
   563  		{
   564  			"valid request",
   565  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators", baseURL, val.Address.String()),
   566  			false,
   567  		},
   568  	}
   569  
   570  	for _, tc := range testCases {
   571  		s.Run(tc.name, func() {
   572  			resp, err := rest.GetRequest(tc.url)
   573  			s.Require().NoError(err)
   574  
   575  			var validators types.QueryDelegatorValidatorsResponse
   576  
   577  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validators)
   578  
   579  			if tc.error {
   580  				s.Require().Error(err)
   581  			} else {
   582  				s.Require().NoError(err)
   583  				s.Require().Len(validators.Validators, len(s.network.Validators))
   584  				s.Require().Equal(int(validators.Pagination.Total), len(s.network.Validators))
   585  			}
   586  		})
   587  	}
   588  }
   589  
   590  func (s *IntegrationTestSuite) TestGRPCQueryDelegatorValidator() {
   591  	val := s.network.Validators[0]
   592  	baseURL := val.APIAddress
   593  
   594  	testCases := []struct {
   595  		name  string
   596  		url   string
   597  		error bool
   598  	}{
   599  		{
   600  			"wrong delegator address",
   601  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, "wrongAccAddress", val.ValAddress.String()),
   602  			true,
   603  		},
   604  		{
   605  			"wrong validator address",
   606  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), "wrongValAddress"),
   607  			true,
   608  		},
   609  		{
   610  			"with empty delegator address",
   611  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, "", val.ValAddress.String()),
   612  			true,
   613  		},
   614  		{
   615  			"with empty validator address",
   616  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), ""),
   617  			true,
   618  		},
   619  		{
   620  			"valid request",
   621  			fmt.Sprintf("%s/cosmos/staking/v1beta1/delegators/%s/validators/%s", baseURL, val.Address.String(), val.ValAddress.String()),
   622  			false,
   623  		},
   624  	}
   625  
   626  	for _, tc := range testCases {
   627  		s.Run(tc.name, func() {
   628  			resp, err := rest.GetRequest(tc.url)
   629  			s.Require().NoError(err)
   630  
   631  			var validator types.QueryDelegatorValidatorResponse
   632  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &validator)
   633  
   634  			if tc.error {
   635  				s.Require().Error(err)
   636  			} else {
   637  				s.Require().NoError(err)
   638  				s.Require().NotNil(validator)
   639  				s.Require().Equal(validator.Validator.OperatorAddress, val.ValAddress.String())
   640  			}
   641  		})
   642  	}
   643  }
   644  
   645  func (s *IntegrationTestSuite) TestGRPCQueryHistoricalInfo() {
   646  	val := s.network.Validators[0]
   647  	baseURL := val.APIAddress
   648  
   649  	testCases := []struct {
   650  		name  string
   651  		url   string
   652  		error bool
   653  	}{
   654  		{
   655  			"wrong height",
   656  			fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, "-1"),
   657  			true,
   658  		},
   659  		{
   660  			"with no height",
   661  			fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, ""),
   662  			true,
   663  		},
   664  		{
   665  			"valid request",
   666  			fmt.Sprintf("%s/cosmos/staking/v1beta1/historical_info/%s", baseURL, "2"),
   667  			false,
   668  		},
   669  	}
   670  
   671  	for _, tc := range testCases {
   672  		s.Run(tc.name, func() {
   673  			resp, err := rest.GetRequest(tc.url)
   674  			s.Require().NoError(err)
   675  
   676  			var historicalInfo types.QueryHistoricalInfoResponse
   677  
   678  			err = val.ClientCtx.Codec.UnmarshalJSON(resp, &historicalInfo)
   679  
   680  			if tc.error {
   681  				s.Require().Error(err)
   682  			} else {
   683  				s.Require().NoError(err)
   684  				s.Require().NotNil(historicalInfo)
   685  			}
   686  		})
   687  	}
   688  }
   689  
   690  func (s *IntegrationTestSuite) TestGRPCQueryParams() {
   691  	val := s.network.Validators[0]
   692  	baseURL := val.APIAddress
   693  
   694  	testCases := []struct {
   695  		name     string
   696  		url      string
   697  		respType proto.Message
   698  		expected proto.Message
   699  	}{
   700  		{
   701  			"gRPC request params",
   702  			fmt.Sprintf("%s/cosmos/staking/v1beta1/params", baseURL),
   703  			&types.QueryParamsResponse{},
   704  			&types.QueryParamsResponse{
   705  				Params: types.DefaultParams(),
   706  			},
   707  		},
   708  	}
   709  
   710  	for _, tc := range testCases {
   711  		resp, err := rest.GetRequest(tc.url)
   712  		s.Run(tc.name, func() {
   713  			s.Require().NoError(err)
   714  			s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
   715  			s.Require().Equal(tc.expected, tc.respType)
   716  		})
   717  	}
   718  }
   719  
   720  func (s *IntegrationTestSuite) TestGRPCQueryPool() {
   721  	val := s.network.Validators[0]
   722  	baseURL := val.APIAddress
   723  
   724  	testCases := []struct {
   725  		name     string
   726  		url      string
   727  		headers  map[string]string
   728  		respType proto.Message
   729  		expected proto.Message
   730  	}{
   731  		{
   732  			"gRPC request params",
   733  			fmt.Sprintf("%s/cosmos/staking/v1beta1/pool", baseURL),
   734  			map[string]string{
   735  				grpctypes.GRPCBlockHeightHeader: "1",
   736  			},
   737  			&types.QueryPoolResponse{},
   738  			&types.QueryPoolResponse{
   739  				Pool: types.Pool{
   740  					NotBondedTokens: sdk.NewInt(0),
   741  					BondedTokens:    cli.DefaultTokens.Mul(sdk.NewInt(2)),
   742  				},
   743  			},
   744  		},
   745  	}
   746  
   747  	for _, tc := range testCases {
   748  		resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
   749  		s.Run(tc.name, func() {
   750  			s.Require().NoError(err)
   751  			s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
   752  			s.Require().Equal(tc.expected.String(), tc.respType.String())
   753  		})
   754  	}
   755  }