代码拉取完成,页面将自动刷新
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package lifecycle
import (
"strconv"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/chaincode"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
)
// LegacyMetadataProvider provides metadata for a lscc-defined chaincode
// on a specific channel.
type LegacyMetadataProvider interface {
Metadata(channel string, cc string, collections ...string) *chaincode.Metadata
}
// ChaincodeInfoProvider provides metadata for a _lifecycle-defined
// chaincode on a specific channel
type ChaincodeInfoProvider interface {
// ChaincodeInfo returns the chaincode definition and its install info.
// An error is returned only if either the channel or the chaincode do not exist.
ChaincodeInfo(channelID, name string) (*LocalChaincodeInfo, error)
}
// ChannelPolicyReferenceProvider is used to determine if a set of signature is valid and complies with a policy
type ChannelPolicyReferenceProvider interface {
// NewPolicy creates a new policy based on the policy bytes
NewPolicy(channelID, channelConfigPolicyReference string) (policies.Policy, error)
}
type channelPolicyReferenceProviderImpl struct {
ChannelConfigSource
}
// NewPolicy implements the method of the same name of the ChannelPolicyReferenceProvider interface
func (c *channelPolicyReferenceProviderImpl) NewPolicy(channelID, channelConfigPolicyReference string) (policies.Policy, error) {
cc := c.GetStableChannelConfig(channelID)
pm := cc.PolicyManager()
p, ok := pm.GetPolicy(channelConfigPolicyReference)
if !ok {
return nil, errors.Errorf("could not retrieve policy for reference '%s' on channel '%s'", channelConfigPolicyReference, channelID)
}
return p, nil
}
// NewMetadataProvider returns a new MetadataProvider instance
func NewMetadataProvider(cip ChaincodeInfoProvider, lmp LegacyMetadataProvider, ccs ChannelConfigSource) *MetadataProvider {
return &MetadataProvider{
ChaincodeInfoProvider: cip,
LegacyMetadataProvider: lmp,
ChannelPolicyReferenceProvider: &channelPolicyReferenceProviderImpl{
ChannelConfigSource: ccs,
},
}
}
type MetadataProvider struct {
ChaincodeInfoProvider ChaincodeInfoProvider
LegacyMetadataProvider LegacyMetadataProvider
ChannelPolicyReferenceProvider ChannelPolicyReferenceProvider
}
func (mp *MetadataProvider) toSignaturePolicyEnvelope(channelID string, policyBytes []byte) ([]byte, error) {
p := &peer.ApplicationPolicy{}
err := proto.Unmarshal(policyBytes, p)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal ApplicationPolicy bytes")
}
switch policy := p.Type.(type) {
case *peer.ApplicationPolicy_SignaturePolicy:
return protoutil.MarshalOrPanic(policy.SignaturePolicy), nil
case *peer.ApplicationPolicy_ChannelConfigPolicyReference:
p, err := mp.ChannelPolicyReferenceProvider.NewPolicy(channelID, policy.ChannelConfigPolicyReference)
if err != nil {
return nil, errors.WithMessagef(err, "could not retrieve policy for reference '%s' on channel '%s'", policy.ChannelConfigPolicyReference, channelID)
}
cp, ok := p.(policies.Converter)
if !ok {
return nil, errors.Errorf("policy with reference '%s' on channel '%s' is not convertible to SignaturePolicyEnvelope", policy.ChannelConfigPolicyReference, channelID)
}
spe, err := cp.Convert()
if err != nil {
return nil, errors.WithMessagef(err, "error converting policy with reference '%s' on channel '%s' to SignaturePolicyEnvelope", policy.ChannelConfigPolicyReference, channelID)
}
return proto.Marshal(spe)
default:
// this will only happen if a new policy type is added to the oneof
return nil, errors.Errorf("unsupported policy type %T on channel '%s'", policy, channelID)
}
}
// Metadata implements the metadata retriever support interface for service discovery
func (mp *MetadataProvider) Metadata(channel string, ccName string, collections ...string) *chaincode.Metadata {
ccInfo, err := mp.ChaincodeInfoProvider.ChaincodeInfo(channel, ccName)
if err != nil {
logger.Debugf("chaincode '%s' on channel '%s' not defined in _lifecycle. requesting metadata from lscc", ccName, channel)
// fallback to legacy metadata via cclifecycle
return mp.LegacyMetadataProvider.Metadata(channel, ccName, collections...)
}
spe, err := mp.toSignaturePolicyEnvelope(channel, ccInfo.Definition.ValidationInfo.ValidationParameter)
if err != nil {
logger.Errorf("could not convert policy for chaincode '%s' on channel '%s', err '%s'", ccName, channel, err)
return nil
}
// report the sequence as the version to service discovery since
// the version is no longer required to change when updating any
// part of the chaincode definition
ccMetadata := &chaincode.Metadata{
Name: ccName,
Version: strconv.FormatInt(ccInfo.Definition.Sequence, 10),
Policy: spe,
CollectionPolicies: map[string][]byte{},
CollectionsConfig: ccInfo.Definition.Collections,
}
if ccInfo.Definition.Collections == nil {
return ccMetadata
}
// process any existing collection endorsement policies
for _, collectionName := range collections {
for _, conf := range ccInfo.Definition.Collections.Config {
staticCollConfig := conf.GetStaticCollectionConfig()
if staticCollConfig == nil {
continue
}
if staticCollConfig.Name == collectionName {
if staticCollConfig.EndorsementPolicy != nil {
ep := protoutil.MarshalOrPanic(staticCollConfig.EndorsementPolicy)
cspe, err := mp.toSignaturePolicyEnvelope(channel, ep)
if err != nil {
logger.Errorf("could not convert collection policy for chaincode '%s' collection '%s' on channel '%s', err '%s'", ccName, collectionName, channel, err)
return nil
}
ccMetadata.CollectionPolicies[collectionName] = cspe
}
}
}
}
return ccMetadata
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。