github.com/renegr87/renegr87@v2.1.1+incompatible/core/common/privdata/collection.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package privdata
     8  
     9  import (
    10  	"strings"
    11  
    12  	"github.com/hyperledger/fabric-protos-go/peer"
    13  	pb "github.com/hyperledger/fabric-protos-go/peer"
    14  	"github.com/hyperledger/fabric/core/ledger"
    15  	"github.com/hyperledger/fabric/protoutil"
    16  )
    17  
    18  // Collection defines a common interface for collections
    19  type Collection interface {
    20  	// SetTxContext configures the tx-specific ephemeral collection info, such
    21  	// as txid, nonce, creator -- for future use
    22  	// SetTxContext(parameters ...interface{})
    23  
    24  	// CollectionID returns this collection's ID
    25  	CollectionID() string
    26  
    27  	// GetEndorsementPolicy returns the endorsement policy for validation -- for
    28  	// future use
    29  	// GetEndorsementPolicy() string
    30  
    31  	// MemberOrgs returns the collection's members as MSP IDs. This serves as
    32  	// a human-readable way of quickly identifying who is part of a collection.
    33  	MemberOrgs() map[string]struct{}
    34  }
    35  
    36  // CollectionAccessPolicy encapsulates functions for the access policy of a collection
    37  type CollectionAccessPolicy interface {
    38  	// AccessFilter returns a member filter function for a collection
    39  	AccessFilter() Filter
    40  
    41  	// The minimum number of peers private data will be sent to upon
    42  	// endorsement. The endorsement would fail if dissemination to at least
    43  	// this number of peers is not achieved.
    44  	RequiredPeerCount() int
    45  
    46  	// The maximum number of peers that private data will be sent to
    47  	// upon endorsement. This number has to be bigger than RequiredPeerCount().
    48  	MaximumPeerCount() int
    49  
    50  	// MemberOrgs returns the collection's members as MSP IDs. This serves as
    51  	// a human-readable way of quickly identifying who is part of a collection.
    52  	MemberOrgs() map[string]struct{}
    53  
    54  	// IsMemberOnlyRead returns a true if only collection members can read
    55  	// the private data
    56  	IsMemberOnlyRead() bool
    57  
    58  	// IsMemberOnlyWrite returns a true if only collection members can write
    59  	// the private data
    60  	IsMemberOnlyWrite() bool
    61  }
    62  
    63  // CollectionPersistenceConfigs encapsulates configurations related to persistence of a collection
    64  type CollectionPersistenceConfigs interface {
    65  	// BlockToLive returns the number of blocks after which the collection data expires.
    66  	// For instance if the value is set to 10, a key last modified by block number 100
    67  	// will be purged at block number 111. A zero value is treated same as MaxUint64
    68  	BlockToLive() uint64
    69  }
    70  
    71  // Filter defines a rule that filters peers according to data signed by them.
    72  // The Identity in the SignedData is a SerializedIdentity of a peer.
    73  // The Data is a message the peer signed, and the Signature is the corresponding
    74  // Signature on that Data.
    75  // Returns: True, if the policy holds for the given signed data.
    76  //          False otherwise
    77  type Filter func(protoutil.SignedData) bool
    78  
    79  // CollectionStore provides various APIs to retrieves stored collections and perform
    80  // membership check & read permission check based on the collection's properties.
    81  // TODO: Refactor CollectionStore - FAB-13082
    82  // (1) function such as RetrieveCollection() and RetrieveCollectionConfigPackage() are
    83  //     never used except in mocks and test files.
    84  // (2) in gossip, at least in 7 different places, the following 3 operations
    85  //     are repeated which can be avoided by introducing a API called IsAMemberOf().
    86  //         (i)   retrieves collection access policy by calling RetrieveCollectionAccessPolicy()
    87  //         (ii)  get the access filter func from the collection access policy
    88  //         (iii) create the evaluation policy and check for membership
    89  // (3) we would need a cache in collection store to avoid repeated crypto operation.
    90  //     This would be simple to implement when we introduce IsAMemberOf() APIs.
    91  type CollectionStore interface {
    92  	// RetrieveCollection retrieves the collection in the following way:
    93  	// If the TxID exists in the ledger, the collection that is returned has the
    94  	// latest configuration that was committed into the ledger before this txID
    95  	// was committed.
    96  	// Else - it's the latest configuration for the collection.
    97  	RetrieveCollection(CollectionCriteria) (Collection, error)
    98  
    99  	// RetrieveCollectionAccessPolicy retrieves a collection's access policy
   100  	RetrieveCollectionAccessPolicy(CollectionCriteria) (CollectionAccessPolicy, error)
   101  
   102  	// RetrieveCollectionConfig retrieves a collection's config
   103  	RetrieveCollectionConfig(CollectionCriteria) (*peer.StaticCollectionConfig, error)
   104  
   105  	// RetrieveCollectionConfigPackage retrieves the whole configuration package
   106  	// for the chaincode with the supplied criteria
   107  	RetrieveCollectionConfigPackage(CollectionCriteria) (*peer.CollectionConfigPackage, error)
   108  
   109  	// RetrieveCollectionPersistenceConfigs retrieves the collection's persistence related configurations
   110  	RetrieveCollectionPersistenceConfigs(CollectionCriteria) (CollectionPersistenceConfigs, error)
   111  
   112  	// RetrieveReadWritePermission retrieves the read-write persmission of the creator of the
   113  	// signedProposal for a given collection using collection access policy and flags such as
   114  	// memberOnlyRead & memberOnlyWrite
   115  	RetrieveReadWritePermission(CollectionCriteria, *pb.SignedProposal, ledger.QueryExecutor) (bool, bool, error)
   116  
   117  	CollectionFilter
   118  }
   119  
   120  type CollectionFilter interface {
   121  	// AccessFilter retrieves the collection's filter that matches a given channel and a collectionPolicyConfig
   122  	AccessFilter(channelName string, collectionPolicyConfig *peer.CollectionPolicyConfig) (Filter, error)
   123  }
   124  
   125  const (
   126  	// Collection-specific constants
   127  
   128  	// CollectionSeparator is the separator used to build the KVS
   129  	// key storing the collections of a chaincode; note that we are
   130  	// using as separator a character which is illegal for either the
   131  	// name or the version of a chaincode so there cannot be any
   132  	// collisions when choosing the name
   133  	collectionSeparator = "~"
   134  	// collectionSuffix is the suffix of the KVS key storing the
   135  	// collections of a chaincode
   136  	collectionSuffix = "collection"
   137  )
   138  
   139  // BuildCollectionKVSKey constructs the collection config key for a given chaincode name
   140  func BuildCollectionKVSKey(ccname string) string {
   141  	return ccname + collectionSeparator + collectionSuffix
   142  }
   143  
   144  // IsCollectionConfigKey detects if a key is a collection key
   145  func IsCollectionConfigKey(key string) bool {
   146  	return strings.Contains(key, collectionSeparator)
   147  }
   148  
   149  // GetCCNameFromCollectionConfigKey returns the chaincode name given a collection config key
   150  func GetCCNameFromCollectionConfigKey(key string) string {
   151  	splittedKey := strings.Split(key, collectionSeparator)
   152  	return splittedKey[0]
   153  }