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 }