github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/core/scc/lscc/deployedcc_infoprovider.go (about) 1 /* 2 Copyright IBM Corp. 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/hyperledger/fabric-protos-go/ledger/rwset/kvrwset" 12 "github.com/hyperledger/fabric-protos-go/peer" 13 "github.com/hyperledger/fabric/core/common/ccprovider" 14 "github.com/hyperledger/fabric/core/common/privdata" 15 "github.com/hyperledger/fabric/core/ledger" 16 "github.com/pkg/errors" 17 ) 18 19 const ( 20 lsccNamespace = "lscc" 21 ) 22 23 // DeployedCCInfoProvider implements interface ledger.DeployedChaincodeInfoProvider 24 type DeployedCCInfoProvider struct { 25 } 26 27 // Namespaces implements function in interface ledger.DeployedChaincodeInfoProvider 28 func (p *DeployedCCInfoProvider) Namespaces() []string { 29 return []string{lsccNamespace} 30 } 31 32 // UpdatedChaincodes implements function in interface ledger.DeployedChaincodeInfoProvider 33 func (p *DeployedCCInfoProvider) UpdatedChaincodes(stateUpdates map[string][]*kvrwset.KVWrite) ([]*ledger.ChaincodeLifecycleInfo, error) { 34 lsccUpdates := stateUpdates[lsccNamespace] 35 lifecycleInfo := []*ledger.ChaincodeLifecycleInfo{} 36 updatedCCNames := map[string]bool{} 37 38 for _, kvWrite := range lsccUpdates { 39 if kvWrite.IsDelete { 40 // lscc namespace is not expected to have deletes 41 continue 42 } 43 // There are LSCC entries for the chaincode and for the chaincode collections. 44 // We can detect collections based on the presence of a CollectionSeparator, 45 // which never exists in chaincode names. 46 if privdata.IsCollectionConfigKey(kvWrite.Key) { 47 ccname := privdata.GetCCNameFromCollectionConfigKey(kvWrite.Key) 48 updatedCCNames[ccname] = true 49 continue 50 } 51 updatedCCNames[kvWrite.Key] = true 52 } 53 54 for updatedCCNames := range updatedCCNames { 55 lifecycleInfo = append(lifecycleInfo, &ledger.ChaincodeLifecycleInfo{Name: updatedCCNames}) 56 } 57 return lifecycleInfo, nil 58 } 59 60 func (p *DeployedCCInfoProvider) ImplicitCollections(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) ([]*peer.StaticCollectionConfig, error) { 61 return nil, nil 62 } 63 64 // ChaincodeInfo implements function in interface ledger.DeployedChaincodeInfoProvider 65 func (p *DeployedCCInfoProvider) ChaincodeInfo(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ledger.DeployedChaincodeInfo, error) { 66 chaincodeDataBytes, err := qe.GetState(lsccNamespace, chaincodeName) 67 if err != nil || chaincodeDataBytes == nil { 68 return nil, err 69 } 70 chaincodeData := &ccprovider.ChaincodeData{} 71 if err := proto.Unmarshal(chaincodeDataBytes, chaincodeData); err != nil { 72 return nil, errors.Wrap(err, "error unmarshalling chaincode state data") 73 } 74 collConfigPkg, err := fetchCollConfigPkg(chaincodeName, qe) 75 if err != nil { 76 return nil, err 77 } 78 return &ledger.DeployedChaincodeInfo{ 79 Name: chaincodeName, 80 Hash: chaincodeData.Id, 81 Version: chaincodeData.Version, 82 ExplicitCollectionConfigPkg: collConfigPkg, 83 IsLegacy: true, 84 }, nil 85 } 86 87 // AllCollectionsConfigPkg implements function in interface ledger.DeployedChaincodeInfoProvider 88 // this implementation returns just the explicit collection config package as the implicit collections 89 // are not used with legacy lifecycle 90 func (p *DeployedCCInfoProvider) AllCollectionsConfigPkg(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) { 91 return fetchCollConfigPkg(chaincodeName, qe) 92 } 93 94 // CollectionInfo implements function in interface ledger.DeployedChaincodeInfoProvider 95 func (p *DeployedCCInfoProvider) CollectionInfo(channelName, chaincodeName, collectionName string, qe ledger.SimpleQueryExecutor) (*peer.StaticCollectionConfig, error) { 96 collConfigPkg, err := fetchCollConfigPkg(chaincodeName, qe) 97 if err != nil || collConfigPkg == nil { 98 return nil, err 99 } 100 for _, conf := range collConfigPkg.Config { 101 staticCollConfig := conf.GetStaticCollectionConfig() 102 if staticCollConfig != nil && staticCollConfig.Name == collectionName { 103 return staticCollConfig, nil 104 } 105 } 106 return nil, nil 107 } 108 109 func fetchCollConfigPkg(chaincodeName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) { 110 collKey := privdata.BuildCollectionKVSKey(chaincodeName) 111 collectionConfigPkgBytes, err := qe.GetState(lsccNamespace, collKey) 112 if err != nil || collectionConfigPkgBytes == nil { 113 return nil, err 114 } 115 collectionConfigPkg := &peer.CollectionConfigPackage{} 116 if err := proto.Unmarshal(collectionConfigPkgBytes, collectionConfigPkg); err != nil { 117 return nil, errors.Wrap(err, "error unmarshalling chaincode collection config pkg") 118 } 119 return collectionConfigPkg, nil 120 }