github.com/anjalikarhana/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  }