github.com/PikeEcosystem/tendermint@v0.0.4/state/txindex/indexer_service_test.go (about)

     1  package txindex_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  	abci "github.com/tendermint/tendermint/abci/types"
     9  	db "github.com/tendermint/tm-db"
    10  
    11  	tmabci "github.com/PikeEcosystem/tendermint/abci/types"
    12  	"github.com/PikeEcosystem/tendermint/libs/log"
    13  	blockidxkv "github.com/PikeEcosystem/tendermint/state/indexer/block/kv"
    14  	"github.com/PikeEcosystem/tendermint/state/txindex"
    15  	"github.com/PikeEcosystem/tendermint/state/txindex/kv"
    16  	"github.com/PikeEcosystem/tendermint/types"
    17  )
    18  
    19  func TestIndexerServiceIndexesBlocks(t *testing.T) {
    20  	// event bus
    21  	eventBus := types.NewEventBus()
    22  	eventBus.SetLogger(log.TestingLogger())
    23  	err := eventBus.Start()
    24  	require.NoError(t, err)
    25  	t.Cleanup(func() {
    26  		if err := eventBus.Stop(); err != nil {
    27  			t.Error(err)
    28  		}
    29  	})
    30  
    31  	// tx indexer
    32  	store := db.NewMemDB()
    33  	txIndexer := kv.NewTxIndex(store)
    34  	blockIndexer := blockidxkv.New(db.NewPrefixDB(store, []byte("block_events")))
    35  
    36  	service := txindex.NewIndexerService(txIndexer, blockIndexer, eventBus)
    37  	service.SetLogger(log.TestingLogger())
    38  	err = service.Start()
    39  	require.NoError(t, err)
    40  	t.Cleanup(func() {
    41  		if err := service.Stop(); err != nil {
    42  			t.Error(err)
    43  		}
    44  	})
    45  
    46  	// publish block with txs
    47  	err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
    48  		Header: types.Header{Height: 1},
    49  		NumTxs: int64(2),
    50  	})
    51  	require.NoError(t, err)
    52  	txResult1 := &abci.TxResult{
    53  		Height: 1,
    54  		Index:  uint32(0),
    55  		Tx:     types.Tx("foo"),
    56  		Result: abci.ResponseDeliverTx{Code: 0},
    57  	}
    58  	err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1})
    59  	require.NoError(t, err)
    60  	txResult2 := &abci.TxResult{
    61  		Height: 1,
    62  		Index:  uint32(1),
    63  		Tx:     types.Tx("bar"),
    64  		Result: abci.ResponseDeliverTx{Code: 0},
    65  	}
    66  	err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2})
    67  	require.NoError(t, err)
    68  
    69  	time.Sleep(100 * time.Millisecond)
    70  
    71  	res, err := txIndexer.Get(types.Tx("foo").Hash())
    72  	require.NoError(t, err)
    73  	require.Equal(t, txResult1, res)
    74  
    75  	ok, err := blockIndexer.Has(1)
    76  	require.NoError(t, err)
    77  	require.True(t, ok)
    78  
    79  	res, err = txIndexer.Get(types.Tx("bar").Hash())
    80  	require.NoError(t, err)
    81  	require.Equal(t, txResult2, res)
    82  }
    83  
    84  func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) {
    85  	var mockTx = types.Tx("MOCK_TX_HASH")
    86  
    87  	testCases := []struct {
    88  		name    string
    89  		tx1     abci.TxResult
    90  		tx2     abci.TxResult
    91  		expSkip bool // do we expect the second tx to be skipped by tx indexer
    92  	}{
    93  		{"skip, previously successful",
    94  			abci.TxResult{
    95  				Height: 1,
    96  				Index:  0,
    97  				Tx:     mockTx,
    98  				Result: abci.ResponseDeliverTx{
    99  					Code: tmabci.CodeTypeOK,
   100  				},
   101  			},
   102  			abci.TxResult{
   103  				Height: 2,
   104  				Index:  0,
   105  				Tx:     mockTx,
   106  				Result: abci.ResponseDeliverTx{
   107  					Code: tmabci.CodeTypeOK + 1,
   108  				},
   109  			},
   110  			true,
   111  		},
   112  		{"not skip, previously unsuccessful",
   113  			abci.TxResult{
   114  				Height: 1,
   115  				Index:  0,
   116  				Tx:     mockTx,
   117  				Result: abci.ResponseDeliverTx{
   118  					Code: tmabci.CodeTypeOK + 1,
   119  				},
   120  			},
   121  			abci.TxResult{
   122  				Height: 2,
   123  				Index:  0,
   124  				Tx:     mockTx,
   125  				Result: abci.ResponseDeliverTx{
   126  					Code: tmabci.CodeTypeOK + 1,
   127  				},
   128  			},
   129  			false,
   130  		},
   131  		{"not skip, both successful",
   132  			abci.TxResult{
   133  				Height: 1,
   134  				Index:  0,
   135  				Tx:     mockTx,
   136  				Result: abci.ResponseDeliverTx{
   137  					Code: tmabci.CodeTypeOK,
   138  				},
   139  			},
   140  			abci.TxResult{
   141  				Height: 2,
   142  				Index:  0,
   143  				Tx:     mockTx,
   144  				Result: abci.ResponseDeliverTx{
   145  					Code: tmabci.CodeTypeOK,
   146  				},
   147  			},
   148  			false,
   149  		},
   150  		{"not skip, both unsuccessful",
   151  			abci.TxResult{
   152  				Height: 1,
   153  				Index:  0,
   154  				Tx:     mockTx,
   155  				Result: abci.ResponseDeliverTx{
   156  					Code: tmabci.CodeTypeOK + 1,
   157  				},
   158  			},
   159  			abci.TxResult{
   160  				Height: 2,
   161  				Index:  0,
   162  				Tx:     mockTx,
   163  				Result: abci.ResponseDeliverTx{
   164  					Code: tmabci.CodeTypeOK + 1,
   165  				},
   166  			},
   167  			false,
   168  		},
   169  		{"skip, same block, previously successful",
   170  			abci.TxResult{
   171  				Height: 1,
   172  				Index:  0,
   173  				Tx:     mockTx,
   174  				Result: abci.ResponseDeliverTx{
   175  					Code: tmabci.CodeTypeOK,
   176  				},
   177  			},
   178  			abci.TxResult{
   179  				Height: 1,
   180  				Index:  0,
   181  				Tx:     mockTx,
   182  				Result: abci.ResponseDeliverTx{
   183  					Code: tmabci.CodeTypeOK + 1,
   184  				},
   185  			},
   186  			true,
   187  		},
   188  		{"not skip, same block, previously unsuccessful",
   189  			abci.TxResult{
   190  				Height: 1,
   191  				Index:  0,
   192  				Tx:     mockTx,
   193  				Result: abci.ResponseDeliverTx{
   194  					Code: tmabci.CodeTypeOK + 1,
   195  				},
   196  			},
   197  			abci.TxResult{
   198  				Height: 1,
   199  				Index:  0,
   200  				Tx:     mockTx,
   201  				Result: abci.ResponseDeliverTx{
   202  					Code: tmabci.CodeTypeOK,
   203  				},
   204  			},
   205  			false,
   206  		},
   207  	}
   208  
   209  	for _, tc := range testCases {
   210  		t.Run(tc.name, func(t *testing.T) {
   211  			indexer := kv.NewTxIndex(db.NewMemDB())
   212  
   213  			if tc.tx1.Height != tc.tx2.Height {
   214  				// index the first tx
   215  				err := indexer.AddBatch(&txindex.Batch{
   216  					Ops: []*abci.TxResult{&tc.tx1},
   217  				})
   218  				require.NoError(t, err)
   219  
   220  				// check if the second one should be skipped.
   221  				ops, err := txindex.DeduplicateBatch([]*abci.TxResult{&tc.tx2}, indexer)
   222  				require.NoError(t, err)
   223  
   224  				if tc.expSkip {
   225  					require.Empty(t, ops)
   226  				} else {
   227  					require.Equal(t, []*abci.TxResult{&tc.tx2}, ops)
   228  				}
   229  			} else {
   230  				// same block
   231  				ops := []*abci.TxResult{&tc.tx1, &tc.tx2}
   232  				ops, err := txindex.DeduplicateBatch(ops, indexer)
   233  				require.NoError(t, err)
   234  				if tc.expSkip {
   235  					// the second one is skipped
   236  					require.Equal(t, []*abci.TxResult{&tc.tx1}, ops)
   237  				} else {
   238  					require.Equal(t, []*abci.TxResult{&tc.tx1, &tc.tx2}, ops)
   239  				}
   240  			}
   241  		})
   242  	}
   243  }