-
Notifications
You must be signed in to change notification settings - Fork 8.9k
/
implicitmeta.go
101 lines (85 loc) · 2.7 KB
/
implicitmeta.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
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package policies
import (
"bytes"
"fmt"
"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric/protos/common"
"go.uber.org/zap/zapcore"
)
type implicitMetaPolicy struct {
threshold int
subPolicies []Policy
// Only used for logging
managers map[string]*ManagerImpl
subPolicyName string
}
// NewPolicy creates a new policy based on the policy bytes
func newImplicitMetaPolicy(data []byte, managers map[string]*ManagerImpl) (*implicitMetaPolicy, error) {
definition := &cb.ImplicitMetaPolicy{}
if err := proto.Unmarshal(data, definition); err != nil {
return nil, fmt.Errorf("Error unmarshaling to ImplicitMetaPolicy: %s", err)
}
subPolicies := make([]Policy, len(managers))
i := 0
for _, manager := range managers {
subPolicies[i], _ = manager.GetPolicy(definition.SubPolicy)
i++
}
var threshold int
switch definition.Rule {
case cb.ImplicitMetaPolicy_ANY:
threshold = 1
case cb.ImplicitMetaPolicy_ALL:
threshold = len(subPolicies)
case cb.ImplicitMetaPolicy_MAJORITY:
threshold = len(subPolicies)/2 + 1
}
// In the special case that there are no policies, consider 0 to be a majority or any
if len(subPolicies) == 0 {
threshold = 0
}
return &implicitMetaPolicy{
subPolicies: subPolicies,
threshold: threshold,
managers: managers,
subPolicyName: definition.SubPolicy,
}, nil
}
// Evaluate takes a set of SignedData and evaluates whether this set of signatures satisfies the policy
func (imp *implicitMetaPolicy) Evaluate(signatureSet []*cb.SignedData) error {
logger.Debugf("This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign")
remaining := imp.threshold
defer func() {
if remaining != 0 {
// This log message may be large and expensive to construct, so worth checking the log level
if logger.IsEnabledFor(zapcore.DebugLevel) {
var b bytes.Buffer
b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", imp.threshold-remaining, imp.threshold))
for m := range imp.managers {
b.WriteString(m)
b.WriteString("/")
b.WriteString(imp.subPolicyName)
b.WriteString(" ")
}
b.WriteString("]")
logger.Debugf(b.String())
}
}
}()
for _, policy := range imp.subPolicies {
if policy.Evaluate(signatureSet) == nil {
remaining--
if remaining == 0 {
return nil
}
}
}
if remaining == 0 {
return nil
}
return fmt.Errorf("implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied", (imp.threshold - remaining), imp.threshold, imp.subPolicyName)
}