github.com/fnagchunpeng/fabric@v2.1.1+incompatible/core/endorser/pvtrwset_assembler.go (about) 1 /* 2 * 3 * Copyright IBM Corp. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 * / 7 * 8 */ 9 10 package endorser 11 12 import ( 13 "fmt" 14 15 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 16 "github.com/hyperledger/fabric-protos-go/peer" 17 "github.com/hyperledger/fabric-protos-go/transientstore" 18 "github.com/hyperledger/fabric/core/ledger" 19 "github.com/pkg/errors" 20 ) 21 22 // PvtRWSetAssembler assembles private read write set for distribution 23 // augments with additional information if needed 24 type PvtRWSetAssembler interface { 25 // AssemblePvtRWSet prepares TxPvtReadWriteSet for distribution 26 // augmenting it into TxPvtReadWriteSetWithConfigInfo adding 27 // information about collections config available related 28 // to private read-write set 29 AssemblePvtRWSet(channelName string, 30 privData *rwset.TxPvtReadWriteSet, 31 txsim ledger.SimpleQueryExecutor, 32 deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider) ( 33 *transientstore.TxPvtReadWriteSetWithConfigInfo, error, 34 ) 35 } 36 37 // CollectionConfigRetriever encapsulates sub-functionality of ledger.TxSimulator 38 // to abstract minimum required functions set 39 type CollectionConfigRetriever interface { 40 // GetState gets the value for given namespace and key. For a chaincode, the namespace corresponds to the chaincodeId 41 GetState(namespace string, key string) ([]byte, error) 42 } 43 44 // AssemblePvtRWSet prepares TxPvtReadWriteSet for distribution 45 // augmenting it into TxPvtReadWriteSetWithConfigInfo adding 46 // information about collections config available related 47 // to private read-write set 48 func AssemblePvtRWSet(channelName string, 49 privData *rwset.TxPvtReadWriteSet, 50 txsim ledger.SimpleQueryExecutor, 51 deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider) ( 52 *transientstore.TxPvtReadWriteSetWithConfigInfo, error, 53 ) { 54 txPvtRwSetWithConfig := &transientstore.TxPvtReadWriteSetWithConfigInfo{ 55 PvtRwset: privData, 56 CollectionConfigs: make(map[string]*peer.CollectionConfigPackage), 57 } 58 59 for _, pvtRwset := range privData.NsPvtRwset { 60 namespace := pvtRwset.Namespace 61 if _, found := txPvtRwSetWithConfig.CollectionConfigs[namespace]; !found { 62 colCP, err := deployedCCInfoProvider.AllCollectionsConfigPkg(channelName, namespace, txsim) 63 if err != nil { 64 return nil, errors.WithMessagef(err, "error while retrieving collection config for chaincode %#v", namespace) 65 } 66 if colCP == nil { 67 return nil, errors.New(fmt.Sprintf("no collection config for chaincode %#v", namespace)) 68 } 69 txPvtRwSetWithConfig.CollectionConfigs[namespace] = colCP 70 } 71 } 72 trimCollectionConfigs(txPvtRwSetWithConfig) 73 return txPvtRwSetWithConfig, nil 74 } 75 76 func trimCollectionConfigs(pvtData *transientstore.TxPvtReadWriteSetWithConfigInfo) { 77 flags := make(map[string]map[string]struct{}) 78 for _, pvtRWset := range pvtData.PvtRwset.NsPvtRwset { 79 namespace := pvtRWset.Namespace 80 for _, col := range pvtRWset.CollectionPvtRwset { 81 if _, found := flags[namespace]; !found { 82 flags[namespace] = make(map[string]struct{}) 83 } 84 flags[namespace][col.CollectionName] = struct{}{} 85 } 86 } 87 88 filteredConfigs := make(map[string]*peer.CollectionConfigPackage) 89 for namespace, configs := range pvtData.CollectionConfigs { 90 filteredConfigs[namespace] = &peer.CollectionConfigPackage{} 91 for _, conf := range configs.Config { 92 if colConf := conf.GetStaticCollectionConfig(); colConf != nil { 93 if _, found := flags[namespace][colConf.Name]; found { 94 filteredConfigs[namespace].Config = append(filteredConfigs[namespace].Config, conf) 95 } 96 } 97 } 98 } 99 pvtData.CollectionConfigs = filteredConfigs 100 }