diff --git a/orderer/consensus/smartbft/chain.go b/orderer/consensus/smartbft/chain.go index 1f87bb0ae2d..9f006157258 100644 --- a/orderer/consensus/smartbft/chain.go +++ b/orderer/consensus/smartbft/chain.go @@ -107,14 +107,15 @@ func NewChain( metricsWalBFT *wal.Metrics, bccsp bccsp.BCCSP, ) (*BFTChain, error) { + logger := flogging.MustGetLogger("orderer.consensus.smartbft.chain").With(zap.String("channel", support.ChannelID())) + requestInspector := &RequestInspector{ ValidateIdentityStructure: func(_ *msp.SerializedIdentity) error { return nil }, + Logger: logger, } - logger := flogging.MustGetLogger("orderer.consensus.smartbft.chain").With(zap.String("channel", support.ChannelID())) - c := &BFTChain{ RuntimeConfig: &atomic.Value{}, Channel: support.ChannelID(), diff --git a/orderer/consensus/smartbft/util.go b/orderer/consensus/smartbft/util.go index e2bf9779c69..fed5dbe258b 100644 --- a/orderer/consensus/smartbft/util.go +++ b/orderer/consensus/smartbft/util.go @@ -254,6 +254,7 @@ type request struct { // RequestInspector inspects incomming requests and validates serialized identity type RequestInspector struct { ValidateIdentityStructure func(identity *msp.SerializedIdentity) error + Logger *flogging.FabricLogger } func (ri *RequestInspector) requestIDFromSigHeader(sigHdr *cb.SignatureHeader) (types.RequestInfo, error) { @@ -277,12 +278,49 @@ func (ri *RequestInspector) requestIDFromSigHeader(sigHdr *cb.SignatureHeader) ( }, nil } +func (ri *RequestInspector) requestIDFromEnvelope(envelope *cb.Envelope) (types.RequestInfo, error) { + data, err := proto.Marshal(envelope) + if err != nil { + return types.RequestInfo{}, err + } + + req, err := ri.unwrapReqFromEnvelop(envelope) + if err != nil { + return types.RequestInfo{}, err + } + + txID := sha256.Sum256(data) + clientID := sha256.Sum256(req.sigHdr.Creator) + return types.RequestInfo{ + ID: hex.EncodeToString(txID[:]), + ClientID: hex.EncodeToString(clientID[:]), + }, nil +} + // RequestID unwraps the request info from the raw request func (ri *RequestInspector) RequestID(rawReq []byte) types.RequestInfo { req, err := ri.unwrapReq(rawReq) if err != nil { return types.RequestInfo{} } + + if req.chHdr.Type == int32(cb.HeaderType_CONFIG) { + configEnvelope := &cb.ConfigEnvelope{} + _, err = protoutil.UnmarshalEnvelopeOfType(req.envelope, cb.HeaderType_CONFIG, configEnvelope) + if err != nil { + ri.Logger.Errorf("can't get config envelope: %s", err.Error()) + return types.RequestInfo{} + } + + reqInfo, err := ri.requestIDFromEnvelope(configEnvelope.LastUpdate) + if err != nil { + ri.Logger.Errorf("can't get request ID: %s", err.Error()) + return types.RequestInfo{} + } + + return reqInfo + } + reqInfo, err := ri.requestIDFromSigHeader(req.sigHdr) if err != nil { return types.RequestInfo{} @@ -290,11 +328,24 @@ func (ri *RequestInspector) RequestID(rawReq []byte) types.RequestInfo { return reqInfo } +func (ri *RequestInspector) isEmpty(req types.RequestInfo) bool { + if len(req.ID) == 0 && len(req.ClientID) == 0 { + return true + } + + return false +} + func (ri *RequestInspector) unwrapReq(req []byte) (*request, error) { envelope, err := protoutil.UnmarshalEnvelope(req) if err != nil { return nil, err } + + return ri.unwrapReqFromEnvelop(envelope) +} + +func (ri *RequestInspector) unwrapReqFromEnvelop(envelope *cb.Envelope) (*request, error) { payload := &cb.Payload{} if err := proto.Unmarshal(envelope.Payload, payload); err != nil { return nil, errors.Wrap(err, "failed unmarshaling payload") diff --git a/orderer/consensus/smartbft/verifier.go b/orderer/consensus/smartbft/verifier.go index 70c2d662cfb..e2fec3f5169 100644 --- a/orderer/consensus/smartbft/verifier.go +++ b/orderer/consensus/smartbft/verifier.go @@ -190,11 +190,18 @@ func (v *Verifier) verifyRequest(rawRequest []byte, noConfigAllowed bool) (types } if req.chHdr.Type == int32(cb.HeaderType_CONFIG) { - err := v.ConfigValidator.ValidateConfig(req.envelope) + err = v.ConfigValidator.ValidateConfig(req.envelope) if err != nil { v.Logger.Errorf("Error verifying config update: %v", err) return types.RequestInfo{}, err } + + reqID := v.ReqInspector.RequestID(rawRequest) + if v.ReqInspector.isEmpty(reqID) { + return types.RequestInfo{}, errors.Errorf("request id is empty") + } + + return reqID, nil } return v.ReqInspector.requestIDFromSigHeader(req.sigHdr) diff --git a/orderer/consensus/smartbft/verifier_test.go b/orderer/consensus/smartbft/verifier_test.go index e4da1686363..09bccbd2c04 100644 --- a/orderer/consensus/smartbft/verifier_test.go +++ b/orderer/consensus/smartbft/verifier_test.go @@ -111,6 +111,7 @@ func TestVerifyConsenterSig(t *testing.T) { ValidateIdentityStructure: func(_ *msp.SerializedIdentity) error { return nil }, + Logger: logger, } cv := &mocks.ConsenterVerifier{} @@ -415,6 +416,7 @@ func TestVerifyProposal(t *testing.T) { ValidateIdentityStructure: func(_ *msp.SerializedIdentity) error { return nil }, + Logger: logger, } lastHash := hex.EncodeToString(protoutil.BlockHeaderHash(lastBlock.Header))