1 Star 0 Fork 0

妥協/fabric

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
convert.go 3.72 KB
一键复制 编辑 原始数据 按行查看 历史
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package policies
import (
"fmt"
cb "github.com/hyperledger/fabric-protos-go/common"
"github.com/pkg/errors"
)
// remap explores the policy tree depth first and remaps the "signed by"
// entries according to the remapping rules; a "signed by" rule requires
// a signature from a principal given its position in the array of principals;
// the idRemap map tells us how to remap these integers given that merging two
// policies implies deduplicating their principals
func remap(sp *cb.SignaturePolicy, idRemap map[int]int) *cb.SignaturePolicy {
switch t := sp.Type.(type) {
case *cb.SignaturePolicy_NOutOf_:
rules := []*cb.SignaturePolicy{}
for _, rule := range t.NOutOf.Rules {
// here we call remap again - we're doing a
// depth-first traversal of this policy tree
rules = append(rules, remap(rule, idRemap))
}
return &cb.SignaturePolicy{
Type: &cb.SignaturePolicy_NOutOf_{
NOutOf: &cb.SignaturePolicy_NOutOf{
N: t.NOutOf.N,
Rules: rules,
},
},
}
case *cb.SignaturePolicy_SignedBy:
// here we do the actual remapping because we have
// the "signed by" rule, whose reference to the
// principal we need to remap
newID, in := idRemap[int(t.SignedBy)]
if !in {
panic("programming error")
}
return &cb.SignaturePolicy{
Type: &cb.SignaturePolicy_SignedBy{
SignedBy: int32(newID),
},
}
default:
panic(fmt.Sprintf("invalid policy type %T", t))
}
}
// merge integrates the policy `that` into the
// policy `this`. The first argument is changed
// whereas the second isn't
func merge(this *cb.SignaturePolicyEnvelope, that *cb.SignaturePolicyEnvelope) {
// at first we build a map of principals in `this`
IDs := this.Identities
idMap := map[string]int{}
for i, id := range this.Identities {
str := id.PrincipalClassification.String() + string(id.Principal)
idMap[str] = i
}
// then we traverse each of the principals in `that`,
// deduplicate them against the ones in `this` and
// create remapping rules so that if `that` references
// a duplicate policy in this, the merged policy will
// ensure that the references in `that` point to the
// correct principal
idRemap := map[int]int{}
for i, id := range that.Identities {
str := id.PrincipalClassification.String() + string(id.Principal)
if j, in := idMap[str]; in {
idRemap[i] = j
} else {
idRemap[i] = len(IDs)
idMap[str] = len(IDs)
IDs = append(IDs, id)
}
}
this.Identities = IDs
newEntry := remap(that.Rule, idRemap)
existingRules := this.Rule.Type.(*cb.SignaturePolicy_NOutOf_).NOutOf.Rules
this.Rule.Type.(*cb.SignaturePolicy_NOutOf_).NOutOf.Rules = append(existingRules, newEntry)
}
// Convert implements the policies.Converter function to
// convert an implicit meta policy into a signature policy envelope.
func (p *ImplicitMetaPolicy) Convert() (*cb.SignaturePolicyEnvelope, error) {
converted := &cb.SignaturePolicyEnvelope{
Version: 0,
Rule: &cb.SignaturePolicy{
Type: &cb.SignaturePolicy_NOutOf_{
NOutOf: &cb.SignaturePolicy_NOutOf{
N: int32(p.Threshold),
},
},
},
}
// the conversion approach for an implicit meta
// policy is to convert each of the subpolicies,
// merge it with the previous one and return the
// merged policy
for i, subPolicy := range p.SubPolicies {
convertibleSubpolicy, ok := subPolicy.(Converter)
if !ok {
return nil, errors.Errorf("subpolicy number %d type %T of policy %s is not convertible", i, subPolicy, p.SubPolicyName)
}
spe, err := convertibleSubpolicy.Convert()
if err != nil {
return nil, errors.WithMessagef(err, "failed to convert subpolicy number %d of policy %s", i, p.SubPolicyName)
}
merge(converted, spe)
}
return converted, nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/liurenhao/fabric.git
git@gitee.com:liurenhao/fabric.git
liurenhao
fabric
fabric
v2.0.0

搜索帮助