github.com/Finschia/ostracon@v1.1.5/rpc/core/tx_test.go (about)

     1  package core
     2  
     3  import (
     4  	"encoding/hex"
     5  	"errors"
     6  	"fmt"
     7  	"math"
     8  	"testing"
     9  	"time"
    10  
    11  	dbm "github.com/tendermint/tm-db"
    12  
    13  	txidxkv "github.com/Finschia/ostracon/state/txindex/kv"
    14  	txidxnull "github.com/Finschia/ostracon/state/txindex/null"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	rpctypes "github.com/Finschia/ostracon/rpc/jsonrpc/types"
    18  	"github.com/Finschia/ostracon/types"
    19  )
    20  
    21  func TestTxSearchByTxHashQuery(t *testing.T) {
    22  	height := int64(1)
    23  	txIndex := 0
    24  	tx := []byte{byte(height), byte(txIndex)}
    25  	hash := hex.EncodeToString(types.Tx(tx).Hash())
    26  	ctx := &rpctypes.Context{}
    27  
    28  	q := fmt.Sprintf("%s='%s'", types.TxHashKey, hash)
    29  	prove := false
    30  	page := 1
    31  	perPage := 10
    32  	orderBy := TestOrderByDefault
    33  
    34  	state, cleanup := makeTestState()
    35  	defer cleanup()
    36  
    37  	{
    38  		// Get by tx.hash (not search/range)
    39  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
    40  
    41  		require.NoError(t, err)
    42  		require.NotNil(t, res)
    43  		require.Equal(t, 0, res.TotalCount) // Don't have tx in db
    44  		require.Equal(t, 0, len(res.Txs))
    45  	}
    46  
    47  	numToMakeBlocks := 1
    48  	numToMakeTxs := 1
    49  	numOfGet := 1
    50  	// SaveBlock
    51  	storeTestBlocks(height, int64(numToMakeBlocks), int64(numToMakeTxs), state, time.Now())
    52  
    53  	{
    54  		// Get by block.height (not search/range)
    55  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
    56  
    57  		require.NoError(t, err)
    58  		require.NotNil(t, res)
    59  		require.Equal(t, numToMakeTxs, res.TotalCount) // Get
    60  		require.Equal(t, numOfGet, len(res.Txs))
    61  	}
    62  }
    63  
    64  func TestTxSearchByTxHeightQuery(t *testing.T) {
    65  	height := int64(1)
    66  	ctx := &rpctypes.Context{}
    67  
    68  	q := fmt.Sprintf("%s>=%d", types.TxHeightKey, height)
    69  	prove := false
    70  	page := 1
    71  	perPage := 10
    72  	orderBy := TestOrderByDefault
    73  
    74  	state, cleanup := makeTestState()
    75  	defer cleanup()
    76  
    77  	numToMakeBlocks := 5
    78  	numToMakeTxs := 3
    79  	numToGet := perPage
    80  	// SaveBlock
    81  	storeTestBlocks(height, int64(numToMakeBlocks), int64(numToMakeTxs), state, time.Now())
    82  
    83  	{
    84  		// Search blocks by range query with asc (default)
    85  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
    86  
    87  		require.NoError(t, err)
    88  		require.NotNil(t, res)
    89  		require.Equal(t, numToMakeBlocks*numToMakeTxs, res.TotalCount)
    90  		require.Equal(t, numToGet, len(res.Txs))
    91  		// check first tx
    92  		first := res.Txs[0]
    93  		require.Equal(t, height, first.Height)
    94  		require.Equal(t, uint32(0), first.Index)
    95  		// check last tx
    96  		last := res.Txs[numToGet-1]
    97  		require.Equal(t, int64(math.Ceil(float64(numToGet)/float64(numToMakeTxs))), last.Height)
    98  		require.Equal(t, uint32(numToGet%numToMakeTxs-1), last.Index)
    99  	}
   100  	{
   101  		orderBy = TestOrderByDesc
   102  		// Search blocks by range query with desc
   103  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   104  
   105  		require.NoError(t, err)
   106  		require.NotNil(t, res)
   107  		require.Equal(t, numToMakeBlocks*numToMakeTxs, res.TotalCount)
   108  		require.Equal(t, numToGet, len(res.Txs))
   109  		// check first tx
   110  		first := res.Txs[0]
   111  		require.Equal(t, int64(numToMakeBlocks), first.Height)
   112  		require.Equal(t, uint32(numToMakeTxs-1), first.Index)
   113  		// check last tx
   114  		last := res.Txs[numToGet-1]
   115  		require.Equal(t, int64(numToMakeBlocks-numToGet/numToMakeTxs), last.Height)
   116  		require.Equal(t, uint32(numToMakeTxs-numToGet%numToMakeTxs), last.Index)
   117  	}
   118  	{
   119  		// Range queries: how to use: see query_test.go
   120  		q = fmt.Sprintf("%s>=%d AND %s<=%d", types.TxHeightKey, height, types.TxHeightKey, height+1)
   121  		orderBy = TestOrderByAsc
   122  		// Search blocks by range query with asc
   123  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   124  
   125  		require.NoError(t, err)
   126  		require.NotNil(t, res)
   127  		require.Equal(t, numToMakeTxs*2, res.TotalCount)
   128  		require.Equal(t, numToMakeTxs*2, len(res.Txs))
   129  		// check first tx
   130  		first := res.Txs[0]
   131  		require.Equal(t, height, first.Height)
   132  		require.Equal(t, uint32(0), first.Index)
   133  		// check last tx
   134  		last := res.Txs[len(res.Txs)-1]
   135  		require.Equal(t, height+1, last.Height)
   136  		require.Equal(t, uint32(numToMakeTxs-1), last.Index)
   137  	}
   138  	{
   139  		// Range queries with illegal key
   140  		q = fmt.Sprintf("%s>=%d AND %s<=%d AND test.key>=1",
   141  			types.TxHeightKey, height, types.TxHeightKey, height+1)
   142  		orderBy = TestOrderByAsc
   143  		// Search blocks by range query with asc
   144  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   145  
   146  		require.NoError(t, err)
   147  		require.NotNil(t, res)
   148  		require.Equal(t, 0, res.TotalCount) // Cannot Get
   149  		require.Equal(t, 0, len(res.Txs))
   150  	}
   151  }
   152  
   153  func TestTxSearch_errors(t *testing.T) {
   154  	ctx := &rpctypes.Context{}
   155  
   156  	q := ""
   157  	prove := false
   158  	page := 0
   159  	perPage := 1
   160  	orderBy := "error"
   161  
   162  	{
   163  		// error: env.TxIndexer.(*txidxnull.TxIndex)
   164  		env = &Environment{}
   165  		env.TxIndexer = &txidxnull.TxIndex{}
   166  
   167  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   168  
   169  		require.Error(t, err)
   170  		require.Equal(t, errors.New("transaction indexing is disabled"), err)
   171  		require.Nil(t, res)
   172  	}
   173  	{
   174  		// error: tmquery.New(query)
   175  		env = &Environment{}
   176  
   177  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   178  
   179  		require.Error(t, err)
   180  		require.Equal(t,
   181  			"\nparse error near Unknown (line 1 symbol 1 - line 1 symbol 1):\n\"\"\n",
   182  			err.Error())
   183  		require.Nil(t, res)
   184  	}
   185  	{
   186  		// error: lookForHash
   187  		env = &Environment{}
   188  		env.TxIndexer = txidxkv.NewTxIndex(dbm.NewMemDB())
   189  		q = fmt.Sprintf("%s=%s", types.TxHashKey, "'1'")
   190  
   191  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   192  
   193  		require.Error(t, err)
   194  		require.Equal(t,
   195  			"error during searching for a hash in the query: encoding/hex: odd length hex string",
   196  			err.Error())
   197  		require.Nil(t, res)
   198  	}
   199  	{
   200  		// error: switch orderBy
   201  		env = &Environment{}
   202  		env.TxIndexer = txidxkv.NewTxIndex(dbm.NewMemDB())
   203  		q = fmt.Sprintf("%s=%s", types.TxHashKey, "'1234567890abcdef'")
   204  
   205  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   206  
   207  		require.Error(t, err)
   208  		require.Equal(t,
   209  			"expected order_by to be either `asc` or `desc` or empty",
   210  			err.Error())
   211  		require.Nil(t, res)
   212  	}
   213  	{
   214  		// error: validatePage(pagePtr, perPage, totalCount)
   215  		env = &Environment{}
   216  		env.TxIndexer = txidxkv.NewTxIndex(dbm.NewMemDB())
   217  		q = fmt.Sprintf("%s=%s", types.TxHashKey, "'1234567890abcdef'")
   218  		orderBy = TestOrderByAsc
   219  
   220  		res, err := TxSearch(ctx, q, prove, &page, &perPage, orderBy)
   221  
   222  		require.Error(t, err)
   223  		require.Equal(t,
   224  			"page should be within [1, 1] range, given 0",
   225  			err.Error())
   226  		require.Nil(t, res)
   227  	}
   228  }