github.com/iotexproject/iotex-core@v1.14.1-rc1/api/grpcserver_integrity_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  	"bytes"
    10  	"context"
    11  	"encoding/hex"
    12  	"math"
    13  	"math/big"
    14  	"regexp"
    15  	"strconv"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/golang/mock/gomock"
    20  	"github.com/iotexproject/go-pkgs/hash"
    21  	"github.com/iotexproject/iotex-address/address"
    22  	"github.com/iotexproject/iotex-election/test/mock/mock_committee"
    23  	"github.com/iotexproject/iotex-proto/golang/iotexapi"
    24  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    25  	"github.com/pkg/errors"
    26  	"github.com/stretchr/testify/require"
    27  	"google.golang.org/grpc/codes"
    28  	"google.golang.org/grpc/status"
    29  	"google.golang.org/protobuf/proto"
    30  	"google.golang.org/protobuf/types/known/timestamppb"
    31  
    32  	"github.com/iotexproject/iotex-core/action"
    33  	"github.com/iotexproject/iotex-core/action/protocol"
    34  	"github.com/iotexproject/iotex-core/action/protocol/poll"
    35  	"github.com/iotexproject/iotex-core/actpool"
    36  	"github.com/iotexproject/iotex-core/blockchain/block"
    37  	"github.com/iotexproject/iotex-core/blockchain/genesis"
    38  	"github.com/iotexproject/iotex-core/consensus"
    39  	"github.com/iotexproject/iotex-core/db"
    40  	"github.com/iotexproject/iotex-core/pkg/unit"
    41  	"github.com/iotexproject/iotex-core/pkg/version"
    42  	"github.com/iotexproject/iotex-core/state"
    43  	"github.com/iotexproject/iotex-core/test/identityset"
    44  	"github.com/iotexproject/iotex-core/test/mock/mock_blockchain"
    45  	"github.com/iotexproject/iotex-core/testutil"
    46  )
    47  
    48  const lld = "lifeLongDelegates"
    49  
    50  var (
    51  	_testTransfer, _ = action.SignedTransfer(identityset.Address(28).String(),
    52  		identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, testutil.TestGasLimit,
    53  		big.NewInt(testutil.TestGasPriceInt64))
    54  
    55  	_testTransferHash, _ = _testTransfer.Hash()
    56  	_testTransferPb      = _testTransfer.Proto()
    57  
    58  	_testExecution, _ = action.SignedExecution(identityset.Address(29).String(),
    59  		identityset.PrivateKey(29), 1, big.NewInt(0), testutil.TestGasLimit,
    60  		big.NewInt(testutil.TestGasPriceInt64), []byte{})
    61  
    62  	_testExecutionHash, _ = _testExecution.Hash()
    63  	_testExecutionPb      = _testExecution.Proto()
    64  
    65  	// invalid nounce
    66  	_testTransferInvalid1, _ = action.SignedTransfer(identityset.Address(28).String(),
    67  		identityset.PrivateKey(28), 2, big.NewInt(10), []byte{}, testutil.TestGasLimit,
    68  		big.NewInt(testutil.TestGasPriceInt64))
    69  	_testTransferInvalid1Pb = _testTransferInvalid1.Proto()
    70  
    71  	// invalid gas price
    72  	_testTransferInvalid2, _ = action.SignedTransfer(identityset.Address(28).String(),
    73  		identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, testutil.TestGasLimit,
    74  		big.NewInt(-1))
    75  	_testTransferInvalid2Pb = _testTransferInvalid2.Proto()
    76  
    77  	// invalid balance
    78  	_testTransferInvalid3, _ = action.SignedTransfer(identityset.Address(29).String(),
    79  		identityset.PrivateKey(29), 3, big.NewInt(29), []byte{}, testutil.TestGasLimit,
    80  		big.NewInt(testutil.TestGasPriceInt64))
    81  	_testTransferInvalid3Pb = _testTransferInvalid3.Proto()
    82  
    83  	// nonce is too high
    84  	_testTransferInvalid4, _ = action.SignedTransfer(identityset.Address(28).String(),
    85  		identityset.PrivateKey(28), actpool.DefaultConfig.MaxNumActsPerAcct+10, big.NewInt(1),
    86  		[]byte{}, uint64(100000), big.NewInt(0))
    87  	_testTransferInvalid4Pb = _testTransferInvalid4.Proto()
    88  
    89  	// replace act with lower gas
    90  	_testTransferInvalid5, _ = action.SignedTransfer(identityset.Address(28).String(),
    91  		identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, 10000,
    92  		big.NewInt(testutil.TestGasPriceInt64))
    93  	_testTransferInvalid5Pb = _testTransferInvalid5.Proto()
    94  
    95  	// gas is too low
    96  	_testTransferInvalid6, _ = action.SignedTransfer(identityset.Address(28).String(),
    97  		identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, 100,
    98  		big.NewInt(testutil.TestGasPriceInt64))
    99  	_testTransferInvalid6Pb = _testTransferInvalid6.Proto()
   100  
   101  	// negative transfer amout
   102  	_testTransferInvalid7, _ = action.SignedTransfer(identityset.Address(28).String(),
   103  		identityset.PrivateKey(28), 3, big.NewInt(-10), []byte{}, 10000,
   104  		big.NewInt(testutil.TestGasPriceInt64))
   105  	_testTransferInvalid7Pb = _testTransferInvalid7.Proto()
   106  
   107  	// gas is too large
   108  	_largeData               = make([]byte, 1e2)
   109  	_testTransferInvalid8, _ = action.SignedTransfer(identityset.Address(28).String(),
   110  		identityset.PrivateKey(28), 3, big.NewInt(10), _largeData, 10000,
   111  		big.NewInt(testutil.TestGasPriceInt64))
   112  	_testTransferInvalid8Pb = _testTransferInvalid8.Proto()
   113  )
   114  
   115  var (
   116  	_delegates = []genesis.Delegate{
   117  		{
   118  			OperatorAddrStr: identityset.Address(0).String(),
   119  			VotesStr:        "10",
   120  		},
   121  		{
   122  			OperatorAddrStr: identityset.Address(1).String(),
   123  			VotesStr:        "10",
   124  		},
   125  		{
   126  			OperatorAddrStr: identityset.Address(2).String(),
   127  			VotesStr:        "10",
   128  		},
   129  	}
   130  )
   131  
   132  var (
   133  	_getAccountTests = []struct {
   134  		in           string
   135  		address      string
   136  		balance      string
   137  		nonce        uint64
   138  		pendingNonce uint64
   139  		numActions   uint64
   140  	}{
   141  		{identityset.Address(30).String(),
   142  			"io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2",
   143  			"3",
   144  			0,
   145  			9,
   146  			9,
   147  		},
   148  		{
   149  			identityset.Address(27).String(),
   150  			"io1mflp9m6hcgm2qcghchsdqj3z3eccrnekx9p0ms",
   151  			"9999999999999999999999898950",
   152  			0,
   153  			6,
   154  			6,
   155  		},
   156  	}
   157  
   158  	_getActionsTests = []struct {
   159  		start      uint64
   160  		count      uint64
   161  		numActions int
   162  	}{
   163  		{
   164  			1,
   165  			11,
   166  			11,
   167  		},
   168  		{
   169  			11,
   170  			5,
   171  			4,
   172  		},
   173  		{
   174  			1,
   175  			0,
   176  			0,
   177  		},
   178  	}
   179  
   180  	_getActionTests = []struct {
   181  		// Arguments
   182  		checkPending bool
   183  		in           string
   184  		// Expected Values
   185  		nonce        uint64
   186  		senderPubKey string
   187  		blkNumber    uint64
   188  	}{
   189  		{
   190  			checkPending: false,
   191  			in:           hex.EncodeToString(_transferHash1[:]),
   192  			nonce:        1,
   193  			senderPubKey: _testTransfer1.SrcPubkey().HexString(),
   194  			blkNumber:    1,
   195  		},
   196  		{
   197  			checkPending: false,
   198  			in:           hex.EncodeToString(_transferHash2[:]),
   199  			nonce:        5,
   200  			senderPubKey: _testTransfer2.SrcPubkey().HexString(),
   201  			blkNumber:    2,
   202  		},
   203  		{
   204  			checkPending: false,
   205  			in:           hex.EncodeToString(_executionHash1[:]),
   206  			nonce:        6,
   207  			senderPubKey: _testExecution1.SrcPubkey().HexString(),
   208  			blkNumber:    2,
   209  		},
   210  	}
   211  
   212  	_getActionsByAddressTests = []struct {
   213  		address    string
   214  		start      uint64
   215  		count      uint64
   216  		numActions int
   217  	}{
   218  		{
   219  			identityset.Address(27).String(),
   220  			0,
   221  			3,
   222  			2,
   223  		},
   224  		{
   225  			identityset.Address(30).String(),
   226  			1,
   227  			8,
   228  			8,
   229  		},
   230  		{
   231  			identityset.Address(33).String(),
   232  			2,
   233  			1,
   234  			0,
   235  		},
   236  	}
   237  
   238  	_getUnconfirmedActionsByAddressTests = []struct {
   239  		address    string
   240  		start      uint64
   241  		count      uint64
   242  		numActions int
   243  	}{
   244  		{
   245  			identityset.Address(27).String(),
   246  			0,
   247  			4,
   248  			4,
   249  		},
   250  		{
   251  			identityset.Address(27).String(),
   252  			2,
   253  			0,
   254  			0,
   255  		},
   256  	}
   257  
   258  	_getActionsByBlockTests = []struct {
   259  		blkHeight  uint64
   260  		start      uint64
   261  		count      uint64
   262  		numActions int
   263  		firstTxGas string
   264  	}{
   265  		{
   266  			2,
   267  			0,
   268  			7,
   269  			7,
   270  			"0",
   271  		},
   272  		{
   273  			4,
   274  			2,
   275  			5,
   276  			3,
   277  			"0",
   278  		},
   279  		{
   280  			3,
   281  			0,
   282  			0,
   283  			0,
   284  			"",
   285  		},
   286  		{
   287  			1,
   288  			0,
   289  			math.MaxUint64,
   290  			2,
   291  			"0",
   292  		},
   293  	}
   294  
   295  	_getBlockMetasTests = []struct {
   296  		start, count      uint64
   297  		numBlks           int
   298  		gasLimit, gasUsed uint64
   299  	}{
   300  		{
   301  			1,
   302  			4,
   303  			4,
   304  			20000,
   305  			10000,
   306  		},
   307  		{
   308  			2,
   309  			5,
   310  			3,
   311  			120000,
   312  			60100,
   313  		},
   314  		{
   315  			1,
   316  			0,
   317  			0,
   318  			20000,
   319  			10000,
   320  		},
   321  		// genesis block
   322  		{
   323  			0,
   324  			1,
   325  			1,
   326  			0,
   327  			0,
   328  		},
   329  	}
   330  
   331  	_getBlockMetaTests = []struct {
   332  		blkHeight      uint64
   333  		numActions     int64
   334  		transferAmount string
   335  		logsBloom      string
   336  	}{
   337  		{
   338  			2,
   339  			7,
   340  			"6",
   341  			"",
   342  		},
   343  		{
   344  			4,
   345  			5,
   346  			"2",
   347  			"",
   348  		},
   349  	}
   350  
   351  	_getChainMetaTests = []struct {
   352  		// Arguments
   353  		emptyChain       bool
   354  		tpsWindow        int
   355  		pollProtocolType string
   356  		// Expected values
   357  		height     uint64
   358  		numActions int64
   359  		tps        int64
   360  		tpsFloat   float32
   361  		epoch      *iotextypes.EpochData
   362  	}{
   363  		{
   364  			emptyChain: true,
   365  		},
   366  
   367  		{
   368  			false,
   369  			1,
   370  			lld,
   371  			4,
   372  			15,
   373  			1,
   374  			5 / 10.0,
   375  			&iotextypes.EpochData{
   376  				Num:                     1,
   377  				Height:                  1,
   378  				GravityChainStartHeight: 1,
   379  			},
   380  		},
   381  		{
   382  			false,
   383  			5,
   384  			"governanceChainCommittee",
   385  			4,
   386  			15,
   387  			2,
   388  			15 / 13.0,
   389  			&iotextypes.EpochData{
   390  				Num:                     1,
   391  				Height:                  1,
   392  				GravityChainStartHeight: 100,
   393  			},
   394  		},
   395  	}
   396  
   397  	_sendActionTests = []struct {
   398  		// Arguments
   399  		actionPb *iotextypes.Action
   400  		// Expected Values
   401  		actionHash string
   402  	}{
   403  		{
   404  			_testTransferPb,
   405  			hex.EncodeToString(_testTransferHash[:]),
   406  		},
   407  		{
   408  			_testExecutionPb,
   409  			hex.EncodeToString(_testExecutionHash[:]),
   410  		},
   411  	}
   412  
   413  	_getReceiptByActionTests = []struct {
   414  		in        string
   415  		status    uint64
   416  		blkHeight uint64
   417  	}{
   418  		{
   419  			hex.EncodeToString(_transferHash1[:]),
   420  			uint64(iotextypes.ReceiptStatus_Success),
   421  			1,
   422  		},
   423  		{
   424  			hex.EncodeToString(_transferHash2[:]),
   425  			uint64(iotextypes.ReceiptStatus_Success),
   426  			2,
   427  		},
   428  		{
   429  			hex.EncodeToString(_executionHash1[:]),
   430  			uint64(iotextypes.ReceiptStatus_Success),
   431  			2,
   432  		},
   433  		{
   434  			hex.EncodeToString(_executionHash3[:]),
   435  			uint64(iotextypes.ReceiptStatus_Success),
   436  			4,
   437  		},
   438  	}
   439  
   440  	_readContractTests = []struct {
   441  		execHash    string
   442  		callerAddr  string
   443  		actionHash  string
   444  		retValue    string
   445  		gasConsumed uint64
   446  	}{
   447  		{
   448  			hex.EncodeToString(_executionHash1[:]),
   449  			"",
   450  			"08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4",
   451  			"",
   452  			10100,
   453  		},
   454  	}
   455  
   456  	_suggestGasPriceTests = []struct {
   457  		defaultGasPrice   uint64
   458  		suggestedGasPrice uint64
   459  	}{
   460  		{
   461  			1,
   462  			1,
   463  		},
   464  	}
   465  
   466  	_estimateGasForActionTests = []struct {
   467  		actionHash   string
   468  		estimatedGas uint64
   469  	}{
   470  		{
   471  			hex.EncodeToString(_transferHash1[:]),
   472  			10000,
   473  		},
   474  		{
   475  			hex.EncodeToString(_transferHash2[:]),
   476  			10000,
   477  		},
   478  	}
   479  
   480  	_readUnclaimedBalanceTests = []struct {
   481  		// Arguments
   482  		protocolID string
   483  		methodName string
   484  		addr       string
   485  		// Expected values
   486  		returnErr bool
   487  		balance   *big.Int
   488  	}{
   489  		{
   490  			protocolID: "rewarding",
   491  			methodName: "UnclaimedBalance",
   492  			addr:       identityset.Address(0).String(),
   493  			returnErr:  false,
   494  			balance:    unit.ConvertIotxToRau(64), // 4 block * 36 IOTX reward by default = 144 IOTX
   495  		},
   496  		{
   497  			protocolID: "rewarding",
   498  			methodName: "UnclaimedBalance",
   499  			addr:       identityset.Address(1).String(),
   500  			returnErr:  false,
   501  			balance:    unit.ConvertIotxToRau(0), // 4 block * 36 IOTX reward by default = 144 IOTX
   502  		},
   503  		{
   504  			protocolID: "Wrong ID",
   505  			methodName: "UnclaimedBalance",
   506  			addr:       identityset.Address(27).String(),
   507  			returnErr:  true,
   508  		},
   509  		{
   510  			protocolID: "rewarding",
   511  			methodName: "Wrong Method",
   512  			addr:       identityset.Address(27).String(),
   513  			returnErr:  true,
   514  		},
   515  	}
   516  
   517  	_readCandidatesByEpochTests = []struct {
   518  		// Arguments
   519  		protocolID   string
   520  		protocolType string
   521  		methodName   string
   522  		epoch        uint64
   523  		// Expected Values
   524  		numDelegates int
   525  	}{
   526  		{
   527  			protocolID:   "poll",
   528  			protocolType: lld,
   529  			methodName:   "CandidatesByEpoch",
   530  			epoch:        1,
   531  			numDelegates: 3,
   532  		},
   533  		{
   534  			protocolID:   "poll",
   535  			protocolType: "governanceChainCommittee",
   536  			methodName:   "CandidatesByEpoch",
   537  			epoch:        1,
   538  			numDelegates: 2,
   539  		},
   540  	}
   541  
   542  	_readBlockProducersByEpochTests = []struct {
   543  		// Arguments
   544  		protocolID            string
   545  		protocolType          string
   546  		methodName            string
   547  		epoch                 uint64
   548  		numCandidateDelegates uint64
   549  		// Expected Values
   550  		numBlockProducers int
   551  	}{
   552  		{
   553  			protocolID:        "poll",
   554  			protocolType:      lld,
   555  			methodName:        "BlockProducersByEpoch",
   556  			epoch:             1,
   557  			numBlockProducers: 3,
   558  		},
   559  		{
   560  			protocolID:            "poll",
   561  			protocolType:          "governanceChainCommittee",
   562  			methodName:            "BlockProducersByEpoch",
   563  			epoch:                 1,
   564  			numCandidateDelegates: 2,
   565  			numBlockProducers:     2,
   566  		},
   567  		{
   568  			protocolID:            "poll",
   569  			protocolType:          "governanceChainCommittee",
   570  			methodName:            "BlockProducersByEpoch",
   571  			epoch:                 1,
   572  			numCandidateDelegates: 1,
   573  			numBlockProducers:     1,
   574  		},
   575  	}
   576  
   577  	_readActiveBlockProducersByEpochTests = []struct {
   578  		// Arguments
   579  		protocolID   string
   580  		protocolType string
   581  		methodName   string
   582  		epoch        uint64
   583  		numDelegates uint64
   584  		// Expected Values
   585  		numActiveBlockProducers int
   586  	}{
   587  		{
   588  			protocolID:              "poll",
   589  			protocolType:            lld,
   590  			methodName:              "ActiveBlockProducersByEpoch",
   591  			epoch:                   1,
   592  			numActiveBlockProducers: 3,
   593  		},
   594  		{
   595  			protocolID:              "poll",
   596  			protocolType:            "governanceChainCommittee",
   597  			methodName:              "ActiveBlockProducersByEpoch",
   598  			epoch:                   1,
   599  			numDelegates:            2,
   600  			numActiveBlockProducers: 2,
   601  		},
   602  		{
   603  			protocolID:              "poll",
   604  			protocolType:            "governanceChainCommittee",
   605  			methodName:              "ActiveBlockProducersByEpoch",
   606  			epoch:                   1,
   607  			numDelegates:            1,
   608  			numActiveBlockProducers: 1,
   609  		},
   610  	}
   611  
   612  	_readRollDPoSMetaTests = []struct {
   613  		// Arguments
   614  		protocolID string
   615  		methodName string
   616  		height     uint64
   617  		// Expected Values
   618  		result uint64
   619  	}{
   620  		{
   621  			protocolID: "rolldpos",
   622  			methodName: "NumCandidateDelegates",
   623  			result:     36,
   624  		},
   625  		{
   626  			protocolID: "rolldpos",
   627  			methodName: "NumDelegates",
   628  			result:     24,
   629  		},
   630  	}
   631  
   632  	_readEpochCtxTests = []struct {
   633  		// Arguments
   634  		protocolID string
   635  		methodName string
   636  		argument   uint64
   637  		// Expected Values
   638  		result uint64
   639  	}{
   640  		{
   641  			protocolID: "rolldpos",
   642  			methodName: "NumSubEpochs",
   643  			argument:   1,
   644  			result:     2,
   645  		},
   646  		{
   647  			protocolID: "rolldpos",
   648  			methodName: "NumSubEpochs",
   649  			argument:   1816201,
   650  			result:     30,
   651  		},
   652  		{
   653  			protocolID: "rolldpos",
   654  			methodName: "EpochNumber",
   655  			argument:   100,
   656  			result:     3,
   657  		},
   658  		{
   659  			protocolID: "rolldpos",
   660  			methodName: "EpochHeight",
   661  			argument:   5,
   662  			result:     193,
   663  		},
   664  		{
   665  			protocolID: "rolldpos",
   666  			methodName: "EpochLastHeight",
   667  			argument:   1000,
   668  			result:     48000,
   669  		},
   670  		{
   671  			protocolID: "rolldpos",
   672  			methodName: "SubEpochNumber",
   673  			argument:   121,
   674  			result:     1,
   675  		},
   676  	}
   677  
   678  	_getEpochMetaTests = []struct {
   679  		// Arguments
   680  		EpochNumber      uint64
   681  		pollProtocolType string
   682  		// Expected Values
   683  		epochData                     *iotextypes.EpochData
   684  		numBlksInEpoch                int
   685  		numConsenusBlockProducers     int
   686  		numActiveCensusBlockProducers int
   687  	}{
   688  		{
   689  			1,
   690  			lld,
   691  			&iotextypes.EpochData{
   692  				Num:                     1,
   693  				Height:                  1,
   694  				GravityChainStartHeight: 1,
   695  			},
   696  			4,
   697  			24,
   698  			24,
   699  		},
   700  		{
   701  			1,
   702  			"governanceChainCommittee",
   703  			&iotextypes.EpochData{
   704  				Num:                     1,
   705  				Height:                  1,
   706  				GravityChainStartHeight: 100,
   707  			},
   708  			4,
   709  			6,
   710  			6,
   711  		},
   712  	}
   713  
   714  	_getRawBlocksTest = []struct {
   715  		// Arguments
   716  		startHeight  uint64
   717  		count        uint64
   718  		withReceipts bool
   719  		// Expected Values
   720  		numBlks     int
   721  		numActions  int
   722  		numReceipts int
   723  	}{
   724  		{
   725  			1,
   726  			1,
   727  			false,
   728  			1,
   729  			2,
   730  			0,
   731  		},
   732  		{
   733  			1,
   734  			2,
   735  			true,
   736  			2,
   737  			9,
   738  			9,
   739  		},
   740  		// genesis block
   741  		{
   742  			0,
   743  			1,
   744  			true,
   745  			1,
   746  			0,
   747  			0,
   748  		},
   749  	}
   750  
   751  	_getLogsByRangeTest = []struct {
   752  		// Arguments
   753  		address   []string
   754  		topics    []*iotexapi.Topics
   755  		fromBlock uint64
   756  		count     uint64
   757  		// Expected Values
   758  		numLogs int
   759  	}{
   760  		{
   761  			address:   []string{},
   762  			topics:    []*iotexapi.Topics{},
   763  			fromBlock: 1,
   764  			count:     100,
   765  			numLogs:   4,
   766  		},
   767  		{
   768  			address:   []string{},
   769  			topics:    []*iotexapi.Topics{},
   770  			fromBlock: 1,
   771  			count:     100,
   772  			numLogs:   4,
   773  		},
   774  	}
   775  
   776  	_getImplicitLogByBlockHeightTest = []struct {
   777  		height uint64
   778  		code   codes.Code
   779  	}{
   780  		{
   781  			1, codes.OK,
   782  		},
   783  		{
   784  			2, codes.OK,
   785  		},
   786  		{
   787  			3, codes.OK,
   788  		},
   789  		{
   790  			4, codes.OK,
   791  		},
   792  		{
   793  			5, codes.InvalidArgument,
   794  		},
   795  	}
   796  
   797  	_getActionByActionHashTest = []struct {
   798  		h              hash.Hash256
   799  		expectedNounce uint64
   800  	}{
   801  		{
   802  			_transferHash1,
   803  			1,
   804  		},
   805  		{
   806  			_transferHash2,
   807  			5,
   808  		},
   809  		{
   810  			_executionHash1,
   811  			6,
   812  		},
   813  		{
   814  			_executionHash3,
   815  			2,
   816  		},
   817  	}
   818  )
   819  
   820  func TestGrpcServer_GetAccountIntegrity(t *testing.T) {
   821  	require := require.New(t)
   822  	cfg := newConfig()
   823  	cfg.api.GRPCPort = testutil.RandomPort()
   824  	svr, bc, dao, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true)
   825  	require.NoError(err)
   826  	grpcHandler := newGRPCHandler(svr.core)
   827  	defer func() {
   828  		testutil.CleanupPath(bfIndexFile)
   829  	}()
   830  
   831  	// deploy a contract
   832  	contractCode := "6080604052348015600f57600080fd5b5060de8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008082409050807f2d93f7749862d33969fb261757410b48065a1bc86a56da5c47820bd063e2338260405160405180910390a28091505091905056fea265627a7a723158200a258cd08ea99ee11aa68c78b6d2bf7ea912615a1e64a81b90a2abca2dd59cfa64736f6c634300050c0032"
   833  	contract, err := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 1, bc.TipHeight(), contractCode)
   834  	require.NoError(err)
   835  	require.True(len(contract) > 0)
   836  
   837  	// read contract address
   838  	request := &iotexapi.GetAccountRequest{Address: contract}
   839  	res, err := grpcHandler.GetAccount(context.Background(), request)
   840  	require.NoError(err)
   841  	accountMeta := res.AccountMeta
   842  	require.Equal(contract, accountMeta.Address)
   843  	require.Equal("0", accountMeta.Balance)
   844  	require.EqualValues(0, accountMeta.Nonce)
   845  	require.EqualValues(1, accountMeta.PendingNonce)
   846  	require.EqualValues(0, accountMeta.NumActions)
   847  	require.True(accountMeta.IsContract)
   848  	require.True(len(accountMeta.ContractByteCode) > 0)
   849  	require.Contains(contractCode, hex.EncodeToString(accountMeta.ContractByteCode))
   850  
   851  	// success
   852  	for _, test := range _getAccountTests {
   853  		request := &iotexapi.GetAccountRequest{Address: test.in}
   854  		res, err := grpcHandler.GetAccount(context.Background(), request)
   855  		require.NoError(err)
   856  		accountMeta := res.AccountMeta
   857  		require.Equal(test.address, accountMeta.Address)
   858  		require.Equal(test.balance, accountMeta.Balance)
   859  		require.Equal(test.nonce, accountMeta.Nonce)
   860  		require.Equal(test.pendingNonce, accountMeta.PendingNonce)
   861  		require.Equal(test.numActions, accountMeta.NumActions)
   862  		require.EqualValues(5, res.BlockIdentifier.Height)
   863  		require.NotZero(res.BlockIdentifier.Hash)
   864  	}
   865  	// failure
   866  	_, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{})
   867  	require.Error(err)
   868  	// error account
   869  	_, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: "io3fn88lge6hyzmruh40cn6l3e49dfkqzqk3lgtq3"})
   870  	require.Error(err)
   871  
   872  	// success: reward pool
   873  	res, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: address.RewardingPoolAddr})
   874  	require.NoError(err)
   875  	require.Equal(address.RewardingPoolAddr, res.AccountMeta.Address)
   876  	require.Equal("200000000000000000000101000", res.AccountMeta.Balance)
   877  	require.EqualValues(5, res.BlockIdentifier.Height)
   878  	require.NotZero(res.BlockIdentifier.Hash)
   879  
   880  	//failure: protocol staking isn't registered
   881  	res, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: address.StakingBucketPoolAddr})
   882  	require.Contains(err.Error(), "protocol staking isn't registered")
   883  }
   884  
   885  func TestGrpcServer_GetActionsIntegrity(t *testing.T) {
   886  	require := require.New(t)
   887  	cfg := newConfig()
   888  	cfg.api.GRPCPort = testutil.RandomPort()
   889  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
   890  	require.NoError(err)
   891  	grpcHandler := newGRPCHandler(svr.core)
   892  	defer func() {
   893  		testutil.CleanupPath(bfIndexFile)
   894  	}()
   895  
   896  	for _, test := range _getActionsTests {
   897  		request := &iotexapi.GetActionsRequest{
   898  			Lookup: &iotexapi.GetActionsRequest_ByIndex{
   899  				ByIndex: &iotexapi.GetActionsByIndexRequest{
   900  					Start: test.start,
   901  					Count: test.count,
   902  				},
   903  			},
   904  		}
   905  
   906  		res, err := grpcHandler.GetActions(context.Background(), request)
   907  		if test.count == 0 {
   908  			require.Error(err)
   909  		} else {
   910  			require.NoError(err)
   911  			require.Equal(test.numActions, len(res.ActionInfo))
   912  		}
   913  
   914  		// TODO (huof6829): create a core service with hasActionIndex disabled to test
   915  	}
   916  
   917  	// failure: empty request
   918  	_, err = grpcHandler.GetActions(context.Background(), &iotexapi.GetActionsRequest{})
   919  	require.Error(err)
   920  
   921  	// failure: range exceed limit
   922  	_, err = grpcHandler.GetActions(context.Background(),
   923  		&iotexapi.GetActionsRequest{
   924  			Lookup: &iotexapi.GetActionsRequest_ByIndex{
   925  				ByIndex: &iotexapi.GetActionsByIndexRequest{
   926  					Start: 1,
   927  					Count: 100000,
   928  				},
   929  			},
   930  		})
   931  	require.Error(err)
   932  
   933  	// failure: start exceed limit
   934  	_, err = grpcHandler.GetActions(context.Background(),
   935  		&iotexapi.GetActionsRequest{
   936  			Lookup: &iotexapi.GetActionsRequest_ByIndex{
   937  				ByIndex: &iotexapi.GetActionsByIndexRequest{
   938  					Start: 100000,
   939  					Count: 1,
   940  				},
   941  			},
   942  		})
   943  	require.Error(err)
   944  }
   945  
   946  func TestGrpcServer_GetActionIntegrity(t *testing.T) {
   947  	require := require.New(t)
   948  	cfg := newConfig()
   949  	cfg.api.GRPCPort = testutil.RandomPort()
   950  	svr, _, dao, _, _, _, bfIndexFile, err := createServerV2(cfg, true)
   951  	require.NoError(err)
   952  	grpcHandler := newGRPCHandler(svr.core)
   953  	defer func() {
   954  		testutil.CleanupPath(bfIndexFile)
   955  	}()
   956  
   957  	for _, test := range _getActionTests {
   958  		request := &iotexapi.GetActionsRequest{
   959  			Lookup: &iotexapi.GetActionsRequest_ByHash{
   960  				ByHash: &iotexapi.GetActionByHashRequest{
   961  					ActionHash:   test.in,
   962  					CheckPending: test.checkPending,
   963  				},
   964  			},
   965  		}
   966  		res, err := grpcHandler.GetActions(context.Background(), request)
   967  		require.NoError(err)
   968  		require.Equal(1, len(res.ActionInfo))
   969  		act := res.ActionInfo[0]
   970  		require.Equal(test.nonce, act.Action.GetCore().GetNonce())
   971  		require.Equal(test.senderPubKey, hex.EncodeToString(act.Action.SenderPubKey))
   972  		if !test.checkPending {
   973  			blk, err := dao.GetBlockByHeight(test.blkNumber)
   974  			require.NoError(err)
   975  			timeStamp := blk.Header.Proto().GetCore().GetTimestamp()
   976  			_blkHash := blk.HashBlock()
   977  			require.Equal(hex.EncodeToString(_blkHash[:]), act.BlkHash)
   978  			require.Equal(test.blkNumber, act.BlkHeight)
   979  			require.Equal(timeStamp, act.Timestamp)
   980  		} else {
   981  			require.Equal(hex.EncodeToString(hash.ZeroHash256[:]), act.BlkHash)
   982  			require.Nil(act.Timestamp)
   983  			require.Equal(uint64(0), act.BlkHeight)
   984  		}
   985  	}
   986  
   987  	// failure: invalid hash
   988  	_, err = grpcHandler.GetActions(context.Background(),
   989  		&iotexapi.GetActionsRequest{
   990  			Lookup: &iotexapi.GetActionsRequest_ByHash{
   991  				ByHash: &iotexapi.GetActionByHashRequest{
   992  					ActionHash:   "0x58df1e9cb0572fea48e8ce9d9b787ae557c304657d01890f4fc5ea88a1f44c3e",
   993  					CheckPending: true,
   994  				},
   995  			},
   996  		})
   997  	require.Error(err)
   998  }
   999  
  1000  func TestGrpcServer_GetActionsByAddressIntegrity(t *testing.T) {
  1001  	require := require.New(t)
  1002  	cfg := newConfig()
  1003  	cfg.api.GRPCPort = testutil.RandomPort()
  1004  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1005  	require.NoError(err)
  1006  	grpcHandler := newGRPCHandler(svr.core)
  1007  	defer func() {
  1008  		testutil.CleanupPath(bfIndexFile)
  1009  	}()
  1010  
  1011  	for _, test := range _getActionsByAddressTests {
  1012  		request := &iotexapi.GetActionsRequest{
  1013  			Lookup: &iotexapi.GetActionsRequest_ByAddr{
  1014  				ByAddr: &iotexapi.GetActionsByAddressRequest{
  1015  					Address: test.address,
  1016  					Start:   test.start,
  1017  					Count:   test.count,
  1018  				},
  1019  			},
  1020  		}
  1021  		res, err := grpcHandler.GetActions(context.Background(), request)
  1022  		require.NoError(err)
  1023  		require.Equal(test.numActions, len(res.ActionInfo))
  1024  		if test.numActions == 0 {
  1025  			// returns empty response body in case of no result
  1026  			require.Equal(&iotexapi.GetActionsResponse{}, res)
  1027  		}
  1028  		var prevAct *iotexapi.ActionInfo
  1029  		for _, act := range res.ActionInfo {
  1030  			if prevAct != nil {
  1031  				require.True(act.Timestamp.GetSeconds() >= prevAct.Timestamp.GetSeconds())
  1032  			}
  1033  			prevAct = act
  1034  		}
  1035  		if test.start > 0 && len(res.ActionInfo) > 0 {
  1036  			request = &iotexapi.GetActionsRequest{
  1037  				Lookup: &iotexapi.GetActionsRequest_ByAddr{
  1038  					ByAddr: &iotexapi.GetActionsByAddressRequest{
  1039  						Address: test.address,
  1040  						Start:   0,
  1041  						Count:   test.start,
  1042  					},
  1043  				},
  1044  			}
  1045  			prevRes, err := grpcHandler.GetActions(context.Background(), request)
  1046  			require.NoError(err)
  1047  			require.True(prevRes.ActionInfo[len(prevRes.ActionInfo)-1].Timestamp.GetSeconds() <= res.ActionInfo[0].Timestamp.GetSeconds())
  1048  		}
  1049  	}
  1050  }
  1051  
  1052  func TestGrpcServer_GetUnconfirmedActionsByAddressIntegrity(t *testing.T) {
  1053  	require := require.New(t)
  1054  	cfg := newConfig()
  1055  	cfg.api.GRPCPort = testutil.RandomPort()
  1056  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true)
  1057  	require.NoError(err)
  1058  	grpcHandler := newGRPCHandler(svr.core)
  1059  	defer func() {
  1060  		testutil.CleanupPath(bfIndexFile)
  1061  	}()
  1062  
  1063  	for _, test := range _getUnconfirmedActionsByAddressTests {
  1064  		request := &iotexapi.GetActionsRequest{
  1065  			Lookup: &iotexapi.GetActionsRequest_UnconfirmedByAddr{
  1066  				UnconfirmedByAddr: &iotexapi.GetUnconfirmedActionsByAddressRequest{
  1067  					Address: test.address,
  1068  					Start:   test.start,
  1069  					Count:   test.count,
  1070  				},
  1071  			},
  1072  		}
  1073  		res, err := grpcHandler.GetActions(context.Background(), request)
  1074  		if test.count == 0 {
  1075  			require.Error(err)
  1076  			continue
  1077  		}
  1078  		require.NoError(err)
  1079  		require.Equal(test.numActions, len(res.ActionInfo))
  1080  		require.Equal(test.address, res.ActionInfo[0].Sender)
  1081  	}
  1082  }
  1083  
  1084  func TestGrpcServer_GetActionsByBlockIntegrity(t *testing.T) {
  1085  	require := require.New(t)
  1086  	cfg := newConfig()
  1087  	cfg.api.GRPCPort = testutil.RandomPort()
  1088  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1089  	require.NoError(err)
  1090  	grpcHandler := newGRPCHandler(svr.core)
  1091  	defer func() {
  1092  		testutil.CleanupPath(bfIndexFile)
  1093  	}()
  1094  
  1095  	for _, test := range _getActionsByBlockTests {
  1096  		request := &iotexapi.GetActionsRequest{
  1097  			Lookup: &iotexapi.GetActionsRequest_ByBlk{
  1098  				ByBlk: &iotexapi.GetActionsByBlockRequest{
  1099  					BlkHash: _blkHash[test.blkHeight],
  1100  					Start:   test.start,
  1101  					Count:   test.count,
  1102  				},
  1103  			},
  1104  		}
  1105  		res, err := grpcHandler.GetActions(context.Background(), request)
  1106  		if test.count == 0 {
  1107  			require.Error(err)
  1108  			continue
  1109  		}
  1110  		require.NoError(err)
  1111  		require.Equal(test.numActions, len(res.ActionInfo))
  1112  		if test.numActions > 0 {
  1113  			require.Equal(test.firstTxGas, res.ActionInfo[0].GasFee)
  1114  		}
  1115  		for _, v := range res.ActionInfo {
  1116  			require.Equal(test.blkHeight, v.BlkHeight)
  1117  			require.Equal(_blkHash[test.blkHeight], v.BlkHash)
  1118  		}
  1119  	}
  1120  }
  1121  
  1122  func TestGrpcServer_GetBlockMetasIntegrity(t *testing.T) {
  1123  	require := require.New(t)
  1124  	cfg := newConfig()
  1125  	cfg.api.GRPCPort = testutil.RandomPort()
  1126  	genesis.SetGenesisTimestamp(cfg.genesis.Timestamp)
  1127  	block.LoadGenesisHash(&cfg.genesis)
  1128  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1129  	require.NoError(err)
  1130  	grpcHandler := newGRPCHandler(svr.core)
  1131  	defer func() {
  1132  		testutil.CleanupPath(bfIndexFile)
  1133  	}()
  1134  
  1135  	for _, test := range _getBlockMetasTests {
  1136  		request := &iotexapi.GetBlockMetasRequest{
  1137  			Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
  1138  				ByIndex: &iotexapi.GetBlockMetasByIndexRequest{
  1139  					Start: test.start,
  1140  					Count: test.count,
  1141  				},
  1142  			},
  1143  		}
  1144  		res, err := grpcHandler.GetBlockMetas(context.Background(), request)
  1145  		if test.count == 0 {
  1146  			require.Error(err)
  1147  			continue
  1148  		}
  1149  		require.NoError(err)
  1150  		require.Equal(test.numBlks, len(res.BlkMetas))
  1151  		meta := res.BlkMetas[0]
  1152  		require.Equal(test.gasLimit, meta.GasLimit)
  1153  		require.Equal(test.gasUsed, meta.GasUsed)
  1154  		if test.start == 0 {
  1155  			// genesis block
  1156  			h := block.GenesisHash()
  1157  			require.Equal(meta.Hash, hex.EncodeToString(h[:]))
  1158  		}
  1159  		var prevBlkPb *iotextypes.BlockMeta
  1160  		for _, blkPb := range res.BlkMetas {
  1161  			if prevBlkPb != nil {
  1162  				require.True(blkPb.Height > prevBlkPb.Height)
  1163  			}
  1164  			prevBlkPb = blkPb
  1165  		}
  1166  	}
  1167  	// failure: empty request
  1168  	_, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{})
  1169  	require.Error(err)
  1170  
  1171  	_, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{
  1172  		Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
  1173  			ByIndex: &iotexapi.GetBlockMetasByIndexRequest{Start: 10, Count: 1},
  1174  		},
  1175  	})
  1176  	require.Error(err)
  1177  
  1178  	_, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{
  1179  		Lookup: &iotexapi.GetBlockMetasRequest_ByHash{
  1180  			ByHash: &iotexapi.GetBlockMetaByHashRequest{BlkHash: "0xa2e8e0c9cafbe93f2b7f7c9d32534bc6fde95f2185e5f2aaa6bf7ebdf1a6610a"},
  1181  		},
  1182  	})
  1183  	require.Error(err)
  1184  }
  1185  
  1186  func TestGrpcServer_GetBlockMetaIntegrity(t *testing.T) {
  1187  	require := require.New(t)
  1188  	cfg := newConfig()
  1189  	cfg.api.GRPCPort = testutil.RandomPort()
  1190  	svr, bc, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1191  	require.NoError(err)
  1192  	grpcHandler := newGRPCHandler(svr.core)
  1193  	defer func() {
  1194  		testutil.CleanupPath(bfIndexFile)
  1195  	}()
  1196  
  1197  	for _, test := range _getBlockMetaTests {
  1198  		header, err := bc.BlockHeaderByHeight(test.blkHeight)
  1199  		require.NoError(err)
  1200  		_blkHash := header.HashBlock()
  1201  		request := &iotexapi.GetBlockMetasRequest{
  1202  			Lookup: &iotexapi.GetBlockMetasRequest_ByHash{
  1203  				ByHash: &iotexapi.GetBlockMetaByHashRequest{
  1204  					BlkHash: hex.EncodeToString(_blkHash[:]),
  1205  				},
  1206  			},
  1207  		}
  1208  		res, err := grpcHandler.GetBlockMetas(context.Background(), request)
  1209  		require.NoError(err)
  1210  		require.Equal(1, len(res.BlkMetas))
  1211  		blkPb := res.BlkMetas[0]
  1212  		require.Equal(test.blkHeight, blkPb.Height)
  1213  		require.Equal(test.numActions, blkPb.NumActions)
  1214  		require.Equal(test.transferAmount, blkPb.TransferAmount)
  1215  		require.Equal(header.LogsBloomfilter(), nil)
  1216  		require.Equal(test.logsBloom, blkPb.LogsBloom)
  1217  	}
  1218  }
  1219  
  1220  func TestGrpcServer_GetChainMetaIntegrity(t *testing.T) {
  1221  	require := require.New(t)
  1222  	ctrl := gomock.NewController(t)
  1223  
  1224  	var pol poll.Protocol
  1225  	for _, test := range _getChainMetaTests {
  1226  		cfg := newConfig()
  1227  		if test.pollProtocolType == lld {
  1228  			pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates)
  1229  		} else if test.pollProtocolType == "governanceChainCommittee" {
  1230  			committee := mock_committee.NewMockCommittee(ctrl)
  1231  			slasher, _ := poll.NewSlasher(
  1232  				func(uint64, uint64) (map[string]uint64, error) {
  1233  					return nil, nil
  1234  				},
  1235  				nil,
  1236  				nil,
  1237  				nil,
  1238  				nil,
  1239  				cfg.genesis.NumCandidateDelegates,
  1240  				cfg.genesis.NumDelegates,
  1241  				cfg.genesis.DardanellesNumSubEpochs,
  1242  				cfg.genesis.ProductivityThreshold,
  1243  				cfg.genesis.ProbationEpochPeriod,
  1244  				cfg.genesis.UnproductiveDelegateMaxCacheSize,
  1245  				cfg.genesis.ProbationIntensityRate)
  1246  			pol, _ = poll.NewGovernanceChainCommitteeProtocol(
  1247  				nil,
  1248  				committee,
  1249  				uint64(123456),
  1250  				func(uint64) (time.Time, error) { return time.Now(), nil },
  1251  				cfg.chain.PollInitialCandidatesInterval,
  1252  				slasher)
  1253  			committee.EXPECT().HeightByTime(gomock.Any()).Return(test.epoch.GravityChainStartHeight, nil)
  1254  		}
  1255  
  1256  		cfg.api.GRPCPort = testutil.RandomPort()
  1257  		cfg.api.TpsWindow = test.tpsWindow
  1258  		svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false)
  1259  		require.NoError(err)
  1260  		grpcHandler := newGRPCHandler(svr.core)
  1261  		defer func() {
  1262  			testutil.CleanupPath(bfIndexFile)
  1263  		}()
  1264  		if pol != nil {
  1265  			require.NoError(pol.ForceRegister(registry))
  1266  		}
  1267  		if test.emptyChain {
  1268  			mbc := mock_blockchain.NewMockBlockchain(ctrl)
  1269  			mbc.EXPECT().TipHeight().Return(uint64(0)).Times(1)
  1270  			mbc.EXPECT().ChainID().Return(uint32(1)).Times(1)
  1271  			coreService, ok := svr.core.(*coreService)
  1272  			require.True(ok)
  1273  			// TODO: create a core service with empty chain to test
  1274  			coreService.bc = mbc
  1275  		}
  1276  		res, err := grpcHandler.GetChainMeta(context.Background(), &iotexapi.GetChainMetaRequest{})
  1277  		require.NoError(err)
  1278  		chainMetaPb := res.ChainMeta
  1279  		require.Equal(test.height, chainMetaPb.Height)
  1280  		require.Equal(test.numActions, chainMetaPb.NumActions)
  1281  		require.Equal(test.tps, chainMetaPb.Tps)
  1282  		if test.epoch != nil {
  1283  			require.Equal(test.epoch.Num, chainMetaPb.Epoch.Num)
  1284  			require.Equal(test.epoch.Height, chainMetaPb.Epoch.Height)
  1285  			require.Equal(test.epoch.GravityChainStartHeight, chainMetaPb.Epoch.GravityChainStartHeight)
  1286  		}
  1287  	}
  1288  }
  1289  
  1290  func TestGrpcServer_SendActionIntegrity(t *testing.T) {
  1291  	require := require.New(t)
  1292  	cfg := newConfig()
  1293  	cfg.api.GRPCPort = testutil.RandomPort()
  1294  	cfg.genesis.MidwayBlockHeight = 10
  1295  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true)
  1296  	require.NoError(err)
  1297  	grpcHandler := newGRPCHandler(svr.core)
  1298  	defer func() {
  1299  		testutil.CleanupPath(bfIndexFile)
  1300  	}()
  1301  
  1302  	coreService, ok := svr.core.(*coreService)
  1303  	require.True(ok)
  1304  	broadcastHandlerCount := 0
  1305  	coreService.broadcastHandler = func(_ context.Context, _ uint32, _ proto.Message) error {
  1306  		broadcastHandlerCount++
  1307  		return nil
  1308  	}
  1309  	coreService.messageBatcher = nil
  1310  
  1311  	for i, test := range _sendActionTests {
  1312  		request := &iotexapi.SendActionRequest{Action: test.actionPb}
  1313  		res, err := grpcHandler.SendAction(context.Background(), request)
  1314  		require.NoError(err)
  1315  		require.Equal(i+1, broadcastHandlerCount)
  1316  		require.Equal(test.actionHash, res.ActionHash)
  1317  	}
  1318  
  1319  	// 3 failure cases
  1320  	ctx := context.Background()
  1321  	tests := []struct {
  1322  		cfg    func() testConfig
  1323  		action *iotextypes.Action
  1324  		err    string
  1325  	}{
  1326  		{
  1327  			func() testConfig {
  1328  				return newConfig()
  1329  			},
  1330  			&iotextypes.Action{},
  1331  			"invalid signature length",
  1332  		},
  1333  		{
  1334  			func() testConfig {
  1335  				return newConfig()
  1336  			},
  1337  			&iotextypes.Action{
  1338  				Signature: action.ValidSig,
  1339  			},
  1340  			"empty action proto to load",
  1341  		},
  1342  		/* TODO: revise unit test
  1343  		{
  1344  			func() testConfig {
  1345  				cfg := newConfig()
  1346  				cfg.actPoll.MaxNumActsPerPool = 8
  1347  				return cfg
  1348  			},
  1349  			_testTransferPb,
  1350  			action.ErrTxPoolOverflow.Error(),
  1351  		},
  1352  		*/
  1353  		{
  1354  			func() testConfig {
  1355  				return newConfig()
  1356  			},
  1357  			_testTransferInvalid1Pb,
  1358  			action.ErrNonceTooLow.Error(),
  1359  		},
  1360  		{
  1361  			func() testConfig {
  1362  				return newConfig()
  1363  			},
  1364  			_testTransferInvalid2Pb,
  1365  			action.ErrUnderpriced.Error(),
  1366  		},
  1367  		{
  1368  			func() testConfig {
  1369  				return newConfig()
  1370  			},
  1371  			_testTransferInvalid3Pb,
  1372  			action.ErrInsufficientFunds.Error(),
  1373  		},
  1374  	}
  1375  
  1376  	for _, test := range tests {
  1377  		request := &iotexapi.SendActionRequest{Action: test.action}
  1378  		cfg := test.cfg()
  1379  		cfg.api.GRPCPort = testutil.RandomPort()
  1380  		svr, _, _, _, _, _, file, err := createServerV2(cfg, true)
  1381  		require.NoError(err)
  1382  		grpcHandler := newGRPCHandler(svr.core)
  1383  		defer func() {
  1384  			testutil.CleanupPath(file)
  1385  		}()
  1386  
  1387  		_, err = grpcHandler.SendAction(ctx, request)
  1388  		require.Contains(err.Error(), test.err)
  1389  	}
  1390  }
  1391  
  1392  func TestGrpcServer_StreamLogsIntegrity(t *testing.T) {
  1393  	require := require.New(t)
  1394  	cfg := newConfig()
  1395  	cfg.api.GRPCPort = testutil.RandomPort()
  1396  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true)
  1397  	require.NoError(err)
  1398  	grpcHandler := newGRPCHandler(svr.core)
  1399  	defer func() {
  1400  		testutil.CleanupPath(bfIndexFile)
  1401  	}()
  1402  
  1403  	err = grpcHandler.StreamLogs(&iotexapi.StreamLogsRequest{}, nil)
  1404  	require.Error(err)
  1405  }
  1406  
  1407  func TestGrpcServer_GetReceiptByActionIntegrity(t *testing.T) {
  1408  	require := require.New(t)
  1409  	cfg := newConfig()
  1410  	cfg.api.GRPCPort = testutil.RandomPort()
  1411  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1412  	require.NoError(err)
  1413  	grpcHandler := newGRPCHandler(svr.core)
  1414  	defer func() {
  1415  		testutil.CleanupPath(bfIndexFile)
  1416  	}()
  1417  
  1418  	for _, test := range _getReceiptByActionTests {
  1419  		request := &iotexapi.GetReceiptByActionRequest{ActionHash: test.in}
  1420  		res, err := grpcHandler.GetReceiptByAction(context.Background(), request)
  1421  		require.NoError(err)
  1422  		receiptPb := res.ReceiptInfo.Receipt
  1423  		require.Equal(test.status, receiptPb.Status)
  1424  		require.Equal(test.blkHeight, receiptPb.BlkHeight)
  1425  		require.NotEqual(hash.ZeroHash256, res.ReceiptInfo.BlkHash)
  1426  	}
  1427  
  1428  	// failure: empty request
  1429  	_, err = grpcHandler.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{ActionHash: "0x"})
  1430  	require.Error(err)
  1431  	// failure: wrong hash
  1432  	_, err = grpcHandler.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{ActionHash: "b7faffcb8b01fa9f32112155bcb93d714f599eab3178e577e88dafd2140bfc5a"})
  1433  	require.Error(err)
  1434  
  1435  }
  1436  
  1437  func TestGrpcServer_GetServerMetaIntegrity(t *testing.T) {
  1438  	require := require.New(t)
  1439  	cfg := newConfig()
  1440  	cfg.api.GRPCPort = testutil.RandomPort()
  1441  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1442  	require.NoError(err)
  1443  	grpcHandler := newGRPCHandler(svr.core)
  1444  	defer func() {
  1445  		testutil.CleanupPath(bfIndexFile)
  1446  	}()
  1447  
  1448  	resProto, err := grpcHandler.GetServerMeta(context.Background(), &iotexapi.GetServerMetaRequest{})
  1449  	res := resProto.GetServerMeta()
  1450  	require.Equal(res.BuildTime, version.BuildTime)
  1451  	require.Equal(res.GoVersion, version.GoVersion)
  1452  	require.Equal(res.GitStatus, version.GitStatus)
  1453  	require.Equal(res.PackageCommitID, version.PackageCommitID)
  1454  	require.Equal(res.PackageVersion, version.PackageVersion)
  1455  }
  1456  
  1457  func TestGrpcServer_ReadContractIntegrity(t *testing.T) {
  1458  	require := require.New(t)
  1459  	cfg := newConfig()
  1460  	cfg.api.GRPCPort = testutil.RandomPort()
  1461  	svr, _, dao, indexer, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1462  	require.NoError(err)
  1463  	grpcHandler := newGRPCHandler(svr.core)
  1464  	defer func() {
  1465  		testutil.CleanupPath(bfIndexFile)
  1466  	}()
  1467  
  1468  	for _, test := range _readContractTests {
  1469  		hash, err := hash.HexStringToHash256(test.execHash)
  1470  		require.NoError(err)
  1471  		ai, err := indexer.GetActionIndex(hash[:])
  1472  		require.NoError(err)
  1473  		blk, err := dao.GetBlockByHeight(ai.BlockHeight())
  1474  		require.NoError(err)
  1475  		exec, _, err := blk.ActionByHash(hash)
  1476  		require.NoError(err)
  1477  		request := &iotexapi.ReadContractRequest{
  1478  			Execution:     exec.Proto().GetCore().GetExecution(),
  1479  			CallerAddress: test.callerAddr,
  1480  			GasLimit:      exec.GasLimit(),
  1481  			GasPrice:      big.NewInt(unit.Qev).String(),
  1482  		}
  1483  
  1484  		res, err := grpcHandler.ReadContract(context.Background(), request)
  1485  		require.NoError(err)
  1486  		require.Equal(test.retValue, res.Data)
  1487  		require.EqualValues(1, res.Receipt.Status)
  1488  		require.Equal(test.actionHash, hex.EncodeToString(res.Receipt.ActHash))
  1489  		require.Equal(test.gasConsumed, res.Receipt.GasConsumed)
  1490  	}
  1491  }
  1492  
  1493  func TestGrpcServer_SuggestGasPriceIntegrity(t *testing.T) {
  1494  	require := require.New(t)
  1495  	cfg := newConfig()
  1496  	cfg.api.GRPCPort = testutil.RandomPort()
  1497  	for _, test := range _suggestGasPriceTests {
  1498  		cfg.api.GasStation.DefaultGas = test.defaultGasPrice
  1499  		svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1500  		require.NoError(err)
  1501  		grpcHandler := newGRPCHandler(svr.core)
  1502  		defer func() {
  1503  			testutil.CleanupPath(bfIndexFile)
  1504  		}()
  1505  		res, err := grpcHandler.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{})
  1506  		require.NoError(err)
  1507  		require.Equal(test.suggestedGasPrice, res.GasPrice)
  1508  	}
  1509  }
  1510  
  1511  func TestGrpcServer_EstimateGasForActionIntegrity(t *testing.T) {
  1512  	require := require.New(t)
  1513  	cfg := newConfig()
  1514  	cfg.api.GRPCPort = testutil.RandomPort()
  1515  	svr, _, dao, indexer, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1516  	require.NoError(err)
  1517  	grpcHandler := newGRPCHandler(svr.core)
  1518  	defer func() {
  1519  		testutil.CleanupPath(bfIndexFile)
  1520  	}()
  1521  
  1522  	for _, test := range _estimateGasForActionTests {
  1523  		hash, err := hash.HexStringToHash256(test.actionHash)
  1524  		require.NoError(err)
  1525  		ai, err := indexer.GetActionIndex(hash[:])
  1526  		require.NoError(err)
  1527  		blk, err := dao.GetBlockByHeight(ai.BlockHeight())
  1528  		require.NoError(err)
  1529  		act, _, err := blk.ActionByHash(hash)
  1530  		require.NoError(err)
  1531  		request := &iotexapi.EstimateGasForActionRequest{Action: act.Proto()}
  1532  
  1533  		res, err := grpcHandler.EstimateGasForAction(context.Background(), request)
  1534  		require.NoError(err)
  1535  		require.Equal(test.estimatedGas, res.Gas)
  1536  	}
  1537  }
  1538  
  1539  func TestGrpcServer_EstimateActionGasConsumptionIntegrity(t *testing.T) {
  1540  	require := require.New(t)
  1541  	cfg := newConfig()
  1542  	cfg.api.GRPCPort = testutil.RandomPort()
  1543  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1544  	require.NoError(err)
  1545  	grpcHandler := newGRPCHandler(svr.core)
  1546  	defer func() {
  1547  		testutil.CleanupPath(bfIndexFile)
  1548  	}()
  1549  
  1550  	// test for contract deploy
  1551  	data := "608060405234801561001057600080fd5b50610123600102600281600019169055503373ffffffffffffffffffffffffffffffffffffffff166001026003816000191690555060035460025417600481600019169055506102ae806100656000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630cc0e1fb1461007d57806328f371aa146100b05780636b1d752b146100df578063d4b8399214610112578063daea85c514610145578063eb6fd96a14610188575b600080fd5b34801561008957600080fd5b506100926101bb565b60405180826000191660001916815260200191505060405180910390f35b3480156100bc57600080fd5b506100c56101c1565b604051808215151515815260200191505060405180910390f35b3480156100eb57600080fd5b506100f46101d7565b60405180826000191660001916815260200191505060405180910390f35b34801561011e57600080fd5b506101276101dd565b60405180826000191660001916815260200191505060405180910390f35b34801561015157600080fd5b50610186600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101e3565b005b34801561019457600080fd5b5061019d61027c565b60405180826000191660001916815260200191505060405180910390f35b60035481565b6000600454600019166001546000191614905090565b60025481565b60045481565b3373ffffffffffffffffffffffffffffffffffffffff166001028173ffffffffffffffffffffffffffffffffffffffff16600102176001816000191690555060016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600154815600a165627a7a7230582089b5f99476d642b66a213c12cd198207b2e813bb1caf3bd75e22be535ebf5d130029"
  1552  	byteCodes, err := hex.DecodeString(data)
  1553  	require.NoError(err)
  1554  	execution, err := action.NewExecution("", 1, big.NewInt(0), 0, big.NewInt(0), byteCodes)
  1555  	require.NoError(err)
  1556  	request := &iotexapi.EstimateActionGasConsumptionRequest{
  1557  		Action: &iotexapi.EstimateActionGasConsumptionRequest_Execution{
  1558  			Execution: execution.Proto(),
  1559  		},
  1560  		CallerAddress: identityset.Address(0).String(),
  1561  	}
  1562  	res, err := grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1563  	require.NoError(err)
  1564  	require.Equal(uint64(286579), res.Gas)
  1565  
  1566  	// test for transfer
  1567  	tran, err := action.NewTransfer(0, big.NewInt(0), "", []byte("123"), 0, big.NewInt(0))
  1568  	require.NoError(err)
  1569  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1570  		Action: &iotexapi.EstimateActionGasConsumptionRequest_Transfer{
  1571  			Transfer: tran.Proto(),
  1572  		},
  1573  		CallerAddress: identityset.Address(0).String(),
  1574  	}
  1575  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1576  	require.NoError(err)
  1577  	require.Equal(uint64(10300), res.Gas)
  1578  
  1579  	var (
  1580  		gaslimit   = uint64(1000000)
  1581  		gasprice   = big.NewInt(10)
  1582  		canAddress = "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza"
  1583  		payload    = []byte("123")
  1584  		amount     = big.NewInt(10)
  1585  		nonce      = uint64(0)
  1586  		duration   = uint32(1000)
  1587  		autoStake  = true
  1588  		index      = uint64(10)
  1589  	)
  1590  
  1591  	// staking related
  1592  	// case I: test for StakeCreate
  1593  	cs, err := action.NewCreateStake(nonce, canAddress, amount.String(), duration, autoStake, payload, gaslimit, gasprice)
  1594  	require.NoError(err)
  1595  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1596  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeCreate{
  1597  			StakeCreate: cs.Proto(),
  1598  		},
  1599  		CallerAddress: identityset.Address(0).String(),
  1600  	}
  1601  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1602  	require.NoError(err)
  1603  	require.Equal(uint64(10300), res.Gas)
  1604  
  1605  	// case II: test for StakeUnstake
  1606  	us, err := action.NewUnstake(nonce, index, payload, gaslimit, gasprice)
  1607  	require.NoError(err)
  1608  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1609  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeUnstake{
  1610  			StakeUnstake: us.Proto(),
  1611  		},
  1612  		CallerAddress: identityset.Address(0).String(),
  1613  	}
  1614  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1615  	require.NoError(err)
  1616  	require.Equal(uint64(10300), res.Gas)
  1617  
  1618  	// case III: test for StakeWithdraw
  1619  	ws, err := action.NewWithdrawStake(nonce, index, payload, gaslimit, gasprice)
  1620  	require.NoError(err)
  1621  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1622  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeWithdraw{
  1623  			StakeWithdraw: ws.Proto(),
  1624  		},
  1625  		CallerAddress: identityset.Address(0).String(),
  1626  	}
  1627  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1628  	require.NoError(err)
  1629  	require.Equal(uint64(10300), res.Gas)
  1630  
  1631  	// Case IV: test for StakeDeposit
  1632  	ds, err := action.NewDepositToStake(nonce, 1, amount.String(), payload, gaslimit, gasprice)
  1633  	require.NoError(err)
  1634  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1635  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeAddDeposit{
  1636  			StakeAddDeposit: ds.Proto(),
  1637  		},
  1638  		CallerAddress: identityset.Address(0).String(),
  1639  	}
  1640  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1641  	require.NoError(err)
  1642  	require.Equal(uint64(10300), res.Gas)
  1643  
  1644  	// Case V: test for StakeChangeCandidate
  1645  	cc, err := action.NewChangeCandidate(nonce, canAddress, index, payload, gaslimit, gasprice)
  1646  	require.NoError(err)
  1647  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1648  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeChangeCandidate{
  1649  			StakeChangeCandidate: cc.Proto(),
  1650  		},
  1651  		CallerAddress: identityset.Address(0).String(),
  1652  	}
  1653  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1654  	require.NoError(err)
  1655  	require.Equal(uint64(10300), res.Gas)
  1656  
  1657  	// Case VI: test for StakeRestake
  1658  	rs, err := action.NewRestake(nonce, index, duration, autoStake, payload, gaslimit, gasprice)
  1659  	require.NoError(err)
  1660  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1661  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeRestake{
  1662  			StakeRestake: rs.Proto(),
  1663  		},
  1664  		CallerAddress: identityset.Address(0).String(),
  1665  	}
  1666  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1667  	require.NoError(err)
  1668  	require.Equal(uint64(10300), res.Gas)
  1669  
  1670  	// Case VII: test for StakeTransfer
  1671  	ts, err := action.NewTransferStake(nonce, canAddress, index, payload, gaslimit, gasprice)
  1672  	require.NoError(err)
  1673  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1674  		Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeTransferOwnership{
  1675  			StakeTransferOwnership: ts.Proto(),
  1676  		},
  1677  		CallerAddress: identityset.Address(0).String(),
  1678  	}
  1679  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1680  	require.NoError(err)
  1681  	require.Equal(uint64(10300), res.Gas)
  1682  
  1683  	// Case VIII: test for CandidateRegister
  1684  	cr, err := action.NewCandidateRegister(nonce, canAddress, canAddress, canAddress, canAddress, amount.String(), duration, autoStake, payload, gaslimit, gasprice)
  1685  	require.NoError(err)
  1686  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1687  		Action: &iotexapi.EstimateActionGasConsumptionRequest_CandidateRegister{
  1688  			CandidateRegister: cr.Proto(),
  1689  		},
  1690  		CallerAddress: identityset.Address(0).String(),
  1691  	}
  1692  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1693  	require.NoError(err)
  1694  	require.Equal(uint64(10300), res.Gas)
  1695  
  1696  	// Case IX: test for CandidateUpdate
  1697  	cu, err := action.NewCandidateUpdate(nonce, canAddress, canAddress, canAddress, gaslimit, gasprice)
  1698  	require.NoError(err)
  1699  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1700  		Action: &iotexapi.EstimateActionGasConsumptionRequest_CandidateUpdate{
  1701  			CandidateUpdate: cu.Proto(),
  1702  		},
  1703  		CallerAddress: identityset.Address(0).String(),
  1704  	}
  1705  	res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1706  	require.NoError(err)
  1707  	require.Equal(uint64(10000), res.Gas)
  1708  
  1709  	// Case X: test for action nil
  1710  	request = &iotexapi.EstimateActionGasConsumptionRequest{
  1711  		Action:        nil,
  1712  		CallerAddress: identityset.Address(0).String(),
  1713  	}
  1714  	_, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  1715  	require.Error(err)
  1716  }
  1717  
  1718  func TestGrpcServer_ReadUnclaimedBalanceIntegrity(t *testing.T) {
  1719  	require := require.New(t)
  1720  	cfg := newConfig()
  1721  	cfg.api.GRPCPort = testutil.RandomPort()
  1722  	cfg.consensus.Scheme = consensus.RollDPoSScheme
  1723  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1724  	require.NoError(err)
  1725  	grpcHandler := newGRPCHandler(svr.core)
  1726  	defer func() {
  1727  		testutil.CleanupPath(bfIndexFile)
  1728  	}()
  1729  
  1730  	for _, test := range _readUnclaimedBalanceTests {
  1731  		out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  1732  			ProtocolID: []byte(test.protocolID),
  1733  			MethodName: []byte(test.methodName),
  1734  			Arguments:  [][]byte{[]byte(test.addr)},
  1735  		})
  1736  		if test.returnErr {
  1737  			require.Error(err)
  1738  			continue
  1739  		}
  1740  		require.NoError(err)
  1741  		val, ok := new(big.Int).SetString(string(out.Data), 10)
  1742  		require.True(ok)
  1743  		require.Equal(test.balance, val)
  1744  	}
  1745  }
  1746  
  1747  func TestGrpcServer_TotalBalanceIntegrity(t *testing.T) {
  1748  	require := require.New(t)
  1749  	cfg := newConfig()
  1750  	cfg.api.GRPCPort = testutil.RandomPort()
  1751  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1752  	require.NoError(err)
  1753  	grpcHandler := newGRPCHandler(svr.core)
  1754  	defer func() {
  1755  		testutil.CleanupPath(bfIndexFile)
  1756  	}()
  1757  
  1758  	out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  1759  		ProtocolID: []byte("rewarding"),
  1760  		MethodName: []byte("TotalBalance"),
  1761  		Arguments:  nil,
  1762  	})
  1763  	require.NoError(err)
  1764  	val, ok := new(big.Int).SetString(string(out.Data), 10)
  1765  	require.True(ok)
  1766  	require.Equal(unit.ConvertIotxToRau(200000000), val)
  1767  }
  1768  
  1769  func TestGrpcServer_AvailableBalanceIntegrity(t *testing.T) {
  1770  	require := require.New(t)
  1771  	cfg := newConfig()
  1772  	cfg.consensus.Scheme = consensus.RollDPoSScheme
  1773  	cfg.api.GRPCPort = testutil.RandomPort()
  1774  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  1775  	require.NoError(err)
  1776  	grpcHandler := newGRPCHandler(svr.core)
  1777  	defer func() {
  1778  		testutil.CleanupPath(bfIndexFile)
  1779  	}()
  1780  
  1781  	out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  1782  		ProtocolID: []byte("rewarding"),
  1783  		MethodName: []byte("AvailableBalance"),
  1784  		Arguments:  nil,
  1785  	})
  1786  	require.NoError(err)
  1787  	val, ok := new(big.Int).SetString(string(out.Data), 10)
  1788  	require.True(ok)
  1789  	require.Equal(unit.ConvertIotxToRau(199999936), val)
  1790  }
  1791  
  1792  func TestGrpcServer_ReadCandidatesByEpochIntegrity(t *testing.T) {
  1793  	require := require.New(t)
  1794  	cfg := newConfig()
  1795  	cfg.api.GRPCPort = testutil.RandomPort()
  1796  
  1797  	ctrl := gomock.NewController(t)
  1798  	committee := mock_committee.NewMockCommittee(ctrl)
  1799  	candidates := []*state.Candidate{
  1800  		{
  1801  			Address:       "address1",
  1802  			Votes:         big.NewInt(1),
  1803  			RewardAddress: "rewardAddress",
  1804  		},
  1805  		{
  1806  			Address:       "address2",
  1807  			Votes:         big.NewInt(1),
  1808  			RewardAddress: "rewardAddress",
  1809  		},
  1810  	}
  1811  
  1812  	for _, test := range _readCandidatesByEpochTests {
  1813  		var pol poll.Protocol
  1814  		if test.protocolType == lld {
  1815  			cfg.genesis.Delegates = _delegates
  1816  			pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates)
  1817  		} else {
  1818  			indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore())
  1819  			require.NoError(err)
  1820  			slasher, _ := poll.NewSlasher(
  1821  				func(uint64, uint64) (map[string]uint64, error) {
  1822  					return nil, nil
  1823  				},
  1824  				func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) {
  1825  					return candidates, 0, nil
  1826  				},
  1827  				nil,
  1828  				nil,
  1829  				indexer,
  1830  				cfg.genesis.NumCandidateDelegates,
  1831  				cfg.genesis.NumDelegates,
  1832  				cfg.genesis.DardanellesNumSubEpochs,
  1833  				cfg.genesis.ProductivityThreshold,
  1834  				cfg.genesis.ProbationEpochPeriod,
  1835  				cfg.genesis.UnproductiveDelegateMaxCacheSize,
  1836  				cfg.genesis.ProbationIntensityRate)
  1837  			pol, _ = poll.NewGovernanceChainCommitteeProtocol(
  1838  				indexer,
  1839  				committee,
  1840  				uint64(123456),
  1841  				func(uint64) (time.Time, error) { return time.Now(), nil },
  1842  				cfg.chain.PollInitialCandidatesInterval,
  1843  				slasher)
  1844  		}
  1845  		svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false)
  1846  		require.NoError(err)
  1847  		grpcHandler := newGRPCHandler(svr.core)
  1848  		defer func() {
  1849  			testutil.CleanupPath(bfIndexFile)
  1850  		}()
  1851  		require.NoError(pol.ForceRegister(registry))
  1852  
  1853  		res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  1854  			ProtocolID: []byte(test.protocolID),
  1855  			MethodName: []byte(test.methodName),
  1856  			Arguments:  [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))},
  1857  		})
  1858  		require.NoError(err)
  1859  		var _delegates state.CandidateList
  1860  		require.NoError(_delegates.Deserialize(res.Data))
  1861  		require.Equal(test.numDelegates, len(_delegates))
  1862  	}
  1863  }
  1864  
  1865  func TestGrpcServer_ReadBlockProducersByEpochIntegrity(t *testing.T) {
  1866  	require := require.New(t)
  1867  	cfg := newConfig()
  1868  	cfg.api.GRPCPort = testutil.RandomPort()
  1869  
  1870  	ctrl := gomock.NewController(t)
  1871  	committee := mock_committee.NewMockCommittee(ctrl)
  1872  	candidates := []*state.Candidate{
  1873  		{
  1874  			Address:       "address1",
  1875  			Votes:         big.NewInt(1),
  1876  			RewardAddress: "rewardAddress",
  1877  		},
  1878  		{
  1879  			Address:       "address2",
  1880  			Votes:         big.NewInt(1),
  1881  			RewardAddress: "rewardAddress",
  1882  		},
  1883  	}
  1884  
  1885  	for _, test := range _readBlockProducersByEpochTests {
  1886  		var pol poll.Protocol
  1887  		if test.protocolType == lld {
  1888  			cfg.genesis.Delegates = _delegates
  1889  			pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates)
  1890  		} else {
  1891  			indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore())
  1892  			require.NoError(err)
  1893  			slasher, _ := poll.NewSlasher(
  1894  				func(uint64, uint64) (map[string]uint64, error) {
  1895  					return nil, nil
  1896  				},
  1897  				func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) {
  1898  					return candidates, 0, nil
  1899  				},
  1900  				nil,
  1901  				nil,
  1902  				indexer,
  1903  				test.numCandidateDelegates,
  1904  				cfg.genesis.NumDelegates,
  1905  				cfg.genesis.DardanellesNumSubEpochs,
  1906  				cfg.genesis.ProductivityThreshold,
  1907  				cfg.genesis.ProbationEpochPeriod,
  1908  				cfg.genesis.UnproductiveDelegateMaxCacheSize,
  1909  				cfg.genesis.ProbationIntensityRate)
  1910  
  1911  			pol, _ = poll.NewGovernanceChainCommitteeProtocol(
  1912  				indexer,
  1913  				committee,
  1914  				uint64(123456),
  1915  				func(uint64) (time.Time, error) { return time.Now(), nil },
  1916  				cfg.chain.PollInitialCandidatesInterval,
  1917  				slasher)
  1918  		}
  1919  		svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false)
  1920  		require.NoError(err)
  1921  		grpcHandler := newGRPCHandler(svr.core)
  1922  		defer func() {
  1923  			testutil.CleanupPath(bfIndexFile)
  1924  		}()
  1925  		require.NoError(pol.ForceRegister(registry))
  1926  		res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  1927  			ProtocolID: []byte(test.protocolID),
  1928  			MethodName: []byte(test.methodName),
  1929  			Arguments:  [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))},
  1930  		})
  1931  		require.NoError(err)
  1932  		var blockProducers state.CandidateList
  1933  		require.NoError(blockProducers.Deserialize(res.Data))
  1934  		require.Equal(test.numBlockProducers, len(blockProducers))
  1935  	}
  1936  }
  1937  
  1938  func TestGrpcServer_ReadActiveBlockProducersByEpochIntegrity(t *testing.T) {
  1939  	require := require.New(t)
  1940  	cfg := newConfig()
  1941  	cfg.api.GRPCPort = testutil.RandomPort()
  1942  
  1943  	ctrl := gomock.NewController(t)
  1944  	committee := mock_committee.NewMockCommittee(ctrl)
  1945  	candidates := []*state.Candidate{
  1946  		{
  1947  			Address:       "address1",
  1948  			Votes:         big.NewInt(1),
  1949  			RewardAddress: "rewardAddress",
  1950  		},
  1951  		{
  1952  			Address:       "address2",
  1953  			Votes:         big.NewInt(1),
  1954  			RewardAddress: "rewardAddress",
  1955  		},
  1956  	}
  1957  
  1958  	for _, test := range _readActiveBlockProducersByEpochTests {
  1959  		var pol poll.Protocol
  1960  		if test.protocolType == lld {
  1961  			cfg.genesis.Delegates = _delegates
  1962  			pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates)
  1963  		} else {
  1964  			indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore())
  1965  			require.NoError(err)
  1966  			slasher, _ := poll.NewSlasher(
  1967  				func(uint64, uint64) (map[string]uint64, error) {
  1968  					return nil, nil
  1969  				},
  1970  				func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) {
  1971  					return candidates, 0, nil
  1972  				},
  1973  				nil,
  1974  				nil,
  1975  				indexer,
  1976  				cfg.genesis.NumCandidateDelegates,
  1977  				test.numDelegates,
  1978  				cfg.genesis.DardanellesNumSubEpochs,
  1979  				cfg.genesis.ProductivityThreshold,
  1980  				cfg.genesis.ProbationEpochPeriod,
  1981  				cfg.genesis.UnproductiveDelegateMaxCacheSize,
  1982  				cfg.genesis.ProbationIntensityRate)
  1983  			pol, _ = poll.NewGovernanceChainCommitteeProtocol(
  1984  				indexer,
  1985  				committee,
  1986  				uint64(123456),
  1987  				func(uint64) (time.Time, error) { return time.Now(), nil },
  1988  				cfg.chain.PollInitialCandidatesInterval,
  1989  				slasher)
  1990  		}
  1991  		svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false)
  1992  		require.NoError(err)
  1993  		grpcHandler := newGRPCHandler(svr.core)
  1994  		defer func() {
  1995  			testutil.CleanupPath(bfIndexFile)
  1996  		}()
  1997  		require.NoError(pol.ForceRegister(registry))
  1998  
  1999  		res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  2000  			ProtocolID: []byte(test.protocolID),
  2001  			MethodName: []byte(test.methodName),
  2002  			Arguments:  [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))},
  2003  		})
  2004  		require.NoError(err)
  2005  		var activeBlockProducers state.CandidateList
  2006  		require.NoError(activeBlockProducers.Deserialize(res.Data))
  2007  		require.Equal(test.numActiveBlockProducers, len(activeBlockProducers))
  2008  	}
  2009  }
  2010  
  2011  func TestGrpcServer_ReadRollDPoSMetaIntegrity(t *testing.T) {
  2012  	require := require.New(t)
  2013  	cfg := newConfig()
  2014  	cfg.api.GRPCPort = testutil.RandomPort()
  2015  	for _, test := range _readRollDPoSMetaTests {
  2016  		svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2017  		require.NoError(err)
  2018  		grpcHandler := newGRPCHandler(svr.core)
  2019  		defer func() {
  2020  			testutil.CleanupPath(bfIndexFile)
  2021  		}()
  2022  		res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  2023  			ProtocolID: []byte(test.protocolID),
  2024  			MethodName: []byte(test.methodName),
  2025  		})
  2026  		require.NoError(err)
  2027  		result, err := strconv.ParseUint(string(res.Data), 10, 64)
  2028  		require.NoError(err)
  2029  		require.Equal(test.result, result)
  2030  	}
  2031  }
  2032  
  2033  func TestGrpcServer_ReadEpochCtxIntegrity(t *testing.T) {
  2034  	require := require.New(t)
  2035  	cfg := newConfig()
  2036  	cfg.api.GRPCPort = testutil.RandomPort()
  2037  	for _, test := range _readEpochCtxTests {
  2038  		svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2039  		require.NoError(err)
  2040  		grpcHandler := newGRPCHandler(svr.core)
  2041  		defer func() {
  2042  			testutil.CleanupPath(bfIndexFile)
  2043  		}()
  2044  		res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{
  2045  			ProtocolID: []byte(test.protocolID),
  2046  			MethodName: []byte(test.methodName),
  2047  			Arguments:  [][]byte{[]byte(strconv.FormatUint(test.argument, 10))},
  2048  		})
  2049  		require.NoError(err)
  2050  		result, err := strconv.ParseUint(string(res.Data), 10, 64)
  2051  		require.NoError(err)
  2052  		require.Equal(test.result, result)
  2053  	}
  2054  }
  2055  
  2056  func TestGrpcServer_GetEpochMetaIntegrity(t *testing.T) {
  2057  	require := require.New(t)
  2058  	ctrl := gomock.NewController(t)
  2059  	cfg := newConfig()
  2060  	cfg.api.GRPCPort = testutil.RandomPort()
  2061  	svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false)
  2062  	require.NoError(err)
  2063  	grpcHandler := newGRPCHandler(svr.core)
  2064  	defer func() {
  2065  		testutil.CleanupPath(bfIndexFile)
  2066  	}()
  2067  	for _, test := range _getEpochMetaTests {
  2068  		if test.pollProtocolType == lld {
  2069  			pol := poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates)
  2070  			require.NoError(pol.ForceRegister(registry))
  2071  		} else if test.pollProtocolType == "governanceChainCommittee" {
  2072  			committee := mock_committee.NewMockCommittee(ctrl)
  2073  			mbc := mock_blockchain.NewMockBlockchain(ctrl)
  2074  			mbc.EXPECT().Genesis().Return(cfg.genesis).Times(3)
  2075  			indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore())
  2076  			require.NoError(err)
  2077  			slasher, _ := poll.NewSlasher(
  2078  				func(uint64, uint64) (map[string]uint64, error) {
  2079  					return nil, nil
  2080  				},
  2081  				func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) {
  2082  					return []*state.Candidate{
  2083  						{
  2084  							Address:       identityset.Address(1).String(),
  2085  							Votes:         big.NewInt(6),
  2086  							RewardAddress: "rewardAddress",
  2087  						},
  2088  						{
  2089  							Address:       identityset.Address(2).String(),
  2090  							Votes:         big.NewInt(5),
  2091  							RewardAddress: "rewardAddress",
  2092  						},
  2093  						{
  2094  							Address:       identityset.Address(3).String(),
  2095  							Votes:         big.NewInt(4),
  2096  							RewardAddress: "rewardAddress",
  2097  						},
  2098  						{
  2099  							Address:       identityset.Address(4).String(),
  2100  							Votes:         big.NewInt(3),
  2101  							RewardAddress: "rewardAddress",
  2102  						},
  2103  						{
  2104  							Address:       identityset.Address(5).String(),
  2105  							Votes:         big.NewInt(2),
  2106  							RewardAddress: "rewardAddress",
  2107  						},
  2108  						{
  2109  							Address:       identityset.Address(6).String(),
  2110  							Votes:         big.NewInt(1),
  2111  							RewardAddress: "rewardAddress",
  2112  						},
  2113  					}, 0, nil
  2114  				},
  2115  				nil,
  2116  				nil,
  2117  				indexer,
  2118  				cfg.genesis.NumCandidateDelegates,
  2119  				cfg.genesis.NumDelegates,
  2120  				cfg.genesis.DardanellesNumSubEpochs,
  2121  				cfg.genesis.ProductivityThreshold,
  2122  				cfg.genesis.ProbationEpochPeriod,
  2123  				cfg.genesis.UnproductiveDelegateMaxCacheSize,
  2124  				cfg.genesis.ProbationIntensityRate)
  2125  			pol, _ := poll.NewGovernanceChainCommitteeProtocol(
  2126  				indexer,
  2127  				committee,
  2128  				uint64(123456),
  2129  				func(uint64) (time.Time, error) { return time.Now(), nil },
  2130  				cfg.chain.PollInitialCandidatesInterval,
  2131  				slasher)
  2132  			require.NoError(pol.ForceRegister(registry))
  2133  			committee.EXPECT().HeightByTime(gomock.Any()).Return(test.epochData.GravityChainStartHeight, nil)
  2134  
  2135  			mbc.EXPECT().TipHeight().Return(uint64(4)).Times(4)
  2136  			mbc.EXPECT().BlockHeaderByHeight(gomock.Any()).DoAndReturn(func(height uint64) (*block.Header, error) {
  2137  				if height > 0 && height <= 4 {
  2138  					pk := identityset.PrivateKey(int(height))
  2139  					blk, err := block.NewBuilder(
  2140  						block.NewRunnableActionsBuilder().Build(),
  2141  					).
  2142  						SetHeight(height).
  2143  						SetTimestamp(time.Time{}).
  2144  						SignAndBuild(pk)
  2145  					if err != nil {
  2146  						return &block.Header{}, err
  2147  					}
  2148  					return &blk.Header, nil
  2149  				}
  2150  				return &block.Header{}, errors.Errorf("invalid block height %d", height)
  2151  			}).AnyTimes()
  2152  			coreService, ok := svr.core.(*coreService)
  2153  			require.True(ok)
  2154  			// TODO: create a core service to test
  2155  			coreService.bc = mbc
  2156  		}
  2157  
  2158  		coreService, ok := svr.core.(*coreService)
  2159  		require.True(ok)
  2160  		coreService.readCache.Clear()
  2161  		res, err := grpcHandler.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{EpochNumber: test.EpochNumber})
  2162  		require.NoError(err)
  2163  		require.Equal(test.epochData.Num, res.EpochData.Num)
  2164  		require.Equal(test.epochData.Height, res.EpochData.Height)
  2165  		require.Equal(test.epochData.GravityChainStartHeight, res.EpochData.GravityChainStartHeight)
  2166  		require.Equal(test.numBlksInEpoch, int(res.TotalBlocks))
  2167  		require.Equal(test.numConsenusBlockProducers, len(res.BlockProducersInfo))
  2168  		var numActiveBlockProducers int
  2169  		var prevInfo *iotexapi.BlockProducerInfo
  2170  		for _, bp := range res.BlockProducersInfo {
  2171  			if bp.Active {
  2172  				numActiveBlockProducers++
  2173  			}
  2174  			if prevInfo != nil {
  2175  				prevVotes, _ := strconv.Atoi(prevInfo.Votes)
  2176  				currVotes, _ := strconv.Atoi(bp.Votes)
  2177  				require.True(prevVotes >= currVotes)
  2178  			}
  2179  			prevInfo = bp
  2180  		}
  2181  		require.Equal(test.numActiveCensusBlockProducers, numActiveBlockProducers)
  2182  	}
  2183  
  2184  	// failure: epoch number
  2185  	_, err = grpcHandler.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{EpochNumber: 0})
  2186  	require.Error(err)
  2187  }
  2188  
  2189  func TestGrpcServer_GetRawBlocksIntegrity(t *testing.T) {
  2190  	require := require.New(t)
  2191  	cfg := newConfig()
  2192  	cfg.api.GRPCPort = testutil.RandomPort()
  2193  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2194  	require.NoError(err)
  2195  	grpcHandler := newGRPCHandler(svr.core)
  2196  	defer func() {
  2197  		testutil.CleanupPath(bfIndexFile)
  2198  	}()
  2199  
  2200  	for _, test := range _getRawBlocksTest {
  2201  		request := &iotexapi.GetRawBlocksRequest{
  2202  			StartHeight:  test.startHeight,
  2203  			Count:        test.count,
  2204  			WithReceipts: test.withReceipts,
  2205  		}
  2206  		res, err := grpcHandler.GetRawBlocks(context.Background(), request)
  2207  		require.NoError(err)
  2208  		blkInfos := res.Blocks
  2209  		require.Equal(test.numBlks, len(blkInfos))
  2210  		if test.startHeight == 0 {
  2211  			// verify genesis block
  2212  			header := blkInfos[0].Block.Header.Core
  2213  			require.EqualValues(version.ProtocolVersion, header.Version)
  2214  			require.Zero(header.Height)
  2215  			ts := timestamppb.New(time.Unix(genesis.Timestamp(), 0))
  2216  			require.Equal(ts, header.Timestamp)
  2217  			require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.PrevBlockHash))
  2218  			require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.TxRoot))
  2219  			require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.DeltaStateDigest))
  2220  			require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.ReceiptRoot))
  2221  		}
  2222  		var numActions, numReceipts int
  2223  		for _, blkInfo := range blkInfos {
  2224  			numActions += len(blkInfo.Block.Body.Actions)
  2225  			numReceipts += len(blkInfo.Receipts)
  2226  		}
  2227  		require.Equal(test.numActions, numActions)
  2228  		require.Equal(test.numReceipts, numReceipts)
  2229  	}
  2230  
  2231  	// failure: invalid count
  2232  	_, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{
  2233  		StartHeight:  1,
  2234  		Count:        0,
  2235  		WithReceipts: true,
  2236  	})
  2237  	require.Error(err)
  2238  
  2239  	// failure: invalid startHeight
  2240  	_, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{
  2241  		StartHeight:  1000000,
  2242  		Count:        10,
  2243  		WithReceipts: true,
  2244  	})
  2245  	require.Error(err)
  2246  
  2247  	// failure: invalid endHeight
  2248  	_, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{
  2249  		StartHeight:  3,
  2250  		Count:        1000,
  2251  		WithReceipts: true,
  2252  	})
  2253  	require.Error(err)
  2254  
  2255  }
  2256  
  2257  func TestGrpcServer_GetLogsIntegrity(t *testing.T) {
  2258  	require := require.New(t)
  2259  	cfg := newConfig()
  2260  	cfg.api.GRPCPort = testutil.RandomPort()
  2261  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2262  	require.NoError(err)
  2263  	grpcHandler := newGRPCHandler(svr.core)
  2264  	defer func() {
  2265  		testutil.CleanupPath(bfIndexFile)
  2266  	}()
  2267  
  2268  	for _, test := range _getLogsByRangeTest {
  2269  		request := &iotexapi.GetLogsRequest{
  2270  			Filter: &iotexapi.LogsFilter{
  2271  				Address: test.address,
  2272  				Topics:  test.topics,
  2273  			},
  2274  			Lookup: &iotexapi.GetLogsRequest_ByRange{
  2275  				ByRange: &iotexapi.GetLogsByRange{
  2276  					FromBlock: test.fromBlock,
  2277  					ToBlock:   test.fromBlock + test.count - 1,
  2278  				},
  2279  			},
  2280  		}
  2281  		res, err := grpcHandler.GetLogs(context.Background(), request)
  2282  		require.NoError(err)
  2283  		logs := res.Logs
  2284  		require.Equal(test.numLogs, len(logs))
  2285  	}
  2286  
  2287  	for _, v := range _blkHash {
  2288  		h, _ := hash.HexStringToHash256(v)
  2289  		request := &iotexapi.GetLogsRequest{
  2290  			Filter: &iotexapi.LogsFilter{
  2291  				Address: []string{},
  2292  				Topics:  []*iotexapi.Topics{},
  2293  			},
  2294  			Lookup: &iotexapi.GetLogsRequest_ByBlock{
  2295  				ByBlock: &iotexapi.GetLogsByBlock{
  2296  					BlockHash: h[:],
  2297  				},
  2298  			},
  2299  		}
  2300  		res, err := grpcHandler.GetLogs(context.Background(), request)
  2301  		require.NoError(err)
  2302  		logs := res.Logs
  2303  		require.Equal(1, len(logs))
  2304  	}
  2305  
  2306  	// failure: empty request
  2307  	_, err = grpcHandler.GetLogs(context.Background(), &iotexapi.GetLogsRequest{
  2308  		Filter: &iotexapi.LogsFilter{},
  2309  	})
  2310  	require.Error(err)
  2311  
  2312  	// failure: empty filter
  2313  	_, err = grpcHandler.GetLogs(context.Background(), &iotexapi.GetLogsRequest{})
  2314  	require.Error(err)
  2315  }
  2316  
  2317  func TestGrpcServer_GetElectionBucketsIntegrity(t *testing.T) {
  2318  	require := require.New(t)
  2319  	cfg := newConfig()
  2320  	cfg.api.GRPCPort = testutil.RandomPort()
  2321  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2322  	require.NoError(err)
  2323  	grpcHandler := newGRPCHandler(svr.core)
  2324  	defer func() {
  2325  		testutil.CleanupPath(bfIndexFile)
  2326  	}()
  2327  
  2328  	// failure: no native election
  2329  	request := &iotexapi.GetElectionBucketsRequest{
  2330  		EpochNum: 0,
  2331  	}
  2332  	_, err = grpcHandler.GetElectionBuckets(context.Background(), request)
  2333  	require.Error(err)
  2334  }
  2335  
  2336  func TestGrpcServer_GetActionByActionHashIntegrity(t *testing.T) {
  2337  	require := require.New(t)
  2338  	cfg := newConfig()
  2339  	cfg.api.GRPCPort = testutil.RandomPort()
  2340  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2341  	require.NoError(err)
  2342  	defer func() {
  2343  		testutil.CleanupPath(bfIndexFile)
  2344  	}()
  2345  
  2346  	for _, test := range _getActionByActionHashTest {
  2347  		ret, _, _, err := svr.core.ActionByActionHash(test.h)
  2348  		require.NoError(err)
  2349  		require.Equal(test.expectedNounce, ret.Envelope.Nonce())
  2350  	}
  2351  }
  2352  
  2353  func TestGrpcServer_GetTransactionLogByActionHashIntegrity(t *testing.T) {
  2354  	require := require.New(t)
  2355  	cfg := newConfig()
  2356  	cfg.api.GRPCPort = testutil.RandomPort()
  2357  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2358  	require.NoError(err)
  2359  	grpcHandler := newGRPCHandler(svr.core)
  2360  	defer func() {
  2361  		testutil.CleanupPath(bfIndexFile)
  2362  	}()
  2363  
  2364  	request := &iotexapi.GetTransactionLogByActionHashRequest{
  2365  		ActionHash: hex.EncodeToString(hash.ZeroHash256[:]),
  2366  	}
  2367  	_, err = grpcHandler.GetTransactionLogByActionHash(context.Background(), request)
  2368  	require.Error(err)
  2369  	sta, ok := status.FromError(err)
  2370  	require.Equal(true, ok)
  2371  	require.Equal(codes.NotFound, sta.Code())
  2372  
  2373  	for h, log := range _implicitLogs {
  2374  		request.ActionHash = hex.EncodeToString(h[:])
  2375  		res, err := grpcHandler.GetTransactionLogByActionHash(context.Background(), request)
  2376  		require.NoError(err)
  2377  		require.Equal(log.Proto(), res.TransactionLog)
  2378  	}
  2379  
  2380  	// TODO (huof6829): Re-enable this test
  2381  	/*
  2382  		// check implicit transfer receiver balance
  2383  		state, err := accountutil.LoadAccount(svr.core.StateFactory(), identityset.Address(31))
  2384  		require.NoError(err)
  2385  		require.Equal(big.NewInt(5), state.Balance)
  2386  	*/
  2387  }
  2388  
  2389  func TestGrpcServer_GetEvmTransfersByBlockHeightIntegrity(t *testing.T) {
  2390  	require := require.New(t)
  2391  	cfg := newConfig()
  2392  	cfg.api.GRPCPort = testutil.RandomPort()
  2393  	svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false)
  2394  	require.NoError(err)
  2395  	grpcHandler := newGRPCHandler(svr.core)
  2396  	defer func() {
  2397  		testutil.CleanupPath(bfIndexFile)
  2398  	}()
  2399  
  2400  	request := &iotexapi.GetTransactionLogByBlockHeightRequest{}
  2401  	for _, test := range _getImplicitLogByBlockHeightTest {
  2402  		request.BlockHeight = test.height
  2403  		res, err := grpcHandler.GetTransactionLogByBlockHeight(context.Background(), request)
  2404  		if test.code != codes.OK {
  2405  			require.Error(err)
  2406  			sta, ok := status.FromError(err)
  2407  			require.Equal(true, ok)
  2408  			require.Equal(test.code, sta.Code())
  2409  		} else {
  2410  			require.NotNil(res)
  2411  			// verify log
  2412  			for _, log := range res.TransactionLogs.Logs {
  2413  				l, ok := _implicitLogs[hash.BytesToHash256(log.ActionHash)]
  2414  				require.True(ok)
  2415  				require.Equal(l.Proto(), log)
  2416  			}
  2417  			require.Equal(test.height, res.BlockIdentifier.Height)
  2418  			require.Equal(_blkHash[test.height], res.BlockIdentifier.Hash)
  2419  		}
  2420  	}
  2421  }
  2422  
  2423  func TestGrpcServer_GetActPoolActionsIntegrity(t *testing.T) {
  2424  	require := require.New(t)
  2425  	cfg := newConfig()
  2426  	cfg.api.GRPCPort = testutil.RandomPort()
  2427  	ctx := genesis.WithGenesisContext(context.Background(), cfg.genesis)
  2428  	svr, _, _, _, _, actPool, bfIndexFile, err := createServerV2(cfg, false)
  2429  	require.NoError(err)
  2430  	grpcHandler := newGRPCHandler(svr.core)
  2431  	defer func() {
  2432  		testutil.CleanupPath(bfIndexFile)
  2433  	}()
  2434  
  2435  	res, err := grpcHandler.GetActPoolActions(ctx, &iotexapi.GetActPoolActionsRequest{})
  2436  	require.NoError(err)
  2437  	require.Equal(len(actPool.PendingActionMap()[identityset.Address(27).String()]), len(res.Actions))
  2438  
  2439  	tsf1, err := action.SignedTransfer(identityset.Address(28).String(), identityset.PrivateKey(27), 2,
  2440  		big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2441  	require.NoError(err)
  2442  	tsf2, err := action.SignedTransfer(identityset.Address(27).String(), identityset.PrivateKey(27), 3,
  2443  		big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2444  	require.NoError(err)
  2445  	tsf3, err := action.SignedTransfer(identityset.Address(29).String(), identityset.PrivateKey(27), 4,
  2446  		big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2447  	require.NoError(err)
  2448  	execution1, err := action.SignedExecution(identityset.Address(31).String(), identityset.PrivateKey(27), 5,
  2449  		big.NewInt(1), testutil.TestGasLimit, big.NewInt(10), []byte{1})
  2450  	require.NoError(err)
  2451  
  2452  	require.NoError(actPool.Add(ctx, tsf1))
  2453  	require.NoError(actPool.Add(ctx, tsf2))
  2454  	require.NoError(actPool.Add(ctx, execution1))
  2455  
  2456  	var requests []string
  2457  	h1, err := tsf1.Hash()
  2458  	require.NoError(err)
  2459  	requests = append(requests, hex.EncodeToString(h1[:]))
  2460  
  2461  	res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{})
  2462  	require.NoError(err)
  2463  	require.Equal(len(actPool.PendingActionMap()[identityset.Address(27).String()]), len(res.Actions))
  2464  
  2465  	res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: requests})
  2466  	require.NoError(err)
  2467  	require.Equal(1, len(res.Actions))
  2468  
  2469  	h2, err := tsf2.Hash()
  2470  	require.NoError(err)
  2471  	requests = append(requests, hex.EncodeToString(h2[:]))
  2472  	res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: requests})
  2473  	require.NoError(err)
  2474  	require.Equal(2, len(res.Actions))
  2475  
  2476  	h3, err := tsf3.Hash()
  2477  	require.NoError(err)
  2478  	_, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: []string{hex.EncodeToString(h3[:])}})
  2479  	require.Error(err)
  2480  }
  2481  
  2482  func TestGrpcServer_GetEstimateGasSpecialIntegrity(t *testing.T) {
  2483  	require := require.New(t)
  2484  	cfg := newConfig()
  2485  	cfg.api.GRPCPort = testutil.RandomPort()
  2486  	svr, bc, dao, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true)
  2487  	require.NoError(err)
  2488  	grpcHandler := newGRPCHandler(svr.core)
  2489  	defer func() {
  2490  		testutil.CleanupPath(bfIndexFile)
  2491  	}()
  2492  
  2493  	// deploy self-desturct contract
  2494  	contractCode := "608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610196806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632e64cec11461004657806343d726d6146100645780636057361d1461006e575b600080fd5b61004e61008a565b60405161005b9190610124565b60405180910390f35b61006c610094565b005b610088600480360381019061008391906100ec565b6100cd565b005b6000600154905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018190555050565b6000813590506100e681610149565b92915050565b6000602082840312156100fe57600080fd5b600061010c848285016100d7565b91505092915050565b61011e8161013f565b82525050565b60006020820190506101396000830184610115565b92915050565b6000819050919050565b6101528161013f565b811461015d57600080fd5b5056fea264697066735822122060e7a28baea4232a95074b94b50009d1d7b99302ef6556a1f3ce7f46a49f8cc064736f6c63430008000033"
  2495  	contract, err := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 1, bc.TipHeight(), contractCode)
  2496  
  2497  	require.NoError(err)
  2498  	require.True(len(contract) > 0)
  2499  
  2500  	// call self-destuct func, which will invoke gas refund policy
  2501  	data := "43d726d6"
  2502  	byteCodes, err := hex.DecodeString(data)
  2503  	require.NoError(err)
  2504  	execution, err := action.NewExecution(contract, 2, big.NewInt(0), 0, big.NewInt(0), byteCodes)
  2505  	require.NoError(err)
  2506  	request := &iotexapi.EstimateActionGasConsumptionRequest{
  2507  		Action: &iotexapi.EstimateActionGasConsumptionRequest_Execution{
  2508  			Execution: execution.Proto(),
  2509  		},
  2510  		CallerAddress: identityset.Address(13).String(),
  2511  	}
  2512  	res, err := grpcHandler.EstimateActionGasConsumption(context.Background(), request)
  2513  	require.NoError(err)
  2514  	require.Equal(uint64(10777), res.Gas)
  2515  }
  2516  
  2517  func TestChainlinkErrIntegrity(t *testing.T) {
  2518  	require := require.New(t)
  2519  
  2520  	gethFatal := regexp.MustCompile(`(: |^)(exceeds block gas limit|invalid sender|negative value|oversized data|gas uint64 overflow|intrinsic gas too low|nonce too high)$`)
  2521  
  2522  	tests := []struct {
  2523  		testName string
  2524  		cfg      func() testConfig
  2525  		actions  []*iotextypes.Action
  2526  		errRegex *regexp.Regexp
  2527  	}{
  2528  		{
  2529  			"NonceTooLow",
  2530  			func() testConfig {
  2531  				return newConfig()
  2532  			},
  2533  			[]*iotextypes.Action{_testTransferInvalid1Pb},
  2534  			regexp.MustCompile(`(: |^)nonce too low$`),
  2535  		},
  2536  		{
  2537  			"TerminallyUnderpriced",
  2538  			func() testConfig {
  2539  				return newConfig()
  2540  			},
  2541  			[]*iotextypes.Action{_testTransferInvalid2Pb},
  2542  			regexp.MustCompile(`(: |^)transaction underpriced$`),
  2543  		},
  2544  		{
  2545  			"InsufficientEth",
  2546  			func() testConfig {
  2547  				return newConfig()
  2548  			},
  2549  			[]*iotextypes.Action{_testTransferInvalid3Pb},
  2550  			regexp.MustCompile(`(: |^)(insufficient funds for transfer|insufficient funds for gas \* price \+ value|insufficient balance for transfer)$`),
  2551  		},
  2552  
  2553  		{
  2554  			"NonceTooHigh",
  2555  			func() testConfig {
  2556  				return newConfig()
  2557  			},
  2558  			[]*iotextypes.Action{_testTransferInvalid4Pb},
  2559  			gethFatal,
  2560  		},
  2561  		{
  2562  			"TransactionAlreadyInMempool",
  2563  			func() testConfig {
  2564  				return newConfig()
  2565  			},
  2566  			[]*iotextypes.Action{_testTransferPb, _testTransferPb},
  2567  			regexp.MustCompile(`(: |^)(?i)(known transaction|already known)`),
  2568  		},
  2569  		{
  2570  			"ReplacementTransactionUnderpriced",
  2571  			func() testConfig {
  2572  				return newConfig()
  2573  			},
  2574  			[]*iotextypes.Action{_testTransferPb, _testTransferInvalid5Pb},
  2575  			regexp.MustCompile(`(: |^)replacement transaction underpriced$`),
  2576  		},
  2577  		{
  2578  			"IntrinsicGasTooLow",
  2579  			func() testConfig {
  2580  				return newConfig()
  2581  			},
  2582  			[]*iotextypes.Action{_testTransferInvalid6Pb},
  2583  			gethFatal,
  2584  		},
  2585  		{
  2586  			"NegativeValue",
  2587  			func() testConfig {
  2588  				return newConfig()
  2589  			},
  2590  			[]*iotextypes.Action{_testTransferInvalid7Pb},
  2591  			gethFatal,
  2592  		},
  2593  		{
  2594  			"ExceedsBlockGasLimit",
  2595  			func() testConfig {
  2596  				cfg := newConfig()
  2597  				cfg.actPoll.MaxGasLimitPerPool = 1e5
  2598  				return cfg
  2599  			},
  2600  			[]*iotextypes.Action{_testTransferInvalid8Pb},
  2601  			gethFatal,
  2602  		},
  2603  	}
  2604  
  2605  	for i, test := range tests {
  2606  		t.Run(strconv.Itoa(i), func(t *testing.T) {
  2607  			cfg := test.cfg()
  2608  			cfg.api.GRPCPort = testutil.RandomPort()
  2609  			svr, _, _, _, _, _, file, err := createServerV2(cfg, true)
  2610  			require.NoError(err)
  2611  			grpcHandler := newGRPCHandler(svr.core)
  2612  			defer func() {
  2613  				testutil.CleanupPath(file)
  2614  			}()
  2615  
  2616  			for _, action := range test.actions {
  2617  				_, err = grpcHandler.SendAction(context.Background(), &iotexapi.SendActionRequest{Action: action})
  2618  				if err != nil {
  2619  					break
  2620  				}
  2621  			}
  2622  			s, ok := status.FromError(err)
  2623  			require.True(ok)
  2624  			require.True(test.errRegex.MatchString(s.Message()))
  2625  		})
  2626  	}
  2627  }
  2628  
  2629  func TestGrpcServer_TraceTransactionStructLogsIntegrity(t *testing.T) {
  2630  	require := require.New(t)
  2631  	cfg := newConfig()
  2632  	cfg.api.GRPCPort = testutil.RandomPort()
  2633  	svr, bc, _, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true)
  2634  	require.NoError(err)
  2635  	grpcHandler := newGRPCHandler(svr.core)
  2636  	defer func() {
  2637  		testutil.CleanupPath(bfIndexFile)
  2638  	}()
  2639  
  2640  	request := &iotexapi.TraceTransactionStructLogsRequest{
  2641  		ActionHash: hex.EncodeToString(hash.ZeroHash256[:]),
  2642  	}
  2643  	_, err = grpcHandler.TraceTransactionStructLogs(context.Background(), request)
  2644  	require.Error(err)
  2645  
  2646  	//unsupport type
  2647  	request.ActionHash = hex.EncodeToString(_transferHash1[:])
  2648  	_, err = grpcHandler.TraceTransactionStructLogs(context.Background(), request)
  2649  	require.Error(err)
  2650  
  2651  	// deploy a contract
  2652  	contractCode := "6080604052348015600f57600080fd5b5060de8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008082409050807f2d93f7749862d33969fb261757410b48065a1bc86a56da5c47820bd063e2338260405160405180910390a28091505091905056fea265627a7a723158200a258cd08ea99ee11aa68c78b6d2bf7ea912615a1e64a81b90a2abca2dd59cfa64736f6c634300050c0032"
  2653  
  2654  	data, _ := hex.DecodeString(contractCode)
  2655  	ex1, err := action.SignedExecution(action.EmptyAddress, identityset.PrivateKey(13), 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), data)
  2656  	require.NoError(err)
  2657  	actPool.Add(context.Background(), ex1)
  2658  	require.NoError(err)
  2659  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  2660  	require.NoError(err)
  2661  	bc.CommitBlock(blk)
  2662  	require.NoError(err)
  2663  	actPool.Reset()
  2664  	ex1Hash, _ := ex1.Hash()
  2665  	request.ActionHash = hex.EncodeToString(ex1Hash[:])
  2666  	ret, err := grpcHandler.TraceTransactionStructLogs(context.Background(), request)
  2667  	require.NoError(err)
  2668  	require.Equal(len(ret.StructLogs), 17)
  2669  	log := ret.StructLogs[0]
  2670  	require.Equal(log.Depth, int32(1))
  2671  	require.Equal(log.Gas, uint64(0x717a0))
  2672  	require.Equal(log.GasCost, uint64(0x3))
  2673  	require.Equal(log.Op, uint64(0x60))
  2674  	require.Equal(log.OpName, "PUSH1")
  2675  }