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 }