github.com/iotexproject/iotex-core@v1.14.1-rc1/api/grpcserver_test.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package api
     7  
     8  import (
     9  	"context"
    10  	"encoding/hex"
    11  	"math/big"
    12  	"testing"
    13  
    14  	"github.com/ethereum/go-ethereum/eth/tracers/logger"
    15  	"github.com/golang/mock/gomock"
    16  	"github.com/iotexproject/go-pkgs/hash"
    17  	"github.com/iotexproject/iotex-proto/golang/iotexapi"
    18  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    19  	"github.com/pkg/errors"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/iotexproject/iotex-core/action"
    23  	apitypes "github.com/iotexproject/iotex-core/api/types"
    24  	"github.com/iotexproject/iotex-core/blockchain/block"
    25  	"github.com/iotexproject/iotex-core/pkg/version"
    26  	"github.com/iotexproject/iotex-core/test/identityset"
    27  	"github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice"
    28  	mock_apitypes "github.com/iotexproject/iotex-core/test/mock/mock_apiresponder"
    29  )
    30  
    31  func TestGrpcServer_GetAccount(t *testing.T) {
    32  	require := require.New(t)
    33  	ctrl := gomock.NewController(t)
    34  	defer ctrl.Finish()
    35  	core := mock_apicoreservice.NewMockCoreService(ctrl)
    36  	grpcSvr := newGRPCHandler(core)
    37  
    38  	t.Run("get acccount", func(t *testing.T) {
    39  		for _, test := range _getAccountTests {
    40  			accountMeta := &iotextypes.AccountMeta{
    41  				Address: test.address,
    42  			}
    43  			blockIdentifier := &iotextypes.BlockIdentifier{}
    44  			request := &iotexapi.GetAccountRequest{
    45  				Address: test.address,
    46  			}
    47  
    48  			core.EXPECT().Account(gomock.Any()).Return(accountMeta, blockIdentifier, nil)
    49  
    50  			res, err := grpcSvr.GetAccount(context.Background(), request)
    51  			require.NoError(err)
    52  			require.Equal(test.address, res.AccountMeta.Address)
    53  		}
    54  	})
    55  
    56  	t.Run("failed to get account", func(t *testing.T) {
    57  		expectedErr := errors.New("failed to get account")
    58  		request := &iotexapi.GetAccountRequest{
    59  			Address: "io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2",
    60  		}
    61  
    62  		core.EXPECT().Account(gomock.Any()).Return(nil, nil, expectedErr)
    63  
    64  		_, err := grpcSvr.GetAccount(context.Background(), request)
    65  		require.Contains(err.Error(), expectedErr.Error())
    66  	})
    67  
    68  	t.Run("invalid address", func(t *testing.T) {
    69  		expectedErr := errors.New("invalid address")
    70  		request := &iotexapi.GetAccountRequest{
    71  			Address: "9254d943485d0fb859ff63c5581acc44f00fc2110343ac0445b99dfe39a6f1a5",
    72  		}
    73  
    74  		_, err := grpcSvr.GetAccount(context.Background(), request)
    75  		require.Contains(err.Error(), expectedErr.Error())
    76  	})
    77  }
    78  
    79  func TestGrpcServer_GetActions(t *testing.T) {
    80  	require := require.New(t)
    81  	ctrl := gomock.NewController(t)
    82  	defer ctrl.Finish()
    83  	core := mock_apicoreservice.NewMockCoreService(ctrl)
    84  	grpcSvr := newGRPCHandler(core)
    85  
    86  	t.Run("get actions by address tests", func(t *testing.T) {
    87  		for _, test := range _getActionsByAddressTests {
    88  			actInfo := &iotexapi.ActionInfo{
    89  				Index:   0,
    90  				ActHash: "test",
    91  			}
    92  			response := []*iotexapi.ActionInfo{}
    93  			for i := 1; i <= test.numActions; i++ {
    94  				response = append(response, actInfo)
    95  			}
    96  
    97  			requests := []struct {
    98  				req  *iotexapi.GetActionsRequest
    99  				call func()
   100  			}{
   101  				{
   102  					req: &iotexapi.GetActionsRequest{
   103  						Lookup: &iotexapi.GetActionsRequest_ByAddr{
   104  							ByAddr: &iotexapi.GetActionsByAddressRequest{
   105  								Address: test.address,
   106  								Start:   test.start,
   107  								Count:   test.count,
   108  							},
   109  						},
   110  					},
   111  					call: func() {
   112  						core.EXPECT().ActionsByAddress(gomock.Any(), gomock.Any(), gomock.Any()).Return(response, nil)
   113  					},
   114  				},
   115  				{
   116  					req: &iotexapi.GetActionsRequest{
   117  						Lookup: &iotexapi.GetActionsRequest_UnconfirmedByAddr{
   118  							UnconfirmedByAddr: &iotexapi.GetUnconfirmedActionsByAddressRequest{
   119  								Address: test.address,
   120  								Start:   test.start,
   121  								Count:   test.count,
   122  							},
   123  						},
   124  					},
   125  					call: func() {
   126  						core.EXPECT().UnconfirmedActionsByAddress(gomock.Any(), gomock.Any(), gomock.Any()).Return(response, nil)
   127  					},
   128  				},
   129  				{
   130  					req: &iotexapi.GetActionsRequest{
   131  						Lookup: &iotexapi.GetActionsRequest_ByIndex{
   132  							ByIndex: &iotexapi.GetActionsByIndexRequest{
   133  								Start: test.start,
   134  								Count: test.count,
   135  							},
   136  						},
   137  					},
   138  					call: func() {
   139  						core.EXPECT().Actions(gomock.Any(), gomock.Any()).Return(response, nil)
   140  					},
   141  				},
   142  			}
   143  
   144  			for _, request := range requests {
   145  				request.call()
   146  				res, err := grpcSvr.GetActions(context.Background(), request.req)
   147  				require.NoError(err)
   148  				require.Equal(uint64(test.numActions), res.Total)
   149  			}
   150  		}
   151  	})
   152  
   153  	t.Run("get actions by hash", func(t *testing.T) {
   154  		for _, test := range _getActionTests {
   155  			response := &iotexapi.ActionInfo{
   156  				Index:     0,
   157  				ActHash:   "test",
   158  				BlkHeight: test.blkNumber,
   159  			}
   160  			request := &iotexapi.GetActionsRequest{
   161  				Lookup: &iotexapi.GetActionsRequest_ByHash{
   162  					ByHash: &iotexapi.GetActionByHashRequest{
   163  						ActionHash:   test.in,
   164  						CheckPending: test.checkPending,
   165  					},
   166  				},
   167  			}
   168  
   169  			core.EXPECT().Action(gomock.Any(), gomock.Any()).Return(response, nil)
   170  
   171  			res, err := grpcSvr.GetActions(context.Background(), request)
   172  			require.NoError(err)
   173  			require.Len(res.ActionInfo, 1)
   174  			require.Equal(test.blkNumber, res.ActionInfo[0].BlkHeight)
   175  		}
   176  	})
   177  
   178  	t.Run("get actions by block test", func(t *testing.T) {
   179  		addr1 := identityset.Address(28).String()
   180  		priKey1 := identityset.PrivateKey(28)
   181  
   182  		tsf1, err := action.SignedTransfer(addr1, priKey1, uint64(1), big.NewInt(10), []byte{}, uint64(100000), big.NewInt(0))
   183  		require.NoError(err)
   184  
   185  		for _, test := range _getActionsByBlockTests {
   186  			gasConsumed, ok := new(big.Int).SetString(test.firstTxGas, 10)
   187  			if !ok {
   188  				gasConsumed = big.NewInt(0)
   189  			}
   190  
   191  			response := &apitypes.BlockWithReceipts{
   192  				Block:    &block.Block{},
   193  				Receipts: []*action.Receipt{},
   194  			}
   195  			for i := 1; i <= test.numActions; i++ {
   196  				response.Block.Actions = append(response.Block.Actions, tsf1)
   197  				response.Receipts = append(response.Receipts, &action.Receipt{
   198  					BlockHeight: test.blkHeight,
   199  					GasConsumed: gasConsumed.Uint64(),
   200  				})
   201  			}
   202  
   203  			request := &iotexapi.GetActionsRequest{
   204  				Lookup: &iotexapi.GetActionsRequest_ByBlk{
   205  					ByBlk: &iotexapi.GetActionsByBlockRequest{
   206  						BlkHash: _blkHash[test.blkHeight],
   207  						Start:   test.start,
   208  						Count:   test.count,
   209  					},
   210  				},
   211  			}
   212  
   213  			core.EXPECT().BlockByHash(gomock.Any()).Return(response, nil)
   214  
   215  			res, err := grpcSvr.GetActions(context.Background(), request)
   216  			require.NoError(err)
   217  			require.Equal(test.numActions-int(test.start), int(res.Total))
   218  		}
   219  	})
   220  
   221  	t.Run("invalid GetActionsRequest type", func(t *testing.T) {
   222  		expectedErr := errors.New("invalid GetActionsRequest type")
   223  		request := &iotexapi.GetActionsRequest{}
   224  
   225  		_, err := grpcSvr.GetActions(context.Background(), request)
   226  		require.Contains(err.Error(), expectedErr.Error())
   227  	})
   228  
   229  	t.Run("failed to get actions", func(t *testing.T) {
   230  		expectedErr := errors.New("failed to get actions")
   231  		request := &iotexapi.GetActionsRequest{
   232  			Lookup: &iotexapi.GetActionsRequest_ByHash{
   233  				ByHash: &iotexapi.GetActionByHashRequest{
   234  					ActionHash:   hex.EncodeToString(_transferHash1[:]),
   235  					CheckPending: false,
   236  				},
   237  			},
   238  		}
   239  
   240  		core.EXPECT().Action(gomock.Any(), gomock.Any()).Return(nil, expectedErr)
   241  
   242  		_, err := grpcSvr.GetActions(context.Background(), request)
   243  		require.Contains(err.Error(), expectedErr.Error())
   244  	})
   245  }
   246  
   247  func TestGrpcServer_GetBlockMetas(t *testing.T) {
   248  	require := require.New(t)
   249  	ctrl := gomock.NewController(t)
   250  	defer ctrl.Finish()
   251  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   252  	grpcSvr := newGRPCHandler(core)
   253  
   254  	errStr := "get block metas mock test error"
   255  	reqIndex := &iotexapi.GetBlockMetasRequest{
   256  		Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
   257  			ByIndex: &iotexapi.GetBlockMetasByIndexRequest{},
   258  		},
   259  	}
   260  	reqHash := &iotexapi.GetBlockMetasRequest{
   261  		Lookup: &iotexapi.GetBlockMetasRequest_ByHash{
   262  			ByHash: &iotexapi.GetBlockMetaByHashRequest{},
   263  		},
   264  	}
   265  	ret := &apitypes.BlockWithReceipts{
   266  		Block: &block.Block{},
   267  		Receipts: []*action.Receipt{
   268  			{},
   269  		},
   270  	}
   271  	rets := []*apitypes.BlockWithReceipts{ret}
   272  
   273  	t.Run("GetBlockMetasInvalidType", func(t *testing.T) {
   274  		_, err := grpcSvr.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{})
   275  		require.Contains(err.Error(), "invalid GetBlockMetasRequest type")
   276  	})
   277  	t.Run("GetBlockMetasByIndexFailed", func(t *testing.T) {
   278  		core.EXPECT().BlockByHeightRange(gomock.Any(), gomock.Any()).Return(nil, errors.New(errStr))
   279  		_, err := grpcSvr.GetBlockMetas(context.Background(), reqIndex)
   280  		require.Contains(err.Error(), errStr)
   281  	})
   282  	t.Run("GetBlockMetasByIndexSuccess", func(t *testing.T) {
   283  		core.EXPECT().BlockByHeightRange(gomock.Any(), gomock.Any()).Return(rets, nil)
   284  		res, err := grpcSvr.GetBlockMetas(context.Background(), reqIndex)
   285  		require.NoError(err)
   286  		require.Equal(res.Total, uint64(1))
   287  	})
   288  	t.Run("GetBlockMetasByHashFailed", func(t *testing.T) {
   289  		core.EXPECT().BlockByHash(gomock.Any()).Return(nil, errors.New(errStr))
   290  		_, err := grpcSvr.GetBlockMetas(context.Background(), reqHash)
   291  		require.Contains(err.Error(), errStr)
   292  	})
   293  	t.Run("GetBlockMetasByHashSuccess", func(t *testing.T) {
   294  		core.EXPECT().BlockByHash(gomock.Any()).Return(ret, nil)
   295  		res, err := grpcSvr.GetBlockMetas(context.Background(), reqHash)
   296  		require.NoError(err)
   297  		require.Equal(res.Total, uint64(1))
   298  	})
   299  }
   300  
   301  func TestGrpcServer_GetChainMeta(t *testing.T) {
   302  	require := require.New(t)
   303  	ctrl := gomock.NewController(t)
   304  	defer ctrl.Finish()
   305  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   306  	grpcSvr := newGRPCHandler(core)
   307  	chainMeta := &iotextypes.ChainMeta{
   308  		Height:   1000,
   309  		ChainID:  1,
   310  		Epoch:    &iotextypes.EpochData{Num: 7000},
   311  		TpsFloat: 11.22,
   312  	}
   313  	syncStatus := "sync ok"
   314  	core.EXPECT().ChainMeta().Return(chainMeta, syncStatus, nil)
   315  	request := &iotexapi.GetChainMetaRequest{}
   316  	res, err := grpcSvr.GetChainMeta(context.Background(), request)
   317  	require.NoError(err)
   318  	require.Equal(chainMeta, res.ChainMeta)
   319  	require.Equal(syncStatus, res.SyncStage)
   320  }
   321  
   322  func TestGrpcServer_SendAction(t *testing.T) {
   323  	require := require.New(t)
   324  	ctrl := gomock.NewController(t)
   325  	defer ctrl.Finish()
   326  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   327  	grpcSvr := newGRPCHandler(core)
   328  
   329  	for _, test := range _sendActionTests {
   330  		core.EXPECT().SendAction(context.Background(), test.actionPb).Return(test.actionHash, nil)
   331  		request := &iotexapi.SendActionRequest{Action: test.actionPb}
   332  		res, err := grpcSvr.SendAction(context.Background(), request)
   333  		require.NoError(err)
   334  		require.Equal(test.actionHash, res.ActionHash)
   335  	}
   336  }
   337  
   338  func TestGrpcServer_StreamBlocks(t *testing.T) {
   339  	require := require.New(t)
   340  	ctrl := gomock.NewController(t)
   341  	defer ctrl.Finish()
   342  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   343  	grpcSvr := newGRPCHandler(core)
   344  
   345  	t.Run("addResponder failed", func(t *testing.T) {
   346  		listener := mock_apitypes.NewMockListener(ctrl)
   347  		listener.EXPECT().AddResponder(gomock.Any()).Return("", errors.New("mock test"))
   348  		core.EXPECT().ChainListener().Return(listener)
   349  		err := grpcSvr.StreamBlocks(&iotexapi.StreamBlocksRequest{}, nil)
   350  		require.Contains(err.Error(), "mock test")
   351  	})
   352  
   353  	t.Run("success", func(t *testing.T) {
   354  		listener := mock_apitypes.NewMockListener(ctrl)
   355  		listener.EXPECT().AddResponder(gomock.Any()).DoAndReturn(func(g *gRPCBlockListener) (string, error) {
   356  			go func() {
   357  				g.errChan <- nil
   358  			}()
   359  			return "", nil
   360  		})
   361  		core.EXPECT().ChainListener().Return(listener)
   362  		err := grpcSvr.StreamBlocks(&iotexapi.StreamBlocksRequest{}, nil)
   363  		require.NoError(err)
   364  	})
   365  }
   366  
   367  func TestGrpcServer_StreamLogs(t *testing.T) {
   368  	require := require.New(t)
   369  	ctrl := gomock.NewController(t)
   370  	defer ctrl.Finish()
   371  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   372  	grpcSvr := newGRPCHandler(core)
   373  
   374  	t.Run("StreamLogsEmptyFilter", func(t *testing.T) {
   375  		err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{}, nil)
   376  		require.Contains(err.Error(), "empty filter")
   377  	})
   378  	t.Run("StreamLogsAddResponderFailed", func(t *testing.T) {
   379  		listener := mock_apitypes.NewMockListener(ctrl)
   380  		listener.EXPECT().AddResponder(gomock.Any()).Return("", errors.New("mock test"))
   381  		core.EXPECT().ChainListener().Return(listener)
   382  		err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{Filter: &iotexapi.LogsFilter{}}, nil)
   383  		require.Contains(err.Error(), "mock test")
   384  	})
   385  	t.Run("StreamLogsSuccess", func(t *testing.T) {
   386  		listener := mock_apitypes.NewMockListener(ctrl)
   387  		listener.EXPECT().AddResponder(gomock.Any()).DoAndReturn(func(g *gRPCLogListener) (string, error) {
   388  			go func() {
   389  				g.errChan <- nil
   390  			}()
   391  			return "", nil
   392  		})
   393  		core.EXPECT().ChainListener().Return(listener)
   394  		err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{Filter: &iotexapi.LogsFilter{}}, nil)
   395  		require.NoError(err)
   396  	})
   397  }
   398  
   399  func TestGrpcServer_GetReceiptByAction(t *testing.T) {
   400  	require := require.New(t)
   401  	ctrl := gomock.NewController(t)
   402  	defer ctrl.Finish()
   403  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   404  	grpcSvr := newGRPCHandler(core)
   405  	receipt := &action.Receipt{
   406  		Status:          1,
   407  		BlockHeight:     1,
   408  		ActionHash:      hash.BytesToHash256([]byte("test")),
   409  		GasConsumed:     1,
   410  		ContractAddress: "test",
   411  		TxIndex:         1,
   412  	}
   413  
   414  	t.Run("get receipt by action", func(t *testing.T) {
   415  		core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, nil)
   416  		core.EXPECT().BlockHashByBlockHeight(gomock.Any()).Return(hash.ZeroHash256, nil)
   417  
   418  		res, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{})
   419  		require.NoError(err)
   420  		require.Equal(receipt.Status, res.ReceiptInfo.Receipt.Status)
   421  		require.Equal(receipt.BlockHeight, res.ReceiptInfo.Receipt.BlkHeight)
   422  		require.Equal(receipt.ActionHash[:], res.ReceiptInfo.Receipt.ActHash)
   423  		require.Equal(receipt.GasConsumed, res.ReceiptInfo.Receipt.GasConsumed)
   424  		require.Equal(receipt.ContractAddress, res.ReceiptInfo.Receipt.ContractAddress)
   425  		require.Equal(receipt.TxIndex, res.ReceiptInfo.Receipt.TxIndex)
   426  		require.Equal(hex.EncodeToString(hash.ZeroHash256[:]), res.ReceiptInfo.BlkHash)
   427  	})
   428  
   429  	t.Run("failed to get block hash by block height", func(t *testing.T) {
   430  		expectedErr := errors.New("failed to get block hash by block height")
   431  		core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, nil)
   432  		core.EXPECT().BlockHashByBlockHeight(gomock.Any()).Return(hash.ZeroHash256, expectedErr)
   433  
   434  		_, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{})
   435  		require.Contains(err.Error(), expectedErr.Error())
   436  	})
   437  
   438  	t.Run("failed to get reciept by action hash", func(t *testing.T) {
   439  		expectedErr := errors.New("failed to get reciept by action hash")
   440  		core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, expectedErr)
   441  
   442  		_, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{})
   443  		require.Contains(err.Error(), expectedErr.Error())
   444  	})
   445  }
   446  
   447  func TestGrpcServer_GetServerMeta(t *testing.T) {
   448  	require := require.New(t)
   449  	ctrl := gomock.NewController(t)
   450  	defer ctrl.Finish()
   451  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   452  	grpcSvr := newGRPCHandler(core)
   453  
   454  	core.EXPECT().ServerMeta().Return("packageVersion", "packageCommitID", "gitStatus", "goVersion", "buildTime")
   455  	res, err := grpcSvr.GetServerMeta(context.Background(), &iotexapi.GetServerMetaRequest{})
   456  	require.NoError(err)
   457  	require.Equal("packageVersion", res.ServerMeta.PackageVersion)
   458  	require.Equal("packageCommitID", res.ServerMeta.PackageCommitID)
   459  	require.Equal("gitStatus", res.ServerMeta.GitStatus)
   460  	require.Equal("goVersion", res.ServerMeta.GoVersion)
   461  	require.Equal("buildTime", res.ServerMeta.BuildTime)
   462  }
   463  
   464  func TestGrpcServer_ReadContract(t *testing.T) {
   465  	require := require.New(t)
   466  	ctrl := gomock.NewController(t)
   467  	defer ctrl.Finish()
   468  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   469  	grpcSvr := newGRPCHandler(core)
   470  	response := &iotextypes.Receipt{
   471  		ActHash:     []byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"),
   472  		GasConsumed: 10100,
   473  	}
   474  
   475  	t.Run("read contract", func(t *testing.T) {
   476  		request := &iotexapi.ReadContractRequest{
   477  			Execution: &iotextypes.Execution{
   478  				Data: _executionHash1[:],
   479  			},
   480  			CallerAddress: identityset.Address(0).String(),
   481  			GasLimit:      10100,
   482  		}
   483  		core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", response, nil)
   484  
   485  		res, err := grpcSvr.ReadContract(context.Background(), request)
   486  		require.NoError(err)
   487  		require.Equal([]byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"), res.Receipt.ActHash)
   488  		require.Equal(10100, int(res.Receipt.GasConsumed))
   489  	})
   490  
   491  	t.Run("read contract from empty address", func(t *testing.T) {
   492  		request := &iotexapi.ReadContractRequest{
   493  			Execution: &iotextypes.Execution{
   494  				Data: _executionHash1[:],
   495  			},
   496  			CallerAddress: "",
   497  			GasLimit:      10100,
   498  		}
   499  		core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", response, nil)
   500  
   501  		res, err := grpcSvr.ReadContract(context.Background(), request)
   502  		require.NoError(err)
   503  		require.Equal([]byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"), res.Receipt.ActHash)
   504  		require.Equal(10100, int(res.Receipt.GasConsumed))
   505  	})
   506  
   507  	t.Run("failed to read contract", func(t *testing.T) {
   508  		expectedErr := errors.New("failed to read contract")
   509  		request := &iotexapi.ReadContractRequest{
   510  			Execution: &iotextypes.Execution{
   511  				Data: _executionHash1[:],
   512  			},
   513  			CallerAddress: "",
   514  			GasLimit:      10100,
   515  		}
   516  		core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil, expectedErr)
   517  
   518  		_, err := grpcSvr.ReadContract(context.Background(), request)
   519  		require.Contains(err.Error(), expectedErr.Error())
   520  	})
   521  
   522  	t.Run("failed to load execution", func(t *testing.T) {
   523  		expectedErr := errors.New("empty action proto to load")
   524  		request := &iotexapi.ReadContractRequest{
   525  			CallerAddress: "",
   526  			GasLimit:      10100,
   527  		}
   528  
   529  		_, err := grpcSvr.ReadContract(context.Background(), request)
   530  		require.Contains(err.Error(), expectedErr.Error())
   531  	})
   532  
   533  	t.Run("invalid caller address", func(t *testing.T) {
   534  		expectedErr := errors.New("invalid address")
   535  		request := &iotexapi.ReadContractRequest{
   536  			Execution: &iotextypes.Execution{
   537  				Data: _executionHash1[:],
   538  			},
   539  			CallerAddress: "9254d943485d0fb859ff63c5581acc44f00fc2110343ac0445b99dfe39a6f1a5",
   540  			GasLimit:      10100,
   541  		}
   542  
   543  		_, err := grpcSvr.ReadContract(context.Background(), request)
   544  		require.Contains(err.Error(), expectedErr.Error())
   545  	})
   546  }
   547  
   548  func TestGrpcServer_SuggestGasPrice(t *testing.T) {
   549  	require := require.New(t)
   550  	ctrl := gomock.NewController(t)
   551  	defer ctrl.Finish()
   552  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   553  	grpcSvr := newGRPCHandler(core)
   554  
   555  	core.EXPECT().SuggestGasPrice().Return(uint64(1), nil)
   556  	res, err := grpcSvr.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{})
   557  	require.NoError(err)
   558  	require.Equal(uint64(1), res.GasPrice)
   559  
   560  	core.EXPECT().SuggestGasPrice().Return(uint64(0), errors.New("mock gas price error"))
   561  	_, err = grpcSvr.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{})
   562  	require.Contains(err.Error(), "mock gas price error")
   563  }
   564  
   565  func TestGrpcServer_EstimateGasForAction(t *testing.T) {
   566  	require := require.New(t)
   567  	ctrl := gomock.NewController(t)
   568  	defer ctrl.Finish()
   569  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   570  	grpcSvr := newGRPCHandler(core)
   571  
   572  	core.EXPECT().EstimateGasForAction(gomock.Any(), gomock.Any()).Return(uint64(10000), nil)
   573  	resp, err := grpcSvr.EstimateGasForAction(context.Background(), &iotexapi.EstimateGasForActionRequest{Action: getAction()})
   574  	require.NoError(err)
   575  	require.Equal(uint64(10000), resp.Gas)
   576  
   577  	core.EXPECT().EstimateGasForAction(gomock.Any(), gomock.Any()).Return(uint64(0), action.ErrNilProto)
   578  	_, err = grpcSvr.EstimateGasForAction(context.Background(), &iotexapi.EstimateGasForActionRequest{Action: nil})
   579  	require.Contains(err.Error(), action.ErrNilProto.Error())
   580  }
   581  
   582  func TestGrpcServer_EstimateActionGasConsumption(t *testing.T) {
   583  	require := require.New(t)
   584  	ctrl := gomock.NewController(t)
   585  	defer ctrl.Finish()
   586  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   587  	grpcSvr := newGRPCHandler(core)
   588  	request := &iotexapi.EstimateActionGasConsumptionRequest{
   589  		CallerAddress: identityset.Address(0).String(),
   590  	}
   591  
   592  	t.Run("Execution is not nil", func(t *testing.T) {
   593  		core.EXPECT().EstimateExecutionGasConsumption(gomock.Any(), gomock.Any(), gomock.Any()).Return(uint64(10100), nil)
   594  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_Execution{
   595  			Execution: &iotextypes.Execution{
   596  				Data: _executionHash1[:],
   597  			},
   598  		}
   599  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   600  		require.NoError(err)
   601  		require.Equal(uint64(10100), res.Gas)
   602  	})
   603  
   604  	core.EXPECT().EstimateGasForNonExecution(gomock.Any()).Return(uint64(10100), nil).Times(10)
   605  
   606  	t.Run("Transfer is not nil", func(t *testing.T) {
   607  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_Transfer{
   608  			Transfer: &iotextypes.Transfer{
   609  				Amount:    "1000",
   610  				Recipient: identityset.Address(29).String(),
   611  				Payload:   []byte("1234567890"),
   612  			},
   613  		}
   614  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   615  		require.NoError(err)
   616  		require.Equal(uint64(10100), res.Gas)
   617  	})
   618  
   619  	t.Run("StakeCreate is not nil", func(t *testing.T) {
   620  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeCreate{
   621  			StakeCreate: &iotextypes.StakeCreate{
   622  				CandidateName:  "Candidate",
   623  				StakedAmount:   "1000",
   624  				StakedDuration: uint32(111),
   625  				Payload:        []byte("1234567890"),
   626  			},
   627  		}
   628  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   629  		require.NoError(err)
   630  		require.Equal(uint64(10100), res.Gas)
   631  	})
   632  
   633  	t.Run("StakeUnstake is not nil", func(t *testing.T) {
   634  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeUnstake{
   635  			StakeUnstake: &iotextypes.StakeReclaim{
   636  				BucketIndex: uint64(111),
   637  				Payload:     []byte("1234567890"),
   638  			},
   639  		}
   640  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   641  		require.NoError(err)
   642  		require.Equal(uint64(10100), res.Gas)
   643  	})
   644  
   645  	t.Run("StakeWithdraw is not nil", func(t *testing.T) {
   646  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeWithdraw{
   647  			StakeWithdraw: &iotextypes.StakeReclaim{
   648  				BucketIndex: uint64(222),
   649  				Payload:     []byte("abc1234567890"),
   650  			},
   651  		}
   652  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   653  		require.NoError(err)
   654  		require.Equal(uint64(10100), res.Gas)
   655  	})
   656  
   657  	t.Run("StakeAddDeposit is not nil", func(t *testing.T) {
   658  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeAddDeposit{
   659  			StakeAddDeposit: &iotextypes.StakeAddDeposit{
   660  				Amount:      "1000",
   661  				BucketIndex: uint64(333),
   662  				Payload:     []byte("abc1234567890"),
   663  			},
   664  		}
   665  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   666  		require.NoError(err)
   667  		require.Equal(uint64(10100), res.Gas)
   668  	})
   669  
   670  	t.Run("StakeRestake is not nil", func(t *testing.T) {
   671  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeRestake{
   672  			StakeRestake: &iotextypes.StakeRestake{
   673  				BucketIndex:    uint64(444),
   674  				StakedDuration: uint32(111),
   675  				Payload:        []byte("abc1234567890"),
   676  			},
   677  		}
   678  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   679  		require.NoError(err)
   680  		require.Equal(uint64(10100), res.Gas)
   681  	})
   682  
   683  	t.Run("StakeChangeCandidate is not nil", func(t *testing.T) {
   684  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeChangeCandidate{
   685  			StakeChangeCandidate: &iotextypes.StakeChangeCandidate{
   686  				CandidateName: "Candidate",
   687  				BucketIndex:   uint64(555),
   688  				Payload:       []byte("abc1234567890"),
   689  			},
   690  		}
   691  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   692  		require.NoError(err)
   693  		require.Equal(uint64(10100), res.Gas)
   694  	})
   695  
   696  	t.Run("StakeTransferOwnership is not nil", func(t *testing.T) {
   697  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeTransferOwnership{
   698  			StakeTransferOwnership: &iotextypes.StakeTransferOwnership{
   699  				BucketIndex:  uint64(666),
   700  				VoterAddress: identityset.Address(29).String(),
   701  				Payload:      []byte("1234567890"),
   702  			},
   703  		}
   704  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   705  		require.NoError(err)
   706  		require.Equal(uint64(10100), res.Gas)
   707  	})
   708  
   709  	t.Run("CandidateRegister is not nil", func(t *testing.T) {
   710  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_CandidateRegister{
   711  			CandidateRegister: &iotextypes.CandidateRegister{
   712  				Candidate: &iotextypes.CandidateBasicInfo{
   713  					Name:            "candidate",
   714  					OperatorAddress: identityset.Address(29).String(),
   715  					RewardAddress:   identityset.Address(28).String(),
   716  				},
   717  				StakedAmount:   "1000",
   718  				StakedDuration: uint32(111),
   719  				OwnerAddress:   identityset.Address(29).String(),
   720  				Payload:        []byte("abc1234567890"),
   721  			},
   722  		}
   723  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   724  		require.NoError(err)
   725  		require.Equal(uint64(10100), res.Gas)
   726  	})
   727  
   728  	t.Run("CandidateUpdate is not nil", func(t *testing.T) {
   729  		request.Action = &iotexapi.EstimateActionGasConsumptionRequest_CandidateUpdate{
   730  			CandidateUpdate: &iotextypes.CandidateBasicInfo{
   731  				Name:            "candidate",
   732  				OperatorAddress: identityset.Address(29).String(),
   733  				RewardAddress:   identityset.Address(28).String(),
   734  			},
   735  		}
   736  		res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request)
   737  		require.NoError(err)
   738  		require.Equal(uint64(10100), res.Gas)
   739  	})
   740  }
   741  
   742  func TestGrpcServer_ReadState(t *testing.T) {
   743  	require := require.New(t)
   744  	ctrl := gomock.NewController(t)
   745  	defer ctrl.Finish()
   746  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   747  	grpcSvr := newGRPCHandler(core)
   748  	core.EXPECT().ReadState(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&iotexapi.ReadStateResponse{
   749  		Data: []byte("10100"),
   750  	}, nil)
   751  	resp, err := grpcSvr.ReadState(context.Background(), &iotexapi.ReadStateRequest{
   752  		ProtocolID: []byte("rewarding"),
   753  		MethodName: []byte("UnclaimedBalance"),
   754  	})
   755  	require.NoError(err)
   756  	require.Equal([]byte("10100"), resp.Data)
   757  }
   758  
   759  func TestGrpcServer_GetEpochMeta(t *testing.T) {
   760  	require := require.New(t)
   761  	ctrl := gomock.NewController(t)
   762  	defer ctrl.Finish()
   763  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   764  	grpcSvr := newGRPCHandler(core)
   765  	epochData := &iotextypes.EpochData{Num: 7000}
   766  	blockProducersInfo := []*iotexapi.BlockProducerInfo{{Production: 8000}}
   767  	core.EXPECT().EpochMeta(gomock.Any()).Return(epochData, uint64(11), blockProducersInfo, nil)
   768  	resp, err := grpcSvr.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{
   769  		EpochNumber: uint64(11),
   770  	})
   771  	require.NoError(err)
   772  	require.Equal(epochData, resp.EpochData)
   773  	require.Equal(uint64(11), resp.TotalBlocks)
   774  	require.Equal(blockProducersInfo, resp.BlockProducersInfo)
   775  }
   776  
   777  func TestGrpcServer_GetRawBlocks(t *testing.T) {
   778  	require := require.New(t)
   779  	ctrl := gomock.NewController(t)
   780  	defer ctrl.Finish()
   781  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   782  	grpcSvr := newGRPCHandler(core)
   783  
   784  	blocks := []*iotexapi.BlockInfo{
   785  		{
   786  			Block: &iotextypes.Block{
   787  				Body: &iotextypes.BlockBody{
   788  					Actions: []*iotextypes.Action{
   789  						{
   790  							Core: &iotextypes.ActionCore{
   791  								Version:  1,
   792  								Nonce:    2,
   793  								GasLimit: 3,
   794  								GasPrice: "4",
   795  							},
   796  						},
   797  					},
   798  				},
   799  			},
   800  			Receipts: []*iotextypes.Receipt{
   801  				{
   802  					Status:          1,
   803  					BlkHeight:       1,
   804  					ActHash:         []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"),
   805  					GasConsumed:     1,
   806  					ContractAddress: "test",
   807  					Logs:            []*iotextypes.Log{},
   808  				},
   809  			},
   810  		},
   811  	}
   812  	core.EXPECT().RawBlocks(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(blocks, nil)
   813  	resp, err := grpcSvr.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{
   814  		StartHeight: 55,
   815  		Count:       1000,
   816  	})
   817  	require.NoError(err)
   818  	require.Equal(blocks, resp.Blocks)
   819  }
   820  
   821  func TestGrpcServer_GetLogs(t *testing.T) {
   822  	require := require.New(t)
   823  	ctrl := gomock.NewController(t)
   824  	defer ctrl.Finish()
   825  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   826  	grpcSvr := newGRPCHandler(core)
   827  	request := &iotexapi.GetLogsRequest{
   828  		Filter: &iotexapi.LogsFilter{
   829  			Address: []string{},
   830  			Topics:  []*iotexapi.Topics{},
   831  		},
   832  	}
   833  	logs := []*action.Log{
   834  		{
   835  			Address:     "_topic1",
   836  			BlockHeight: 1,
   837  			Topics: []hash.Hash256{
   838  				hash.Hash256b([]byte("_topic1")),
   839  				hash.Hash256b([]byte("_topic11")),
   840  			},
   841  		},
   842  		{
   843  			Address:     "_topic2",
   844  			BlockHeight: 2,
   845  			Topics: []hash.Hash256{
   846  				hash.Hash256b([]byte("_topic2")),
   847  				hash.Hash256b([]byte("_topic22")),
   848  			},
   849  		},
   850  	}
   851  
   852  	t.Run("by block", func(t *testing.T) {
   853  		core.EXPECT().LogsInBlockByHash(gomock.Any(), gomock.Any()).Return(logs, nil)
   854  		request.Lookup = &iotexapi.GetLogsRequest_ByBlock{
   855  			ByBlock: &iotexapi.GetLogsByBlock{
   856  				BlockHash: []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"),
   857  			},
   858  		}
   859  		res, err := grpcSvr.GetLogs(context.Background(), request)
   860  		require.NoError(err)
   861  		require.Len(res.Logs, 2)
   862  		blkHash := hash.BytesToHash256(request.GetByBlock().BlockHash)
   863  		require.Equal(blkHash[:], res.Logs[0].BlkHash)
   864  		require.Equal(logs[0].Address, res.Logs[0].ContractAddress)
   865  		require.Equal(logs[0].BlockHeight, res.Logs[0].BlkHeight)
   866  		require.Len(res.Logs[0].Topics, 2)
   867  		require.Equal(logs[0].Topics[0][:], res.Logs[0].Topics[0])
   868  		require.Equal(logs[0].Topics[1][:], res.Logs[0].Topics[1])
   869  		require.Equal(blkHash[:], res.Logs[1].BlkHash)
   870  		require.Equal(logs[1].Address, res.Logs[1].ContractAddress)
   871  		require.Equal(logs[1].BlockHeight, res.Logs[1].BlkHeight)
   872  		require.Len(res.Logs[1].Topics, 2)
   873  		require.Equal(logs[1].Topics[0][:], res.Logs[1].Topics[0])
   874  		require.Equal(logs[1].Topics[1][:], res.Logs[1].Topics[1])
   875  	})
   876  
   877  	t.Run("by range", func(t *testing.T) {
   878  		hashes := []hash.Hash256{
   879  			hash.BytesToHash256([]byte("02ae2a956d21e8d481c3a69e146633470cf625ec")),
   880  			hash.BytesToHash256([]byte("956d21e8d481c3a6901fc246633470cf62ae2ae1")),
   881  		}
   882  		core.EXPECT().LogsInRange(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(logs, hashes, nil)
   883  		request.Lookup = &iotexapi.GetLogsRequest_ByRange{
   884  			ByRange: &iotexapi.GetLogsByRange{
   885  				FromBlock: 1,
   886  				ToBlock:   100,
   887  			},
   888  		}
   889  		res, err := grpcSvr.GetLogs(context.Background(), request)
   890  		require.NoError(err)
   891  		require.Len(res.Logs, 2)
   892  		require.Equal(hashes[0][:], res.Logs[0].BlkHash)
   893  		require.Equal(logs[0].Address, res.Logs[0].ContractAddress)
   894  		require.Equal(logs[0].BlockHeight, res.Logs[0].BlkHeight)
   895  		require.Len(res.Logs[0].Topics, 2)
   896  		require.Equal(logs[0].Topics[0][:], res.Logs[0].Topics[0])
   897  		require.Equal(logs[0].Topics[1][:], res.Logs[0].Topics[1])
   898  		require.Equal(hashes[1][:], res.Logs[1].BlkHash)
   899  		require.Equal(logs[1].Address, res.Logs[1].ContractAddress)
   900  		require.Equal(logs[1].BlockHeight, res.Logs[1].BlkHeight)
   901  		require.Len(res.Logs[1].Topics, 2)
   902  		require.Equal(logs[1].Topics[0][:], res.Logs[1].Topics[0])
   903  		require.Equal(logs[1].Topics[1][:], res.Logs[1].Topics[1])
   904  	})
   905  }
   906  
   907  func TestGrpcServer_GetElectionBuckets(t *testing.T) {
   908  	require := require.New(t)
   909  	ctrl := gomock.NewController(t)
   910  	defer ctrl.Finish()
   911  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   912  	grpcSvr := newGRPCHandler(core)
   913  
   914  	buckets := []*iotextypes.ElectionBucket{
   915  		{
   916  			Voter:     []byte("_voter"),
   917  			Candidate: []byte("_candidate"),
   918  		},
   919  	}
   920  	core.EXPECT().ElectionBuckets(gomock.Any()).Return(buckets, nil)
   921  	resp, err := grpcSvr.GetElectionBuckets(context.Background(), &iotexapi.GetElectionBucketsRequest{
   922  		EpochNum: 11,
   923  	})
   924  	require.NoError(err)
   925  	require.Equal(buckets, resp.Buckets)
   926  }
   927  
   928  func TestGrpcServer_GetTransactionLogByActionHash(t *testing.T) {
   929  	require := require.New(t)
   930  	ctrl := gomock.NewController(t)
   931  	defer ctrl.Finish()
   932  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   933  	grpcSvr := newGRPCHandler(core)
   934  
   935  	txLog := &iotextypes.TransactionLog{
   936  		ActionHash:      []byte("_testAction"),
   937  		NumTransactions: 100,
   938  	}
   939  	core.EXPECT().TransactionLogByActionHash(gomock.Any()).Return(txLog, nil)
   940  	resp, err := grpcSvr.GetTransactionLogByActionHash(context.Background(), &iotexapi.GetTransactionLogByActionHashRequest{
   941  		ActionHash: "_actionHash",
   942  	})
   943  	require.NoError(err)
   944  	require.Equal(txLog, resp.TransactionLog)
   945  }
   946  
   947  func TestGrpcServer_GetTransactionLogByBlockHeight(t *testing.T) {
   948  	require := require.New(t)
   949  	ctrl := gomock.NewController(t)
   950  	defer ctrl.Finish()
   951  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   952  	grpcSvr := newGRPCHandler(core)
   953  
   954  	blockIdentifier := &iotextypes.BlockIdentifier{
   955  		Height: 10100,
   956  	}
   957  	txLog := &iotextypes.TransactionLogs{
   958  		Logs: []*iotextypes.TransactionLog{
   959  			{
   960  				ActionHash:      []byte("_testAction"),
   961  				NumTransactions: 100,
   962  			},
   963  		},
   964  	}
   965  	core.EXPECT().TransactionLogByBlockHeight(gomock.Any()).Return(blockIdentifier, txLog, nil)
   966  	resp, err := grpcSvr.GetTransactionLogByBlockHeight(context.Background(), &iotexapi.GetTransactionLogByBlockHeightRequest{
   967  		BlockHeight: 10101,
   968  	})
   969  	require.NoError(err)
   970  	require.Equal(blockIdentifier, resp.BlockIdentifier)
   971  	require.Equal(txLog, resp.TransactionLogs)
   972  }
   973  
   974  func TestGrpcServer_GetActPoolActions(t *testing.T) {
   975  	require := require.New(t)
   976  	ctrl := gomock.NewController(t)
   977  	defer ctrl.Finish()
   978  	core := mock_apicoreservice.NewMockCoreService(ctrl)
   979  	grpcSvr := newGRPCHandler(core)
   980  
   981  	addr1 := identityset.Address(28).String()
   982  	priKey1 := identityset.PrivateKey(29)
   983  	tsf1, err := action.SignedTransfer(addr1, priKey1, uint64(1), big.NewInt(10), []byte{}, uint64(100000), big.NewInt(0))
   984  	require.NoError(err)
   985  	tsf2, err := action.SignedTransfer(addr1, priKey1, uint64(2), big.NewInt(20), []byte{}, uint64(100000), big.NewInt(0))
   986  	require.NoError(err)
   987  	acts := []*action.SealedEnvelope{tsf1, tsf2}
   988  	core.EXPECT().ActionsInActPool(gomock.Any()).Return(acts, nil)
   989  	resp, err := grpcSvr.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{
   990  		ActionHashes: []string{"_actionHash"},
   991  	})
   992  	require.NoError(err)
   993  	require.Equal(len(acts), len(resp.Actions))
   994  	require.Equal(acts[0].Signature(), resp.Actions[0].Signature)
   995  	require.Equal(acts[1].Signature(), resp.Actions[1].Signature)
   996  	require.Equal(acts[0].SrcPubkey().Bytes(), resp.Actions[0].SenderPubKey)
   997  	require.Equal(acts[1].SrcPubkey().Bytes(), resp.Actions[1].SenderPubKey)
   998  }
   999  
  1000  func TestGrpcServer_ReadContractStorage(t *testing.T) {
  1001  	require := require.New(t)
  1002  	ctrl := gomock.NewController(t)
  1003  	defer ctrl.Finish()
  1004  	core := mock_apicoreservice.NewMockCoreService(ctrl)
  1005  	grpcSvr := newGRPCHandler(core)
  1006  
  1007  	core.EXPECT().ReadContractStorage(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte("_data"), nil)
  1008  	resp, err := grpcSvr.ReadContractStorage(context.Background(), &iotexapi.ReadContractStorageRequest{
  1009  		Contract: "io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2",
  1010  		Key:      []byte("_key"),
  1011  	})
  1012  	require.NoError(err)
  1013  	require.Equal([]byte("_data"), resp.Data)
  1014  }
  1015  
  1016  func TestGrpcServer_TraceTransactionStructLogs(t *testing.T) {
  1017  	require := require.New(t)
  1018  	ctrl := gomock.NewController(t)
  1019  	defer ctrl.Finish()
  1020  	core := mock_apicoreservice.NewMockCoreService(ctrl)
  1021  	grpcSvr := newGRPCHandler(core)
  1022  
  1023  	core.EXPECT().TraceTransaction(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil, logger.NewStructLogger(nil), nil)
  1024  	resp, err := grpcSvr.TraceTransactionStructLogs(context.Background(), &iotexapi.TraceTransactionStructLogsRequest{
  1025  		ActionHash: "_actionHash",
  1026  	})
  1027  	require.NoError(err)
  1028  	require.Equal(0, len(resp.StructLogs))
  1029  }
  1030  
  1031  func getAction() (act *iotextypes.Action) {
  1032  	pubKey1 := identityset.PrivateKey(28).PublicKey()
  1033  	addr2 := identityset.Address(29).String()
  1034  
  1035  	act = &iotextypes.Action{
  1036  		Core: &iotextypes.ActionCore{
  1037  			Action: &iotextypes.ActionCore_Transfer{
  1038  				Transfer: &iotextypes.Transfer{Recipient: addr2},
  1039  			},
  1040  			Version: version.ProtocolVersion,
  1041  			Nonce:   101,
  1042  		},
  1043  		SenderPubKey: pubKey1.Bytes(),
  1044  		Signature:    action.ValidSig,
  1045  	}
  1046  	return
  1047  }
  1048  
  1049  func getActionWithPayload() (act *iotextypes.Action) {
  1050  	pubKey1 := identityset.PrivateKey(28).PublicKey()
  1051  	addr2 := identityset.Address(29).String()
  1052  
  1053  	act = &iotextypes.Action{
  1054  		Core: &iotextypes.ActionCore{
  1055  			Action: &iotextypes.ActionCore_Transfer{
  1056  				Transfer: &iotextypes.Transfer{Recipient: addr2, Payload: []byte("1234567890")},
  1057  			},
  1058  			Version: version.ProtocolVersion,
  1059  			Nonce:   101,
  1060  		},
  1061  		SenderPubKey: pubKey1.Bytes(),
  1062  		Signature:    action.ValidSig,
  1063  	}
  1064  	return
  1065  }