github.com/iotexproject/iotex-core@v1.14.1-rc1/api/loglistener.go (about)

     1  package api
     2  
     3  import (
     4  	"github.com/iotexproject/iotex-proto/golang/iotexapi"
     5  	"go.uber.org/zap"
     6  
     7  	"github.com/iotexproject/iotex-core/api/logfilter"
     8  	apitypes "github.com/iotexproject/iotex-core/api/types"
     9  	"github.com/iotexproject/iotex-core/blockchain/block"
    10  	"github.com/iotexproject/iotex-core/pkg/log"
    11  )
    12  
    13  type gRPCLogListener struct {
    14  	logFilter    *logfilter.LogFilter
    15  	streamHandle streamHandler
    16  	errChan      chan error
    17  }
    18  
    19  // NewGRPCLogListener returns a new log listener
    20  func NewGRPCLogListener(in *logfilter.LogFilter, handler streamHandler, errChan chan error) apitypes.Responder {
    21  	return &gRPCLogListener{
    22  		logFilter:    in,
    23  		streamHandle: handler,
    24  		errChan:      errChan,
    25  	}
    26  }
    27  
    28  // Respond to new block
    29  func (ll *gRPCLogListener) Respond(_ string, blk *block.Block) error {
    30  	if !ll.logFilter.ExistInBloomFilter(blk.LogsBloomfilter()) {
    31  		return nil
    32  	}
    33  	blkHash := blk.HashBlock()
    34  	logs := ll.logFilter.MatchLogs(blk.Receipts)
    35  	// send matched logs thru streaming API
    36  	for _, e := range logs {
    37  		logPb := e.ConvertToLogPb()
    38  		logPb.BlkHash = blkHash[:]
    39  		if _, err := ll.streamHandle(&iotexapi.StreamLogsResponse{Log: logPb}); err != nil {
    40  			ll.errChan <- err
    41  			log.L().Info("error streaming the log",
    42  				zap.Uint64("height", e.BlockHeight),
    43  				zap.Error(err))
    44  			return err
    45  		}
    46  	}
    47  	return nil
    48  }
    49  
    50  // Exit send to error channel
    51  func (ll *gRPCLogListener) Exit() {
    52  	ll.errChan <- nil
    53  }
    54  
    55  type web3LogListener struct {
    56  	logFilter    *logfilter.LogFilter
    57  	streamHandle streamHandler
    58  }
    59  
    60  // NewWeb3LogListener returns a new websocket block listener
    61  func NewWeb3LogListener(filter *logfilter.LogFilter, handler streamHandler) apitypes.Responder {
    62  	return &web3LogListener{
    63  		logFilter:    filter,
    64  		streamHandle: handler,
    65  	}
    66  }
    67  
    68  // Respond to new block
    69  func (ll *web3LogListener) Respond(id string, blk *block.Block) error {
    70  	if !ll.logFilter.ExistInBloomFilter(blk.LogsBloomfilter()) {
    71  		return nil
    72  	}
    73  	blkHash := blk.HashBlock()
    74  	logs := ll.logFilter.MatchLogs(blk.Receipts)
    75  
    76  	for _, e := range logs {
    77  		res := &streamResponse{
    78  			id: id,
    79  			result: &getLogsResult{
    80  				blockHash: blkHash,
    81  				log:       e,
    82  			},
    83  		}
    84  		if _, err := ll.streamHandle(res); err != nil {
    85  			log.L().Info(
    86  				"Error when streaming the block",
    87  				zap.Uint64("height", blk.Height()),
    88  				zap.Error(err),
    89  			)
    90  			return err
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  // Exit send to error channel
    97  func (ll *web3LogListener) Exit() {}