Fabric 1.0原始碼分析(39) policy(背書策略)

尹成發表於2018-05-21
# Fabric 1.0原始碼筆記 之 policy(背書策略)

## 1、policy概述

policy程式碼分佈在core/policy、core/policyprovider、common/policies目錄下。目錄結構如下:

* core/policy/policy.go,PolicyChecker介面定義及實現、PolicyCheckerFactory介面定義。
* core/policyprovider/provider.go,PolicyChecker工廠預設實現。
* common/policies目錄
    * policy.go,ChannelPolicyManagerGetter介面及實現。
    * implicitmeta_util.go,通道策略工具函式。

## 2、PolicyChecker工廠

### 2.1、PolicyCheckerFactory介面定義

```go
type PolicyCheckerFactory interface {
    NewPolicyChecker() PolicyChecker //構造PolicyChecker例項
}

var pcFactory PolicyCheckerFactory //全域性變數定義及賦值函式
func RegisterPolicyCheckerFactory(f PolicyCheckerFactory) {
    pcFactory = f
}
//程式碼在core/policy/policy.go
```

### 2.2、PolicyCheckerFactory介面預設實現

```go
type defaultFactory struct{}

//構造policy.PolicyChecker
func (f *defaultFactory) NewPolicyChecker() policy.PolicyChecker {
    return policy.NewPolicyChecker(
        peer.NewChannelPolicyManagerGetter(), //&channelPolicyManagerGetter{}
        mgmt.GetLocalMSP(),
        mgmt.NewLocalMSPPrincipalGetter(),
    )
}

//獲取policy.PolicyChecker,即呼叫policy.GetPolicyChecker()
func GetPolicyChecker() policy.PolicyChecker

func init() { //初始化全域性變數pcFactory
    policy.RegisterPolicyCheckerFactory(&defaultFactory{})
}
```

## 3、PolicyChecker介面定義及實現

### 3.1、PolicyChecker介面定義

```go
type PolicyChecker interface {
    CheckPolicy(channelID, policyName string, signedProp *pb.SignedProposal) error
    CheckPolicyBySignedData(channelID, policyName string, sd []*common.SignedData) error
    CheckPolicyNoChannel(policyName string, signedProp *pb.SignedProposal) error
}
//程式碼在core/policy/policy.go
```

### 3.2、PolicyChecker介面實現

PolicyChecker介面實現,即policyChecker結構體及方法。

```go
type policyChecker struct {
    channelPolicyManagerGetter policies.ChannelPolicyManagerGetter //通道策略管理器
    localMSP msp.IdentityDeserializer //身份
    principalGetter mgmt.MSPPrincipalGetter //委託人
}

//構造policyChecker
func NewPolicyChecker(channelPolicyManagerGetter policies.ChannelPolicyManagerGetter, localMSP msp.IdentityDeserializer, principalGetter mgmt.MSPPrincipalGetter) PolicyChecker
//檢查簽名提案是否符合通道策略
func (p *policyChecker) CheckPolicy(channelID, policyName string, signedProp *pb.SignedProposal) error
func (p *policyChecker) CheckPolicyNoChannel(policyName string, signedProp *pb.SignedProposal) error
//檢查簽名資料是否符合通道策略,獲取策略並調取policy.Evaluate(sd)
func (p *policyChecker) CheckPolicyBySignedData(channelID, policyName string, sd []*common.SignedData) error
func GetPolicyChecker() PolicyChecker //pcFactory.NewPolicyChecker()
//程式碼在core/policy/policy.go
```

func (p *policyChecker) CheckPolicy(channelID, policyName string, signedProp *pb.SignedProposal) error程式碼如下:

```go
func (p *policyChecker) CheckPolicy(channelID, policyName string, signedProp *pb.SignedProposal) error {
    if channelID == "" { //channelID為空,調取CheckPolicyNoChannel()
        return p.CheckPolicyNoChannel(policyName, signedProp)
    }
    
    policyManager, _ := p.channelPolicyManagerGetter.Manager(channelID)
    proposal, err := utils.GetProposal(signedProp.ProposalBytes) //獲取proposal
    header, err := utils.GetHeader(proposal.Header)
    shdr, err := utils.GetSignatureHeader(header.SignatureHeader) //SignatureHeader
    sd := []*common.SignedData{&common.SignedData{
        Data: signedProp.ProposalBytes,
        Identity: shdr.Creator,
        Signature: signedProp.Signature,
    }}
    return p.CheckPolicyBySignedData(channelID, policyName, sd)
}
//程式碼在core/policy/policy.go
```

## 4、ChannelPolicyManagerGetter介面及實現

### 4.1、ChannelPolicyManagerGetter介面定義

```go
type ChannelPolicyManagerGetter interface {
    Manager(channelID string) (Manager, bool)
}
//程式碼在common/policies/policy.go
```

### 4.2、ChannelPolicyManagerGetter介面實現

ChannelPolicyManagerGetter介面實現,即ManagerImpl結構體及方法。

```go
type ManagerImpl struct {
    parent *ManagerImpl
    basePath string
    fqPrefix string
    providers map[int32]Provider //type Provider interface
    config *policyConfig //type policyConfig struct
    pendingConfig map[interface{}]*policyConfig //type policyConfig struct
    pendingLock sync.RWMutex
    SuppressSanityLogMessages bool
}

type Provider interface {
    NewPolicy(data []byte) (Policy, proto.Message, error)
}

type policyConfig struct {
    policies map[string]Policy //type Policy interface
    managers map[string]*ManagerImpl
    imps []*implicitMetaPolicy
}

type Policy interface {
    //對給定的簽名資料,按規則檢驗確認是否符合約定的條件
    Evaluate(signatureSet []*cb.SignedData) error
}

//構造ManagerImpl
func NewManagerImpl(basePath string, providers map[int32]Provider) *ManagerImpl
//獲取pm.basePath
func (pm *ManagerImpl) BasePath() string
//獲取pm.config.policies,即map[string]Policy中Key列表
func (pm *ManagerImpl) PolicyNames() []string
//獲取指定路徑的子管理器
func (pm *ManagerImpl) Manager(path []string) (Manager, bool)
//獲取pm.config.policies[relpath]
//獲取Policy
func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool)
func (pm *ManagerImpl) BeginPolicyProposals(tx interface{}, groups []string) ([]Proposer, error)
func (pm *ManagerImpl) RollbackProposals(tx interface{})
func (pm *ManagerImpl) PreCommit(tx interface{}) error
func (pm *ManagerImpl) CommitProposals(tx interface{})
func (pm *ManagerImpl) ProposePolicy(tx interface{}, key string, configPolicy *cb.ConfigPolicy) (proto.Message, error)
//程式碼在common/policies/policy.go
```

```go
type implicitMetaPolicy struct {
    conf *cb.ImplicitMetaPolicy
    threshold int
    subPolicies []Policy
}
//程式碼在common/policies/implicitmeta.go
```

## 5、通道策略工具函式

```go
type ImplicitMetaPolicy_Rule int32
const (
    ImplicitMetaPolicy_ANY ImplicitMetaPolicy_Rule = 0 //任意
    ImplicitMetaPolicy_ALL ImplicitMetaPolicy_Rule = 1 //所有
    ImplicitMetaPolicy_MAJORITY ImplicitMetaPolicy_Rule = 2 //大多數
)
//程式碼在protos/common/policies.pb.go
```

```go
//構造cb.Policy
func ImplicitMetaPolicyWithSubPolicy(subPolicyName string, rule cb.ImplicitMetaPolicy_Rule) *cb.ConfigPolicy
func TemplateImplicitMetaPolicyWithSubPolicy(path []string, policyName string, subPolicyName string, rule cb.ImplicitMetaPolicy_Rule) *cb.ConfigGroup

//調取TemplateImplicitMetaPolicyWithSubPolicy(path, policyName, policyName, rule)
func TemplateImplicitMetaPolicy(path []string, policyName string, rule cb.ImplicitMetaPolicy_Rule) *cb.ConfigGroup

//任意,TemplateImplicitMetaPolicy(path, policyName, cb.ImplicitMetaPolicy_ANY)
func TemplateImplicitMetaAnyPolicy(path []string, policyName string) *cb.ConfigGroup

//所有,TemplateImplicitMetaPolicy(path, policyName, cb.ImplicitMetaPolicy_ALL)
func TemplateImplicitMetaAllPolicy(path []string, policyName string) *cb.ConfigGroup

//大多數,TemplateImplicitMetaPolicy(path, policyName, cb.ImplicitMetaPolicy_MAJORITY)
func TemplateImplicitMetaMajorityPolicy(path []string, policyName string) *cb.ConfigGroup
//程式碼在common/policies/implicitmeta_util.go
```





網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN






網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN

相關文章