github.com/true-sqn/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  }