github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/scc/lscc/deployedcc_infoprovider.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lscc
     8  
     9  import (
    10  	"github.com/golang/protobuf/proto"
    11  	"github.com/hechain20/hechain/core/common/ccprovider"
    12  	"github.com/hechain20/hechain/core/common/privdata"
    13  	"github.com/hechain20/hechain/core/ledger"
    14  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/rwsetutil"
    15  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    16  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    17  	"github.com/hyperledger/fabric-protos-go/peer"
    18  	"github.com/pkg/errors"
    19  )
    20  
    21  const (
    22  	lsccNamespace = "lscc"
    23  )
    24  
    25  // DeployedCCInfoProvider implements interface ledger.DeployedChaincodeInfoProvider
    26  type DeployedCCInfoProvider struct{}
    27  
    28  // Namespaces implements function in interface ledger.DeployedChaincodeInfoProvider
    29  func (p *DeployedCCInfoProvider) Namespaces() []string {
    30  	return []string{lsccNamespace}
    31  }
    32  
    33  // UpdatedChaincodes implements function in interface ledger.DeployedChaincodeInfoProvider
    34  func (p *DeployedCCInfoProvider) UpdatedChaincodes(stateUpdates map[string][]*kvrwset.KVWrite) ([]*ledger.ChaincodeLifecycleInfo, error) {
    35  	lsccUpdates := stateUpdates[lsccNamespace]
    36  	lifecycleInfo := []*ledger.ChaincodeLifecycleInfo{}
    37  	updatedCCNames := map[string]bool{}
    38  
    39  	for _, kvWrite := range lsccUpdates {
    40  		if rwsetutil.IsKVWriteDelete(kvWrite) {
    41  			// lscc namespace is not expected to have deletes
    42  			continue
    43  		}
    44  		// There are LSCC entries for the chaincode and for the chaincode collections.
    45  		// We can detect collections based on the presence of a CollectionSeparator,
    46  		// which never exists in chaincode names.
    47  		if privdata.IsCollectionConfigKey(kvWrite.Key) {
    48  			ccname := privdata.GetCCNameFromCollectionConfigKey(kvWrite.Key)
    49  			updatedCCNames[ccname] = true
    50  			continue
    51  		}
    52  		updatedCCNames[kvWrite.Key] = true
    53  	}
    54  
    55  	for updatedCCNames := range updatedCCNames {
    56  		lifecycleInfo = append(lifecycleInfo, &ledger.ChaincodeLifecycleInfo{Name: updatedCCNames})
    57  	}
    58  	return lifecycleInfo, nil
    59  }
    60  
    61  func (p *DeployedCCInfoProvider) ImplicitCollections(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) ([]*peer.StaticCollectionConfig, error) {
    62  	return nil, nil
    63  }
    64  
    65  // GenerateImplicitCollectionForOrg is not implemented for legacy chaincodes
    66  func (p *DeployedCCInfoProvider) GenerateImplicitCollectionForOrg(mspid string) *peer.StaticCollectionConfig {
    67  	return nil
    68  }
    69  
    70  // ChaincodeInfo implements function in interface ledger.DeployedChaincodeInfoProvider
    71  func (p *DeployedCCInfoProvider) ChaincodeInfo(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ledger.DeployedChaincodeInfo, error) {
    72  	chaincodeDataBytes, err := qe.GetState(lsccNamespace, chaincodeName)
    73  	if err != nil || chaincodeDataBytes == nil {
    74  		return nil, err
    75  	}
    76  	chaincodeData := &ccprovider.ChaincodeData{}
    77  	if err := proto.Unmarshal(chaincodeDataBytes, chaincodeData); err != nil {
    78  		return nil, errors.Wrap(err, "error unmarshalling chaincode state data")
    79  	}
    80  	collConfigPkg, err := fetchCollConfigPkg(chaincodeName, qe)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	return &ledger.DeployedChaincodeInfo{
    85  		Name:                        chaincodeName,
    86  		Hash:                        chaincodeData.Id,
    87  		Version:                     chaincodeData.Version,
    88  		ExplicitCollectionConfigPkg: collConfigPkg,
    89  		IsLegacy:                    true,
    90  	}, nil
    91  }
    92  
    93  // AllChaincodesInfo returns the mapping of chaincode name to DeployedChaincodeInfo for legacy chaincodes
    94  func (p *DeployedCCInfoProvider) AllChaincodesInfo(channelName string, qe ledger.SimpleQueryExecutor) (map[string]*ledger.DeployedChaincodeInfo, error) {
    95  	iter, err := qe.GetStateRangeScanIterator(lsccNamespace, "", "")
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	defer iter.Close()
   100  
   101  	result := make(map[string]*ledger.DeployedChaincodeInfo)
   102  	for {
   103  		entry, err := iter.Next()
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  		if entry == nil {
   108  			break
   109  		}
   110  
   111  		kv := entry.(*queryresult.KV)
   112  		if !privdata.IsCollectionConfigKey(kv.Key) {
   113  			deployedccInfo, err := p.ChaincodeInfo(channelName, kv.Key, qe)
   114  			if err != nil {
   115  				return nil, err
   116  			}
   117  			result[kv.Key] = deployedccInfo
   118  		}
   119  	}
   120  	return result, nil
   121  }
   122  
   123  // AllCollectionsConfigPkg implements function in interface ledger.DeployedChaincodeInfoProvider
   124  // this implementation returns just the explicit collection config package as the implicit collections
   125  // are not used with legacy lifecycle
   126  func (p *DeployedCCInfoProvider) AllCollectionsConfigPkg(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) {
   127  	return fetchCollConfigPkg(chaincodeName, qe)
   128  }
   129  
   130  // CollectionInfo implements function in interface ledger.DeployedChaincodeInfoProvider
   131  func (p *DeployedCCInfoProvider) CollectionInfo(channelName, chaincodeName, collectionName string, qe ledger.SimpleQueryExecutor) (*peer.StaticCollectionConfig, error) {
   132  	collConfigPkg, err := fetchCollConfigPkg(chaincodeName, qe)
   133  	if err != nil || collConfigPkg == nil {
   134  		return nil, err
   135  	}
   136  	for _, conf := range collConfigPkg.Config {
   137  		staticCollConfig := conf.GetStaticCollectionConfig()
   138  		if staticCollConfig != nil && staticCollConfig.Name == collectionName {
   139  			return staticCollConfig, nil
   140  		}
   141  	}
   142  	return nil, nil
   143  }
   144  
   145  func fetchCollConfigPkg(chaincodeName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) {
   146  	collKey := privdata.BuildCollectionKVSKey(chaincodeName)
   147  	collectionConfigPkgBytes, err := qe.GetState(lsccNamespace, collKey)
   148  	if err != nil || collectionConfigPkgBytes == nil {
   149  		return nil, err
   150  	}
   151  	collectionConfigPkg := &peer.CollectionConfigPackage{}
   152  	if err := proto.Unmarshal(collectionConfigPkgBytes, collectionConfigPkg); err != nil {
   153  		return nil, errors.Wrap(err, "error unmarshalling chaincode collection config pkg")
   154  	}
   155  	return collectionConfigPkg, nil
   156  }