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

     1  package api
     2  
     3  import (
     4  	"encoding/hex"
     5  
     6  	"go.uber.org/zap"
     7  
     8  	"github.com/iotexproject/iotex-proto/golang/iotexapi"
     9  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    10  
    11  	apitypes "github.com/iotexproject/iotex-core/api/types"
    12  	"github.com/iotexproject/iotex-core/blockchain/block"
    13  	"github.com/iotexproject/iotex-core/pkg/log"
    14  )
    15  
    16  type streamHandler func(interface{}) (int, error)
    17  
    18  type gRPCBlockListener struct {
    19  	streamHandle streamHandler
    20  	errChan      chan error
    21  }
    22  
    23  // NewGRPCBlockListener returns a new gRPC block listener
    24  func NewGRPCBlockListener(handler streamHandler, errChan chan error) apitypes.Responder {
    25  	return &gRPCBlockListener{
    26  		streamHandle: handler,
    27  		errChan:      errChan,
    28  	}
    29  }
    30  
    31  // Respond to new block
    32  func (bl *gRPCBlockListener) Respond(_ string, blk *block.Block) error {
    33  	var receiptsPb []*iotextypes.Receipt
    34  	for _, receipt := range blk.Receipts {
    35  		receiptsPb = append(receiptsPb, receipt.ConvertToReceiptPb())
    36  	}
    37  	blockInfo := &iotexapi.BlockInfo{
    38  		Block:    blk.ConvertToBlockPb(),
    39  		Receipts: receiptsPb,
    40  	}
    41  	h := blk.HashBlock()
    42  	blockID := &iotextypes.BlockIdentifier{
    43  		Hash:   hex.EncodeToString(h[:]),
    44  		Height: blk.Height(),
    45  	}
    46  	// send blockInfo thru streaming API
    47  	if _, err := bl.streamHandle(&iotexapi.StreamBlocksResponse{
    48  		Block:           blockInfo,
    49  		BlockIdentifier: blockID,
    50  	}); err != nil {
    51  		log.L().Info(
    52  			"Error when streaming the block",
    53  			zap.Uint64("height", blockInfo.GetBlock().GetHeader().GetCore().GetHeight()),
    54  			zap.Error(err),
    55  		)
    56  		bl.errChan <- err
    57  		return err
    58  	}
    59  	return nil
    60  }
    61  
    62  // Exit send to error channel
    63  func (bl *gRPCBlockListener) Exit() {
    64  	bl.errChan <- nil
    65  }
    66  
    67  type web3BlockListener struct {
    68  	streamHandle streamHandler
    69  }
    70  
    71  // NewWeb3BlockListener returns a new websocket block listener
    72  func NewWeb3BlockListener(handler streamHandler) apitypes.Responder {
    73  	return &web3BlockListener{
    74  		streamHandle: handler,
    75  	}
    76  }
    77  
    78  // Respond to new block
    79  func (bl *web3BlockListener) Respond(id string, blk *block.Block) error {
    80  	res := &streamResponse{
    81  		id: id,
    82  		result: &getBlockResult{
    83  			blk: blk,
    84  		},
    85  	}
    86  	// send blockInfo thru streaming API
    87  	if _, err := bl.streamHandle(res); err != nil {
    88  		log.L().Info(
    89  			"Error when streaming the block",
    90  			zap.Uint64("height", blk.Height()),
    91  			zap.Error(err),
    92  		)
    93  		return err
    94  	}
    95  	return nil
    96  }
    97  
    98  // Exit send to error channel
    99  func (bl *web3BlockListener) Exit() {}