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