forked from hyperledger/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
/
default_validation.go
118 lines (106 loc) · 3.71 KB
/
default_validation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package builtin
import (
"fmt"
"reflect"
commonerrors "github.com/hyperledger/fabric/common/errors"
"github.com/hyperledger/fabric/core/handlers/validation/api"
. "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/identities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/policies"
. "github.com/hyperledger/fabric/core/handlers/validation/api/state"
"github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)
type DefaultValidationFactory struct {
}
func (*DefaultValidationFactory) New() validation.Plugin {
return &DefaultValidation{}
}
type DefaultValidation struct {
TxValidator TransactionValidator
}
//go:generate mockery -dir . -name TransactionValidator -case underscore -output mocks/
type TransactionValidator interface {
Validate(txData []byte, policy []byte) commonerrors.TxValidationError
}
func (v *DefaultValidation) Validate(block *common.Block, namespace string, txPosition int, actionPosition int, contextData ...validation.ContextDatum) error {
if len(contextData) == 0 {
logger.Panicf("Expected to receive policy bytes in context data")
}
serializedPolicy, isSerializedPolicy := contextData[0].(SerializedPolicy)
if !isSerializedPolicy {
logger.Panicf("Expected to receive a serialized policy in the first context data")
}
if block == nil || block.Data == nil {
return errors.New("empty block")
}
if txPosition >= len(block.Data.Data) {
return errors.Errorf("block has only %d transactions, but requested tx at position %d", len(block.Data.Data), txPosition)
}
if block.Header == nil {
return errors.Errorf("no block header")
}
err := v.TxValidator.Validate(block.Data.Data[txPosition], serializedPolicy.Bytes())
logger.Debugf("block %d, namespace: %s, tx %d validation results is: %v", block.Header.Number, namespace, txPosition, err)
return convertErrorTypeOrPanic(err)
}
func convertErrorTypeOrPanic(err error) error {
if err == nil {
return nil
}
if err, isExecutionError := err.(*commonerrors.VSCCExecutionFailureError); isExecutionError {
return &validation.ExecutionFailureError{
Reason: err.Error(),
}
}
if err, isEndorsementError := err.(*commonerrors.VSCCEndorsementPolicyError); isEndorsementError {
return err
}
logger.Panicf("Programming error: The error is %v, of type %v but expected to be either ExecutionFailureError or VSCCEndorsementPolicyError", err, reflect.TypeOf(err))
return &validation.ExecutionFailureError{Reason: fmt.Sprintf("error of type %v returned from VSCC", reflect.TypeOf(err))}
}
func (v *DefaultValidation) Init(dependencies ...validation.Dependency) error {
var (
d IdentityDeserializer
c Capabilities
sf StateFetcher
pe PolicyEvaluator
)
for _, dep := range dependencies {
if deserializer, isIdentityDeserializer := dep.(IdentityDeserializer); isIdentityDeserializer {
d = deserializer
}
if capabilities, isCapabilities := dep.(Capabilities); isCapabilities {
c = capabilities
}
if stateFetcher, isStateFetcher := dep.(StateFetcher); isStateFetcher {
sf = stateFetcher
}
if policyEvaluator, isPolicyFetcher := dep.(PolicyEvaluator); isPolicyFetcher {
pe = policyEvaluator
}
}
if sf == nil {
return errors.New("stateFetcher not passed in init")
}
if d == nil {
return errors.New("identityDeserializer not passed in init")
}
if c == nil {
return errors.New("capabilities not passed in init")
}
if pe == nil {
return errors.New("policy fetcher not passed in init")
}
v.TxValidator = &ValidatorOneValidSignature{
policyEvaluator: pe,
deserializer: d,
stateFetcher: sf,
capabilities: c,
}
return nil
}