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  }