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