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  }