github.com/noirx94/tendermintmp@v0.0.1/state/txindex/indexer_service.go (about) 1 package txindex 2 3 import ( 4 "context" 5 6 "github.com/tendermint/tendermint/libs/service" 7 "github.com/tendermint/tendermint/state/indexer" 8 "github.com/tendermint/tendermint/types" 9 ) 10 11 // XXX/TODO: These types should be moved to the indexer package. 12 13 const ( 14 subscriber = "IndexerService" 15 ) 16 17 // IndexerService connects event bus, transaction and block indexers together in 18 // order to index transactions and blocks coming from the event bus. 19 type IndexerService struct { 20 service.BaseService 21 22 txIdxr TxIndexer 23 blockIdxr indexer.BlockIndexer 24 eventBus *types.EventBus 25 } 26 27 // NewIndexerService returns a new service instance. 28 func NewIndexerService( 29 txIdxr TxIndexer, 30 blockIdxr indexer.BlockIndexer, 31 eventBus *types.EventBus, 32 ) *IndexerService { 33 34 is := &IndexerService{txIdxr: txIdxr, blockIdxr: blockIdxr, eventBus: eventBus} 35 is.BaseService = *service.NewBaseService(nil, "IndexerService", is) 36 return is 37 } 38 39 // OnStart implements service.Service by subscribing for all transactions 40 // and indexing them by events. 41 func (is *IndexerService) OnStart() error { 42 // Use SubscribeUnbuffered here to ensure both subscriptions does not get 43 // cancelled due to not pulling messages fast enough. Cause this might 44 // sometimes happen when there are no other subscribers. 45 blockHeadersSub, err := is.eventBus.SubscribeUnbuffered( 46 context.Background(), 47 subscriber, 48 types.EventQueryNewBlockHeader) 49 if err != nil { 50 return err 51 } 52 53 txsSub, err := is.eventBus.SubscribeUnbuffered(context.Background(), subscriber, types.EventQueryTx) 54 if err != nil { 55 return err 56 } 57 58 go func() { 59 for { 60 msg := <-blockHeadersSub.Out() 61 eventDataHeader := msg.Data().(types.EventDataNewBlockHeader) 62 height := eventDataHeader.Header.Height 63 batch := NewBatch(eventDataHeader.NumTxs) 64 65 for i := int64(0); i < eventDataHeader.NumTxs; i++ { 66 msg2 := <-txsSub.Out() 67 txResult := msg2.Data().(types.EventDataTx).TxResult 68 69 if err = batch.Add(&txResult); err != nil { 70 is.Logger.Error( 71 "failed to add tx to batch", 72 "height", height, 73 "index", txResult.Index, 74 "err", err, 75 ) 76 } 77 } 78 79 if err := is.blockIdxr.Index(eventDataHeader); err != nil { 80 is.Logger.Error("failed to index block", "height", height, "err", err) 81 } else { 82 is.Logger.Info("indexed block", "height", height) 83 } 84 85 if err = is.txIdxr.AddBatch(batch); err != nil { 86 is.Logger.Error("failed to index block txs", "height", height, "err", err) 87 } else { 88 is.Logger.Debug("indexed block txs", "height", height, "num_txs", eventDataHeader.NumTxs) 89 } 90 } 91 }() 92 return nil 93 } 94 95 // OnStop implements service.Service by unsubscribing from all transactions. 96 func (is *IndexerService) OnStop() { 97 if is.eventBus.IsRunning() { 98 _ = is.eventBus.UnsubscribeAll(context.Background(), subscriber) 99 } 100 }