github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/events/producer/eventhelper.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package producer
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/hyperledger/fabric/protos/common"
    23  	pb "github.com/hyperledger/fabric/protos/peer"
    24  	"github.com/hyperledger/fabric/protos/utils"
    25  )
    26  
    27  // SendProducerBlockEvent sends block event to clients
    28  func SendProducerBlockEvent(block *common.Block) error {
    29  	logger.Debugf("Entry")
    30  	defer logger.Debugf("Exit")
    31  	bevent := &common.Block{}
    32  	bevent.Header = block.Header
    33  	bevent.Metadata = block.Metadata
    34  	bevent.Data = &common.BlockData{}
    35  	var channelId string
    36  	for _, d := range block.Data.Data {
    37  		ebytes := d
    38  		if ebytes != nil {
    39  			if env, err := utils.GetEnvelopeFromBlock(ebytes); err != nil {
    40  				logger.Errorf("error getting tx from block(%s)\n", err)
    41  			} else if env != nil {
    42  				// get the payload from the envelope
    43  				payload, err := utils.GetPayload(env)
    44  				if err != nil {
    45  					return fmt.Errorf("could not extract payload from envelope, err %s", err)
    46  				}
    47  
    48  				chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
    49  				if err != nil {
    50  					return err
    51  				}
    52  				channelId = chdr.ChannelId
    53  
    54  				if common.HeaderType(chdr.Type) == common.HeaderType_ENDORSER_TRANSACTION {
    55  					logger.Debugf("Channel [%s]: Block event for block number [%d] contains transaction id: %s", channelId, block.Header.Number, chdr.TxId)
    56  					tx, err := utils.GetTransaction(payload.Data)
    57  					if err != nil {
    58  						return fmt.Errorf("error unmarshalling transaction payload for block event: %s", err)
    59  					}
    60  					chaincodeActionPayload, err := utils.GetChaincodeActionPayload(tx.Actions[0].Payload)
    61  					if err != nil {
    62  						return fmt.Errorf("error unmarshalling transaction action payload for block event: %s", err)
    63  					}
    64  					propRespPayload, err := utils.GetProposalResponsePayload(chaincodeActionPayload.Action.ProposalResponsePayload)
    65  					if err != nil {
    66  						return fmt.Errorf("error unmarshalling proposal response payload for block event: %s", err)
    67  					}
    68  					//ENDORSER_ACTION, ProposalResponsePayload.Extension field contains ChaincodeAction
    69  					caPayload, err := utils.GetChaincodeAction(propRespPayload.Extension)
    70  					if err != nil {
    71  						return fmt.Errorf("error unmarshalling chaincode action for block event: %s", err)
    72  					}
    73  					// Drop read write set from transaction before sending block event
    74  					// Performance issue with chaincode deploy txs and causes nodejs grpc
    75  					// to hit max message size bug
    76  					// Dropping the read write set may cause issues for security and
    77  					// we will need to revist when event security is addressed
    78  					caPayload.Results = nil
    79  					chaincodeActionPayload.Action.ProposalResponsePayload, err = utils.GetBytesProposalResponsePayload(propRespPayload.ProposalHash, caPayload.Response, caPayload.Results, caPayload.Events, caPayload.ChaincodeId)
    80  					if err != nil {
    81  						return fmt.Errorf("error marshalling tx proposal payload for block event: %s", err)
    82  					}
    83  					tx.Actions[0].Payload, err = utils.GetBytesChaincodeActionPayload(chaincodeActionPayload)
    84  					if err != nil {
    85  						return fmt.Errorf("error marshalling tx action payload for block event: %s", err)
    86  					}
    87  					payload.Data, err = utils.GetBytesTransaction(tx)
    88  					if err != nil {
    89  						return fmt.Errorf("error marshalling payload for block event: %s", err)
    90  					}
    91  					env.Payload, err = utils.GetBytesPayload(payload)
    92  					if err != nil {
    93  						return fmt.Errorf("error marshalling tx envelope for block event: %s", err)
    94  					}
    95  					ebytes, err = utils.GetBytesEnvelope(env)
    96  					if err != nil {
    97  						return fmt.Errorf("cannot marshal transaction %s", err)
    98  					}
    99  				}
   100  			}
   101  		}
   102  		bevent.Data.Data = append(bevent.Data.Data, ebytes)
   103  	}
   104  
   105  	logger.Infof("Channel [%s]: Sending event for block number [%d]", channelId, block.Header.Number)
   106  
   107  	return Send(CreateBlockEvent(bevent))
   108  }
   109  
   110  //CreateBlockEvent creates a Event from a Block
   111  func CreateBlockEvent(te *common.Block) *pb.Event {
   112  	return &pb.Event{Event: &pb.Event_Block{Block: te}}
   113  }
   114  
   115  //CreateChaincodeEvent creates a Event from a ChaincodeEvent
   116  func CreateChaincodeEvent(te *pb.ChaincodeEvent) *pb.Event {
   117  	return &pb.Event{Event: &pb.Event_ChaincodeEvent{ChaincodeEvent: te}}
   118  }
   119  
   120  //CreateRejectionEvent creates an Event from TxResults
   121  func CreateRejectionEvent(tx *pb.Transaction, errorMsg string) *pb.Event {
   122  	return &pb.Event{Event: &pb.Event_Rejection{Rejection: &pb.Rejection{Tx: tx, ErrorMsg: errorMsg}}}
   123  }