github.com/lzy4123/fabric@v2.1.1+incompatible/core/handlers/validation/builtin/default_validation.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package builtin 8 9 import ( 10 "fmt" 11 "reflect" 12 13 "github.com/hyperledger/fabric-protos-go/common" 14 commonerrors "github.com/hyperledger/fabric/common/errors" 15 "github.com/hyperledger/fabric/common/flogging" 16 "github.com/hyperledger/fabric/core/committer/txvalidator/v20/plugindispatcher" 17 validation "github.com/hyperledger/fabric/core/handlers/validation/api" 18 . "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities" 19 . "github.com/hyperledger/fabric/core/handlers/validation/api/identities" 20 . "github.com/hyperledger/fabric/core/handlers/validation/api/policies" 21 . "github.com/hyperledger/fabric/core/handlers/validation/api/state" 22 v12 "github.com/hyperledger/fabric/core/handlers/validation/builtin/v12" 23 v13 "github.com/hyperledger/fabric/core/handlers/validation/builtin/v13" 24 v20 "github.com/hyperledger/fabric/core/handlers/validation/builtin/v20" 25 "github.com/pkg/errors" 26 ) 27 28 var logger = flogging.MustGetLogger("vscc") 29 30 type DefaultValidationFactory struct { 31 } 32 33 func (*DefaultValidationFactory) New() validation.Plugin { 34 return &DefaultValidation{} 35 } 36 37 type DefaultValidation struct { 38 Capabilities Capabilities 39 TxValidatorV1_2 TransactionValidator 40 TxValidatorV1_3 TransactionValidator 41 TxValidatorV2_0 TransactionValidator 42 } 43 44 //go:generate mockery -dir . -name TransactionValidator -case underscore -output mocks/ 45 type TransactionValidator interface { 46 Validate(block *common.Block, namespace string, txPosition int, actionPosition int, policy []byte) commonerrors.TxValidationError 47 } 48 49 func (v *DefaultValidation) Validate(block *common.Block, namespace string, txPosition int, actionPosition int, contextData ...validation.ContextDatum) error { 50 if len(contextData) == 0 { 51 logger.Panicf("Expected to receive policy bytes in context data") 52 } 53 54 serializedPolicy, isSerializedPolicy := contextData[0].(SerializedPolicy) 55 if !isSerializedPolicy { 56 logger.Panicf("Expected to receive a serialized policy in the first context data") 57 } 58 if block == nil || block.Data == nil { 59 return errors.New("empty block") 60 } 61 if txPosition >= len(block.Data.Data) { 62 return errors.Errorf("block has only %d transactions, but requested tx at position %d", len(block.Data.Data), txPosition) 63 } 64 if block.Header == nil { 65 return errors.Errorf("no block header") 66 } 67 68 var err error 69 switch { 70 case v.Capabilities.V2_0Validation(): 71 err = v.TxValidatorV2_0.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes()) 72 73 case v.Capabilities.V1_3Validation(): 74 err = v.TxValidatorV1_3.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes()) 75 76 case v.Capabilities.V1_2Validation(): 77 fallthrough 78 79 default: 80 err = v.TxValidatorV1_2.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes()) 81 } 82 83 logger.Debugf("block %d, namespace: %s, tx %d validation results is: %v", block.Header.Number, namespace, txPosition, err) 84 return convertErrorTypeOrPanic(err) 85 } 86 87 func convertErrorTypeOrPanic(err error) error { 88 if err == nil { 89 return nil 90 } 91 if err, isExecutionError := err.(*commonerrors.VSCCExecutionFailureError); isExecutionError { 92 return &validation.ExecutionFailureError{ 93 Reason: err.Error(), 94 } 95 } 96 if err, isEndorsementError := err.(*commonerrors.VSCCEndorsementPolicyError); isEndorsementError { 97 return err 98 } 99 logger.Panicf("Programming error: The error is %v, of type %v but expected to be either ExecutionFailureError or VSCCEndorsementPolicyError", err, reflect.TypeOf(err)) 100 return &validation.ExecutionFailureError{Reason: fmt.Sprintf("error of type %v returned from VSCC", reflect.TypeOf(err))} 101 } 102 103 func (v *DefaultValidation) Init(dependencies ...validation.Dependency) error { 104 var ( 105 d IdentityDeserializer 106 c Capabilities 107 sf StateFetcher 108 pe PolicyEvaluator 109 cor plugindispatcher.CollectionResources 110 ) 111 for _, dep := range dependencies { 112 if deserializer, isIdentityDeserializer := dep.(IdentityDeserializer); isIdentityDeserializer { 113 d = deserializer 114 } 115 if capabilities, isCapabilities := dep.(Capabilities); isCapabilities { 116 c = capabilities 117 } 118 if stateFetcher, isStateFetcher := dep.(StateFetcher); isStateFetcher { 119 sf = stateFetcher 120 } 121 if policyEvaluator, isPolicyFetcher := dep.(PolicyEvaluator); isPolicyFetcher { 122 pe = policyEvaluator 123 } 124 if collectionResources, isCollectionResources := dep.(plugindispatcher.CollectionResources); isCollectionResources { 125 cor = collectionResources 126 } 127 } 128 if sf == nil { 129 return errors.New("stateFetcher not passed in init") 130 } 131 if d == nil { 132 return errors.New("identityDeserializer not passed in init") 133 } 134 if c == nil { 135 return errors.New("capabilities not passed in init") 136 } 137 if pe == nil { 138 return errors.New("policy fetcher not passed in init") 139 } 140 if cor == nil { 141 return errors.New("collection resources not passed in init") 142 } 143 144 v.Capabilities = c 145 v.TxValidatorV1_2 = v12.New(c, sf, d, pe) 146 v.TxValidatorV1_3 = v13.New(c, sf, d, pe) 147 v.TxValidatorV2_0 = v20.New(c, sf, d, pe, cor) 148 149 return nil 150 }