github.com/true-sqn/fabric@v2.1.1+incompatible/core/tx/processor_factory.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package tx 8 9 import ( 10 "github.com/pkg/errors" 11 12 "github.com/hyperledger/fabric-protos-go/common" 13 "github.com/hyperledger/fabric-protos-go/peer" 14 "github.com/hyperledger/fabric/pkg/tx" 15 "github.com/hyperledger/fabric/protoutil" 16 ) 17 18 // ProcessorFactory maintains a mapping between transaction type and associate `ProcessorCreator` 19 type ProcessorFactory struct { 20 ProcessorCreators map[common.HeaderType]tx.ProcessorCreator 21 } 22 23 // CreateProcessor unmarshals bytes into an Envelope and invokes a ProcessorCreators corresponding to the transaction type 24 // present in the ChannelHeader. If successful, this function returns the Processor and simulatedRWSet created by the ProcessorCreators. 25 // However, if this function encounters and error in detecting the transaction type or a 26 // ProcessorCreators has not been registered for the transaction type, the error returned would be of type 27 // `tx.InvalidErr` which implies that the transaction is found to be invalid at the very beginning stage 28 func (f *ProcessorFactory) CreateProcessor(txEnvelopeBytes []byte) (processor tx.Processor, simulatedRWSet [][]byte, err error) { 29 txEnv, err := validateProtoAndConstructTxEnv(txEnvelopeBytes) 30 if err != nil { 31 return nil, nil, err 32 } 33 c, ok := f.ProcessorCreators[common.HeaderType(txEnv.ChannelHeader.Type)] 34 if !ok { 35 return nil, nil, &tx.InvalidErr{ 36 ActualErr: errors.Errorf("invalid transaction type %d", txEnv.ChannelHeader.Type), 37 ValidationCode: peer.TxValidationCode_UNKNOWN_TX_TYPE, 38 } 39 } 40 return c.NewProcessor(txEnv) 41 } 42 43 // validateProtoAndConstructTxEnv attemps to unmarshal the bytes and prepare an instance of struct tx.Envelope 44 // It returns an error of type `tx.InvalidErr` if the proto message is found to be invalid 45 func validateProtoAndConstructTxEnv(txEnvelopeBytes []byte) (*tx.Envelope, error) { 46 txenv, err := protoutil.UnmarshalEnvelope(txEnvelopeBytes) 47 if err != nil { 48 return nil, &tx.InvalidErr{ 49 ActualErr: err, 50 ValidationCode: peer.TxValidationCode_INVALID_OTHER_REASON, 51 } 52 } 53 54 if len(txenv.Payload) == 0 { 55 return nil, &tx.InvalidErr{ 56 ActualErr: errors.New("nil envelope payload"), 57 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 58 } 59 } 60 61 payload, err := protoutil.UnmarshalPayload(txenv.Payload) 62 if err != nil { 63 return nil, &tx.InvalidErr{ 64 ActualErr: err, 65 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 66 } 67 } 68 69 if payload.Header == nil { 70 return nil, &tx.InvalidErr{ 71 ActualErr: errors.New("nil payload header"), 72 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 73 } 74 } 75 76 if len(payload.Header.ChannelHeader) == 0 { 77 return nil, &tx.InvalidErr{ 78 ActualErr: errors.New("nil payload channel header"), 79 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 80 } 81 } 82 83 chdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader) 84 if err != nil { 85 return nil, &tx.InvalidErr{ 86 ActualErr: err, 87 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 88 } 89 } 90 91 if len(payload.Header.SignatureHeader) == 0 { 92 return nil, &tx.InvalidErr{ 93 ActualErr: errors.New("nil payload signature header"), 94 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 95 } 96 } 97 98 shdr, err := protoutil.UnmarshalSignatureHeader(payload.Header.SignatureHeader) 99 if err != nil { 100 return nil, &tx.InvalidErr{ 101 ActualErr: err, 102 ValidationCode: peer.TxValidationCode_BAD_PAYLOAD, 103 } 104 } 105 106 //other checks over shdr.Nonce, shdr.Creator can be added if universally applicable 107 108 //what TODO in legacy validation: 109 // validate cHdr.ChainID ? 110 // validate epoch in cHdr.Epoch? 111 112 return &tx.Envelope{ 113 SignedBytes: txenv.Payload, 114 Signature: txenv.Signature, 115 Data: payload.Data, 116 ChannelHeaderBytes: payload.Header.ChannelHeader, 117 SignatureHeaderBytes: payload.Header.SignatureHeader, 118 ChannelHeader: chdr, 119 SignatureHeader: shdr, 120 }, 121 nil 122 }