github.com/defanghe/fabric@v2.1.1+incompatible/discovery/support/chaincode/support.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package chaincode 8 9 import ( 10 "github.com/golang/protobuf/proto" 11 common2 "github.com/hyperledger/fabric-protos-go/common" 12 "github.com/hyperledger/fabric/common/chaincode" 13 "github.com/hyperledger/fabric/common/flogging" 14 "github.com/hyperledger/fabric/common/policies" 15 "github.com/hyperledger/fabric/common/policies/inquire" 16 ) 17 18 var logger = flogging.MustGetLogger("discovery.DiscoverySupport") 19 20 type MetadataRetriever interface { 21 Metadata(channel string, cc string, collections ...string) *chaincode.Metadata 22 } 23 24 // DiscoverySupport implements support that is used for service discovery 25 // that is related to chaincode 26 type DiscoverySupport struct { 27 ci MetadataRetriever 28 } 29 30 // NewDiscoverySupport creates a new DiscoverySupport 31 func NewDiscoverySupport(ci MetadataRetriever) *DiscoverySupport { 32 s := &DiscoverySupport{ 33 ci: ci, 34 } 35 return s 36 } 37 38 func (s *DiscoverySupport) PoliciesByChaincode(channel string, cc string, collections ...string) []policies.InquireablePolicy { 39 chaincodeData := s.ci.Metadata(channel, cc, collections...) 40 if chaincodeData == nil { 41 logger.Infof("Chaincode %s wasn't found", cc) 42 return nil 43 } 44 45 // chaincode policy 46 pol := &common2.SignaturePolicyEnvelope{} 47 if err := proto.Unmarshal(chaincodeData.Policy, pol); err != nil { 48 logger.Errorf("Failed unmarshaling policy for chaincode '%s': %s", cc, err) 49 return nil 50 } 51 if len(pol.Identities) == 0 || pol.Rule == nil { 52 logger.Errorf("Invalid policy, either Identities(%v) or Rule(%v) are empty", pol.Identities, pol.Rule) 53 return nil 54 } 55 // chaincodeData.CollectionPolicies will be nil when using legacy lifecycle (lscc) 56 // because collection endorsement policies are not supported in lscc 57 chaincodePolicy := inquire.NewInquireableSignaturePolicy(pol) 58 if chaincodeData.CollectionPolicies == nil || len(collections) == 0 { 59 return []policies.InquireablePolicy{chaincodePolicy} 60 } 61 62 // process any collection policies 63 inquireablePolicies := make(map[string]struct{}) 64 uniqueInquireablePolicies := []policies.InquireablePolicy{} 65 66 for _, collectionName := range collections { 67 // default to the chaincode policy if the collection policy doesn't exist 68 if _, collectionPolicyExists := chaincodeData.CollectionPolicies[collectionName]; !collectionPolicyExists { 69 if _, exists := inquireablePolicies[string(chaincodeData.Policy)]; !exists { 70 uniqueInquireablePolicies = append(uniqueInquireablePolicies, chaincodePolicy) 71 inquireablePolicies[string(chaincodeData.Policy)] = struct{}{} 72 } 73 continue 74 } 75 76 collectionPolicy := chaincodeData.CollectionPolicies[collectionName] 77 pol := &common2.SignaturePolicyEnvelope{} 78 if err := proto.Unmarshal(collectionPolicy, pol); err != nil { 79 logger.Errorf("Failed unmarshaling collection policy for chaincode '%s' collection '%s': %s", cc, collectionName, err) 80 return nil 81 } 82 if len(pol.Identities) == 0 || pol.Rule == nil { 83 logger.Errorf("Invalid collection policy, either Identities(%v) or Rule(%v) are empty", pol.Identities, pol.Rule) 84 return nil 85 } 86 // only add to uniqueInquireablePolicies if the policy doesn't already exist there 87 // this prevents duplicate inquireablePolicies from being returned 88 if _, exists := inquireablePolicies[string(collectionPolicy)]; !exists { 89 uniqueInquireablePolicies = append(uniqueInquireablePolicies, inquire.NewInquireableSignaturePolicy(pol)) 90 inquireablePolicies[string(collectionPolicy)] = struct{}{} 91 } 92 } 93 94 return uniqueInquireablePolicies 95 }