github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/rpc/client/client_test.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"fmt"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/gnolang/gno/tm2/pkg/amino"
    12  	abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
    13  	cstypes "github.com/gnolang/gno/tm2/pkg/bft/consensus/types"
    14  	ctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/core/types"
    15  	types "github.com/gnolang/gno/tm2/pkg/bft/rpc/lib/types"
    16  	bfttypes "github.com/gnolang/gno/tm2/pkg/bft/types"
    17  	"github.com/gnolang/gno/tm2/pkg/p2p"
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  // generateMockRequestClient generates a single RPC request mock client
    23  func generateMockRequestClient(
    24  	t *testing.T,
    25  	method string,
    26  	verifyParamsFn func(*testing.T, map[string]any),
    27  	responseData any,
    28  ) *mockClient {
    29  	t.Helper()
    30  
    31  	return &mockClient{
    32  		sendRequestFn: func(
    33  			_ context.Context,
    34  			request types.RPCRequest,
    35  		) (*types.RPCResponse, error) {
    36  			// Validate the request
    37  			require.Equal(t, "2.0", request.JSONRPC)
    38  			require.NotNil(t, request.ID)
    39  			require.Equal(t, request.Method, method)
    40  
    41  			// Validate the params
    42  			var params map[string]any
    43  			require.NoError(t, json.Unmarshal(request.Params, &params))
    44  
    45  			verifyParamsFn(t, params)
    46  
    47  			// Prepare the result
    48  			result, err := amino.MarshalJSON(responseData)
    49  			require.NoError(t, err)
    50  
    51  			// Prepare the response
    52  			response := &types.RPCResponse{
    53  				JSONRPC: "2.0",
    54  				ID:      request.ID,
    55  				Result:  result,
    56  				Error:   nil,
    57  			}
    58  
    59  			return response, nil
    60  		},
    61  	}
    62  }
    63  
    64  // generateMockRequestsClient generates a batch RPC request mock client
    65  func generateMockRequestsClient(
    66  	t *testing.T,
    67  	method string,
    68  	verifyParamsFn func(*testing.T, map[string]any),
    69  	responseData []any,
    70  ) *mockClient {
    71  	t.Helper()
    72  
    73  	return &mockClient{
    74  		sendBatchFn: func(
    75  			_ context.Context,
    76  			requests types.RPCRequests,
    77  		) (types.RPCResponses, error) {
    78  			responses := make(types.RPCResponses, 0, len(requests))
    79  
    80  			// Validate the requests
    81  			for index, r := range requests {
    82  				require.Equal(t, "2.0", r.JSONRPC)
    83  				require.NotNil(t, r.ID)
    84  				require.Equal(t, r.Method, method)
    85  
    86  				// Validate the params
    87  				var params map[string]any
    88  				require.NoError(t, json.Unmarshal(r.Params, &params))
    89  
    90  				verifyParamsFn(t, params)
    91  
    92  				// Prepare the result
    93  				result, err := amino.MarshalJSON(responseData[index])
    94  				require.NoError(t, err)
    95  
    96  				// Prepare the response
    97  				response := types.RPCResponse{
    98  					JSONRPC: "2.0",
    99  					ID:      r.ID,
   100  					Result:  result,
   101  					Error:   nil,
   102  				}
   103  
   104  				responses = append(responses, response)
   105  			}
   106  
   107  			return responses, nil
   108  		},
   109  	}
   110  }
   111  
   112  func TestRPCClient_Status(t *testing.T) {
   113  	t.Parallel()
   114  
   115  	var (
   116  		expectedStatus = &ctypes.ResultStatus{
   117  			NodeInfo: p2p.NodeInfo{
   118  				Moniker: "dummy",
   119  			},
   120  		}
   121  
   122  		verifyFn = func(t *testing.T, params map[string]any) {
   123  			t.Helper()
   124  
   125  			assert.Len(t, params, 0)
   126  		}
   127  
   128  		mockClient = generateMockRequestClient(
   129  			t,
   130  			statusMethod,
   131  			verifyFn,
   132  			expectedStatus,
   133  		)
   134  	)
   135  
   136  	// Create the client
   137  	c := NewRPCClient(mockClient)
   138  
   139  	// Get the status
   140  	status, err := c.Status()
   141  	require.NoError(t, err)
   142  
   143  	assert.Equal(t, expectedStatus, status)
   144  }
   145  
   146  func TestRPCClient_ABCIInfo(t *testing.T) {
   147  	t.Parallel()
   148  
   149  	var (
   150  		expectedInfo = &ctypes.ResultABCIInfo{
   151  			Response: abci.ResponseInfo{
   152  				LastBlockAppHash: []byte("dummy"),
   153  			},
   154  		}
   155  
   156  		verifyFn = func(t *testing.T, params map[string]any) {
   157  			t.Helper()
   158  
   159  			assert.Len(t, params, 0)
   160  		}
   161  
   162  		mockClient = generateMockRequestClient(
   163  			t,
   164  			abciInfoMethod,
   165  			verifyFn,
   166  			expectedInfo,
   167  		)
   168  	)
   169  
   170  	// Create the client
   171  	c := NewRPCClient(mockClient)
   172  
   173  	// Get the info
   174  	info, err := c.ABCIInfo()
   175  	require.NoError(t, err)
   176  
   177  	assert.Equal(t, expectedInfo, info)
   178  }
   179  
   180  func TestRPCClient_ABCIQuery(t *testing.T) {
   181  	t.Parallel()
   182  
   183  	var (
   184  		path = "path"
   185  		data = []byte("data")
   186  		opts = DefaultABCIQueryOptions
   187  
   188  		expectedQuery = &ctypes.ResultABCIQuery{
   189  			Response: abci.ResponseQuery{
   190  				Value: []byte("dummy"),
   191  			},
   192  		}
   193  
   194  		verifyFn = func(t *testing.T, params map[string]any) {
   195  			t.Helper()
   196  
   197  			assert.Equal(t, path, params["path"])
   198  			assert.Equal(t, base64.StdEncoding.EncodeToString(data), params["data"])
   199  			assert.Equal(t, fmt.Sprintf("%d", opts.Height), params["height"])
   200  			assert.Equal(t, opts.Prove, params["prove"])
   201  		}
   202  
   203  		mockClient = generateMockRequestClient(
   204  			t,
   205  			abciQueryMethod,
   206  			verifyFn,
   207  			expectedQuery,
   208  		)
   209  	)
   210  
   211  	// Create the client
   212  	c := NewRPCClient(mockClient)
   213  
   214  	// Get the query
   215  	query, err := c.ABCIQuery(path, data)
   216  	require.NoError(t, err)
   217  
   218  	assert.Equal(t, expectedQuery, query)
   219  }
   220  
   221  func TestRPCClient_BroadcastTxCommit(t *testing.T) {
   222  	t.Parallel()
   223  
   224  	var (
   225  		tx = []byte("tx")
   226  
   227  		expectedTxCommit = &ctypes.ResultBroadcastTxCommit{
   228  			Hash: []byte("dummy"),
   229  		}
   230  
   231  		verifyFn = func(t *testing.T, params map[string]any) {
   232  			t.Helper()
   233  
   234  			assert.Equal(t, base64.StdEncoding.EncodeToString(tx), params["tx"])
   235  		}
   236  
   237  		mockClient = generateMockRequestClient(
   238  			t,
   239  			broadcastTxCommitMethod,
   240  			verifyFn,
   241  			expectedTxCommit,
   242  		)
   243  	)
   244  
   245  	// Create the client
   246  	c := NewRPCClient(mockClient)
   247  
   248  	// Get the broadcast
   249  	txCommit, err := c.BroadcastTxCommit(tx)
   250  	require.NoError(t, err)
   251  
   252  	assert.Equal(t, expectedTxCommit, txCommit)
   253  }
   254  
   255  func TestRPCClient_BroadcastTxAsync(t *testing.T) {
   256  	t.Parallel()
   257  
   258  	var (
   259  		tx = []byte("tx")
   260  
   261  		expectedTxBroadcast = &ctypes.ResultBroadcastTx{
   262  			Hash: []byte("dummy"),
   263  		}
   264  
   265  		verifyFn = func(t *testing.T, params map[string]any) {
   266  			t.Helper()
   267  
   268  			assert.Equal(t, base64.StdEncoding.EncodeToString(tx), params["tx"])
   269  		}
   270  
   271  		mockClient = generateMockRequestClient(
   272  			t,
   273  			broadcastTxAsyncMethod,
   274  			verifyFn,
   275  			expectedTxBroadcast,
   276  		)
   277  	)
   278  
   279  	// Create the client
   280  	c := NewRPCClient(mockClient)
   281  
   282  	// Get the broadcast
   283  	txAsync, err := c.BroadcastTxAsync(tx)
   284  	require.NoError(t, err)
   285  
   286  	assert.Equal(t, expectedTxBroadcast, txAsync)
   287  }
   288  
   289  func TestRPCClient_BroadcastTxSync(t *testing.T) {
   290  	t.Parallel()
   291  
   292  	var (
   293  		tx = []byte("tx")
   294  
   295  		expectedTxBroadcast = &ctypes.ResultBroadcastTx{
   296  			Hash: []byte("dummy"),
   297  		}
   298  
   299  		verifyFn = func(t *testing.T, params map[string]any) {
   300  			t.Helper()
   301  
   302  			assert.Equal(t, base64.StdEncoding.EncodeToString(tx), params["tx"])
   303  		}
   304  
   305  		mockClient = generateMockRequestClient(
   306  			t,
   307  			broadcastTxSyncMethod,
   308  			verifyFn,
   309  			expectedTxBroadcast,
   310  		)
   311  	)
   312  
   313  	// Create the client
   314  	c := NewRPCClient(mockClient)
   315  
   316  	// Get the broadcast
   317  	txSync, err := c.BroadcastTxSync(tx)
   318  	require.NoError(t, err)
   319  
   320  	assert.Equal(t, expectedTxBroadcast, txSync)
   321  }
   322  
   323  func TestRPCClient_UnconfirmedTxs(t *testing.T) {
   324  	t.Parallel()
   325  
   326  	var (
   327  		limit = 10
   328  
   329  		expectedResult = &ctypes.ResultUnconfirmedTxs{
   330  			Count: 10,
   331  		}
   332  
   333  		verifyFn = func(t *testing.T, params map[string]any) {
   334  			t.Helper()
   335  
   336  			assert.Equal(t, fmt.Sprintf("%d", limit), params["limit"])
   337  		}
   338  
   339  		mockClient = generateMockRequestClient(
   340  			t,
   341  			unconfirmedTxsMethod,
   342  			verifyFn,
   343  			expectedResult,
   344  		)
   345  	)
   346  
   347  	// Create the client
   348  	c := NewRPCClient(mockClient)
   349  
   350  	// Get the result
   351  	result, err := c.UnconfirmedTxs(limit)
   352  	require.NoError(t, err)
   353  
   354  	assert.Equal(t, expectedResult, result)
   355  }
   356  
   357  func TestRPCClient_NumUnconfirmedTxs(t *testing.T) {
   358  	t.Parallel()
   359  
   360  	var (
   361  		expectedResult = &ctypes.ResultUnconfirmedTxs{
   362  			Count: 10,
   363  		}
   364  
   365  		verifyFn = func(t *testing.T, params map[string]any) {
   366  			t.Helper()
   367  
   368  			assert.Len(t, params, 0)
   369  		}
   370  
   371  		mockClient = generateMockRequestClient(
   372  			t,
   373  			numUnconfirmedTxsMethod,
   374  			verifyFn,
   375  			expectedResult,
   376  		)
   377  	)
   378  
   379  	// Create the client
   380  	c := NewRPCClient(mockClient)
   381  
   382  	// Get the result
   383  	result, err := c.NumUnconfirmedTxs()
   384  	require.NoError(t, err)
   385  
   386  	assert.Equal(t, expectedResult, result)
   387  }
   388  
   389  func TestRPCClient_NetInfo(t *testing.T) {
   390  	t.Parallel()
   391  
   392  	var (
   393  		expectedResult = &ctypes.ResultNetInfo{
   394  			NPeers: 10,
   395  		}
   396  
   397  		verifyFn = func(t *testing.T, params map[string]any) {
   398  			t.Helper()
   399  
   400  			assert.Len(t, params, 0)
   401  		}
   402  
   403  		mockClient = generateMockRequestClient(
   404  			t,
   405  			netInfoMethod,
   406  			verifyFn,
   407  			expectedResult,
   408  		)
   409  	)
   410  
   411  	// Create the client
   412  	c := NewRPCClient(mockClient)
   413  
   414  	// Get the result
   415  	result, err := c.NetInfo()
   416  	require.NoError(t, err)
   417  
   418  	assert.Equal(t, expectedResult, result)
   419  }
   420  
   421  func TestRPCClient_DumpConsensusState(t *testing.T) {
   422  	t.Parallel()
   423  
   424  	var (
   425  		expectedResult = &ctypes.ResultDumpConsensusState{
   426  			RoundState: &cstypes.RoundState{
   427  				Round: 10,
   428  			},
   429  		}
   430  
   431  		verifyFn = func(t *testing.T, params map[string]any) {
   432  			t.Helper()
   433  
   434  			assert.Len(t, params, 0)
   435  		}
   436  
   437  		mockClient = generateMockRequestClient(
   438  			t,
   439  			dumpConsensusStateMethod,
   440  			verifyFn,
   441  			expectedResult,
   442  		)
   443  	)
   444  
   445  	// Create the client
   446  	c := NewRPCClient(mockClient)
   447  
   448  	// Get the result
   449  	result, err := c.DumpConsensusState()
   450  	require.NoError(t, err)
   451  
   452  	assert.Equal(t, expectedResult, result)
   453  }
   454  
   455  func TestRPCClient_ConsensusState(t *testing.T) {
   456  	t.Parallel()
   457  
   458  	var (
   459  		expectedResult = &ctypes.ResultConsensusState{
   460  			RoundState: cstypes.RoundStateSimple{
   461  				ProposalBlockHash: []byte("dummy"),
   462  			},
   463  		}
   464  
   465  		verifyFn = func(t *testing.T, params map[string]any) {
   466  			t.Helper()
   467  
   468  			assert.Len(t, params, 0)
   469  		}
   470  
   471  		mockClient = generateMockRequestClient(
   472  			t,
   473  			consensusStateMethod,
   474  			verifyFn,
   475  			expectedResult,
   476  		)
   477  	)
   478  
   479  	// Create the client
   480  	c := NewRPCClient(mockClient)
   481  
   482  	// Get the result
   483  	result, err := c.ConsensusState()
   484  	require.NoError(t, err)
   485  
   486  	assert.Equal(t, expectedResult, result)
   487  }
   488  
   489  func TestRPCClient_ConsensusParams(t *testing.T) {
   490  	t.Parallel()
   491  
   492  	var (
   493  		blockHeight = int64(10)
   494  
   495  		expectedResult = &ctypes.ResultConsensusParams{
   496  			BlockHeight: blockHeight,
   497  		}
   498  
   499  		verifyFn = func(t *testing.T, params map[string]any) {
   500  			t.Helper()
   501  
   502  			assert.Equal(t, fmt.Sprintf("%d", blockHeight), params["height"])
   503  		}
   504  
   505  		mockClient = generateMockRequestClient(
   506  			t,
   507  			consensusParamsMethod,
   508  			verifyFn,
   509  			expectedResult,
   510  		)
   511  	)
   512  
   513  	// Create the client
   514  	c := NewRPCClient(mockClient)
   515  
   516  	// Get the result
   517  	result, err := c.ConsensusParams(&blockHeight)
   518  	require.NoError(t, err)
   519  
   520  	assert.Equal(t, expectedResult, result)
   521  }
   522  
   523  func TestRPCClient_Health(t *testing.T) {
   524  	t.Parallel()
   525  
   526  	var (
   527  		expectedResult = &ctypes.ResultHealth{}
   528  
   529  		verifyFn = func(t *testing.T, params map[string]any) {
   530  			t.Helper()
   531  
   532  			assert.Len(t, params, 0)
   533  		}
   534  
   535  		mockClient = generateMockRequestClient(
   536  			t,
   537  			healthMethod,
   538  			verifyFn,
   539  			expectedResult,
   540  		)
   541  	)
   542  
   543  	// Create the client
   544  	c := NewRPCClient(mockClient)
   545  
   546  	// Get the result
   547  	result, err := c.Health()
   548  	require.NoError(t, err)
   549  
   550  	assert.Equal(t, expectedResult, result)
   551  }
   552  
   553  func TestRPCClient_BlockchainInfo(t *testing.T) {
   554  	t.Parallel()
   555  
   556  	var (
   557  		minHeight = int64(5)
   558  		maxHeight = int64(10)
   559  
   560  		expectedResult = &ctypes.ResultBlockchainInfo{
   561  			LastHeight: 100,
   562  		}
   563  
   564  		verifyFn = func(t *testing.T, params map[string]any) {
   565  			t.Helper()
   566  
   567  			assert.Equal(t, fmt.Sprintf("%d", minHeight), params["minHeight"])
   568  			assert.Equal(t, fmt.Sprintf("%d", maxHeight), params["maxHeight"])
   569  		}
   570  
   571  		mockClient = generateMockRequestClient(
   572  			t,
   573  			blockchainMethod,
   574  			verifyFn,
   575  			expectedResult,
   576  		)
   577  	)
   578  
   579  	// Create the client
   580  	c := NewRPCClient(mockClient)
   581  
   582  	// Get the result
   583  	result, err := c.BlockchainInfo(minHeight, maxHeight)
   584  	require.NoError(t, err)
   585  
   586  	assert.Equal(t, expectedResult, result)
   587  }
   588  
   589  func TestRPCClient_Genesis(t *testing.T) {
   590  	t.Parallel()
   591  
   592  	var (
   593  		expectedResult = &ctypes.ResultGenesis{
   594  			Genesis: &bfttypes.GenesisDoc{
   595  				ChainID: "dummy",
   596  			},
   597  		}
   598  
   599  		verifyFn = func(t *testing.T, params map[string]any) {
   600  			t.Helper()
   601  
   602  			assert.Len(t, params, 0)
   603  		}
   604  
   605  		mockClient = generateMockRequestClient(
   606  			t,
   607  			genesisMethod,
   608  			verifyFn,
   609  			expectedResult,
   610  		)
   611  	)
   612  
   613  	// Create the client
   614  	c := NewRPCClient(mockClient)
   615  
   616  	// Get the result
   617  	result, err := c.Genesis()
   618  	require.NoError(t, err)
   619  
   620  	assert.Equal(t, expectedResult, result)
   621  }
   622  
   623  func TestRPCClient_Block(t *testing.T) {
   624  	t.Parallel()
   625  
   626  	var (
   627  		height = int64(10)
   628  
   629  		expectedResult = &ctypes.ResultBlock{
   630  			BlockMeta: &bfttypes.BlockMeta{
   631  				Header: bfttypes.Header{
   632  					Height: height,
   633  				},
   634  			},
   635  		}
   636  
   637  		verifyFn = func(t *testing.T, params map[string]any) {
   638  			t.Helper()
   639  
   640  			assert.Equal(t, fmt.Sprintf("%d", height), params["height"])
   641  		}
   642  
   643  		mockClient = generateMockRequestClient(
   644  			t,
   645  			blockMethod,
   646  			verifyFn,
   647  			expectedResult,
   648  		)
   649  	)
   650  
   651  	// Create the client
   652  	c := NewRPCClient(mockClient)
   653  
   654  	// Get the result
   655  	result, err := c.Block(&height)
   656  	require.NoError(t, err)
   657  
   658  	assert.Equal(t, expectedResult, result)
   659  }
   660  
   661  func TestRPCClient_BlockResults(t *testing.T) {
   662  	t.Parallel()
   663  
   664  	var (
   665  		height = int64(10)
   666  
   667  		expectedResult = &ctypes.ResultBlockResults{
   668  			Height: height,
   669  		}
   670  
   671  		verifyFn = func(t *testing.T, params map[string]any) {
   672  			t.Helper()
   673  
   674  			assert.Equal(t, fmt.Sprintf("%d", height), params["height"])
   675  		}
   676  
   677  		mockClient = generateMockRequestClient(
   678  			t,
   679  			blockResultsMethod,
   680  			verifyFn,
   681  			expectedResult,
   682  		)
   683  	)
   684  
   685  	// Create the client
   686  	c := NewRPCClient(mockClient)
   687  
   688  	// Get the result
   689  	result, err := c.BlockResults(&height)
   690  	require.NoError(t, err)
   691  
   692  	assert.Equal(t, expectedResult, result)
   693  }
   694  
   695  func TestRPCClient_Commit(t *testing.T) {
   696  	t.Parallel()
   697  
   698  	var (
   699  		height = int64(10)
   700  
   701  		expectedResult = &ctypes.ResultCommit{
   702  			CanonicalCommit: true,
   703  		}
   704  
   705  		verifyFn = func(t *testing.T, params map[string]any) {
   706  			t.Helper()
   707  
   708  			assert.Equal(t, fmt.Sprintf("%d", height), params["height"])
   709  		}
   710  
   711  		mockClient = generateMockRequestClient(
   712  			t,
   713  			commitMethod,
   714  			verifyFn,
   715  			expectedResult,
   716  		)
   717  	)
   718  
   719  	// Create the client
   720  	c := NewRPCClient(mockClient)
   721  
   722  	// Get the result
   723  	result, err := c.Commit(&height)
   724  	require.NoError(t, err)
   725  
   726  	assert.Equal(t, expectedResult, result)
   727  }
   728  
   729  func TestRPCClient_Tx(t *testing.T) {
   730  	t.Parallel()
   731  
   732  	var (
   733  		hash = []byte("tx hash")
   734  
   735  		expectedResult = &ctypes.ResultTx{
   736  			Hash:   hash,
   737  			Height: 10,
   738  		}
   739  
   740  		verifyFn = func(t *testing.T, params map[string]any) {
   741  			t.Helper()
   742  
   743  			assert.Equal(t, base64.StdEncoding.EncodeToString(hash), params["hash"])
   744  		}
   745  
   746  		mockClient = generateMockRequestClient(
   747  			t,
   748  			txMethod,
   749  			verifyFn,
   750  			expectedResult,
   751  		)
   752  	)
   753  
   754  	// Create the client
   755  	c := NewRPCClient(mockClient)
   756  
   757  	// Get the result
   758  	result, err := c.Tx(hash)
   759  	require.NoError(t, err)
   760  
   761  	assert.Equal(t, expectedResult, result)
   762  }
   763  
   764  func TestRPCClient_Validators(t *testing.T) {
   765  	t.Parallel()
   766  
   767  	var (
   768  		height = int64(10)
   769  
   770  		expectedResult = &ctypes.ResultValidators{
   771  			BlockHeight: height,
   772  		}
   773  
   774  		verifyFn = func(t *testing.T, params map[string]any) {
   775  			t.Helper()
   776  
   777  			assert.Equal(t, fmt.Sprintf("%d", height), params["height"])
   778  		}
   779  
   780  		mockClient = generateMockRequestClient(
   781  			t,
   782  			validatorsMethod,
   783  			verifyFn,
   784  			expectedResult,
   785  		)
   786  	)
   787  
   788  	// Create the client
   789  	c := NewRPCClient(mockClient)
   790  
   791  	// Get the result
   792  	result, err := c.Validators(&height)
   793  	require.NoError(t, err)
   794  
   795  	assert.Equal(t, expectedResult, result)
   796  }
   797  
   798  func TestRPCClient_Batch(t *testing.T) {
   799  	t.Parallel()
   800  
   801  	convertResults := func(results []*ctypes.ResultStatus) []any {
   802  		res := make([]any, len(results))
   803  
   804  		for index, item := range results {
   805  			res[index] = item
   806  		}
   807  
   808  		return res
   809  	}
   810  
   811  	var (
   812  		expectedStatuses = []*ctypes.ResultStatus{
   813  			{
   814  				NodeInfo: p2p.NodeInfo{
   815  					Moniker: "dummy",
   816  				},
   817  			},
   818  			{
   819  				NodeInfo: p2p.NodeInfo{
   820  					Moniker: "dummy",
   821  				},
   822  			},
   823  			{
   824  				NodeInfo: p2p.NodeInfo{
   825  					Moniker: "dummy",
   826  				},
   827  			},
   828  		}
   829  
   830  		verifyFn = func(t *testing.T, params map[string]any) {
   831  			t.Helper()
   832  
   833  			assert.Len(t, params, 0)
   834  		}
   835  
   836  		mockClient = generateMockRequestsClient(
   837  			t,
   838  			statusMethod,
   839  			verifyFn,
   840  			convertResults(expectedStatuses),
   841  		)
   842  	)
   843  
   844  	// Create the client
   845  	c := NewRPCClient(mockClient)
   846  
   847  	// Create the batch
   848  	batch := c.NewBatch()
   849  
   850  	require.NoError(t, batch.Status())
   851  	require.NoError(t, batch.Status())
   852  	require.NoError(t, batch.Status())
   853  
   854  	require.EqualValues(t, 3, batch.Count())
   855  
   856  	// Send the batch
   857  	ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
   858  	defer cancelFn()
   859  
   860  	results, err := batch.Send(ctx)
   861  	require.NoError(t, err)
   862  
   863  	require.Len(t, results, len(expectedStatuses))
   864  
   865  	for index, result := range results {
   866  		castResult, ok := result.(*ctypes.ResultStatus)
   867  		require.True(t, ok)
   868  
   869  		assert.Equal(t, expectedStatuses[index], castResult)
   870  	}
   871  }