diff --git a/pkg/fabric-client/events/eventhub.go b/pkg/fabric-client/events/eventhub.go index b0526352f5..35463d6644 100755 --- a/pkg/fabric-client/events/eventhub.go +++ b/pkg/fabric-client/events/eventhub.go @@ -297,11 +297,16 @@ func (eventHub *EventHub) Recv(msg *pb.Event) (bool, error) { for _, v := range eventHub.getBlockRegistrants() { v(blockEvent.Block) } - for _, tdata := range blockEvent.Block.Data.Data { - if ccEvent, channelID, err := getChainCodeEvent(tdata); err != nil { - logger.Warnf("getChainCodeEvent return error: %v\n", err) - } else if ccEvent != nil { - eventHub.notifyChaincodeRegistrants(channelID, ccEvent, true) + txFilter := util.TxValidationFlags(blockEvent.Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) + for i, tdata := range blockEvent.Block.Data.Data { + if txFilter.IsValid(i) { + if ccEvent, channelID, err := getChainCodeEvent(tdata); err != nil { + logger.Warnf("getChainCodeEvent return error: %v\n", err) + } else if ccEvent != nil { + eventHub.notifyChaincodeRegistrants(channelID, ccEvent, true) + } + } else { + logger.Debugf("received invalid transaction") } } return diff --git a/pkg/fabric-client/events/eventhub_test.go b/pkg/fabric-client/events/eventhub_test.go index b203e1b96c..0f75a9be39 100755 --- a/pkg/fabric-client/events/eventhub_test.go +++ b/pkg/fabric-client/events/eventhub_test.go @@ -215,6 +215,55 @@ func TestChaincodeBlockEvent(t *testing.T) { } } +func TestChaincodeBlockEventWithInvalidTx(t *testing.T) { + channelID := "somechannelid" + ccID := "someccid" + eventName := "someevent" + txID := generateTxID() + + eventHub, clientFactory := createMockedEventHub(t) + if t.Failed() { + return + } + + client := clientFactory.clients[0] + if client == nil { + t.Fatalf("No client") + } + + eventReceived := make(chan *fab.ChaincodeEvent) + + // Register for CC event + registration := eventHub.RegisterChaincodeEvent(ccID, eventName, func(event *fab.ChaincodeEvent) { + eventReceived <- event + }) + + // Publish CC event + go client.MockEvent(&pb.Event{ + Event: (&MockCCBlockEventBuilder{ + CCID: ccID, + EventName: eventName, + ChannelID: channelID, + TxID: txID.ID, + }).BuildWithTxValidationFlag(false), + }) + + // Wait for CC event + var event *fab.ChaincodeEvent + select { + case event = <-eventReceived: + t.Fatalf("CC event is not expected to be triggered for a CC Block Event with invalid Tx flag") + case <-time.After(time.Second * 5): + t.Log("Timeout expected on CC event with Block Event having an invalid Tx flag") + eventHub.UnregisterChaincodeEvent(registration) + } + + // Check CC event + if event != nil { + t.Fatalf("Expecting nil event but got [%s]", event) + } +} + // completionHandler waits for a single event with a timeout type completionHandler struct { completed chan bool diff --git a/pkg/fabric-client/events/eventmocks.go b/pkg/fabric-client/events/eventmocks.go index 98f60890fa..3c9cdb04f3 100644 --- a/pkg/fabric-client/events/eventmocks.go +++ b/pkg/fabric-client/events/eventmocks.go @@ -212,10 +212,15 @@ func (b *MockTxEventBuilder) buildChannelHeader() *common.ChannelHeader { // Build builds a mock chaincode event block func (b *MockCCBlockEventBuilder) Build() *pb.Event_Block { + return b.BuildWithTxValidationFlag(true) +} + +// Build builds a mock chaincode event block with valid/invalid TxValidation Flag (set in the argument) +func (b *MockCCBlockEventBuilder) BuildWithTxValidationFlag(isValid bool) *pb.Event_Block { return &pb.Event_Block{ Block: &common.Block{ Header: &common.BlockHeader{}, - Metadata: b.buildBlockMetadata(), + Metadata: b.buildBlockMetadataWithValidFlag(isValid), Data: &common.BlockData{ Data: [][]byte{internal.MarshalOrPanic(b.buildEnvelope())}, }, @@ -224,11 +229,15 @@ func (b *MockCCBlockEventBuilder) Build() *pb.Event_Block { } func (b *MockCCBlockEventBuilder) buildBlockMetadata() *common.BlockMetadata { + return b.buildBlockMetadataWithValidFlag(true) +} + +func (b *MockCCBlockEventBuilder) buildBlockMetadataWithValidFlag(isValid bool) *common.BlockMetadata { return &common.BlockMetadata{ Metadata: [][]byte{ []byte{}, []byte{}, - b.buildTransactionsFilterMetaDataBytes(), + b.buildTransactionsFilterMetaDataBytesWithValidFlag(isValid), []byte{}, }, } @@ -241,7 +250,15 @@ func (b *MockCCBlockEventBuilder) buildEnvelope() *common.Envelope { } func (b *MockCCBlockEventBuilder) buildTransactionsFilterMetaDataBytes() []byte { - return []byte(ledger_util.TxValidationFlags{uint8(pb.TxValidationCode_VALID)}) + return b.buildTransactionsFilterMetaDataBytesWithValidFlag(true) +} + +func (b *MockCCBlockEventBuilder) buildTransactionsFilterMetaDataBytesWithValidFlag(isValidTx bool) []byte { + if isValidTx { + return []byte(ledger_util.TxValidationFlags{uint8(pb.TxValidationCode_VALID)}) + } + // return transaction with any non valid flag + return []byte(ledger_util.TxValidationFlags{uint8(pb.TxValidationCode_BAD_COMMON_HEADER)}) } func (b *MockCCBlockEventBuilder) buildPayload() *common.Payload {