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