Skip to content

Commit

Permalink
[FAB-5868] Specify collection interface
Browse files Browse the repository at this point in the history
This generic collection interface is implemented by different kinds of
collection types.

The collection's access policy interface is consumed by gossip
to govern access to private read-write sets.

The collection store acts as a collection factory and serves collection
objects based on collection criteria.

The nop-collection is an implementation of both interfaces, i.e. a
collection type, that allows all organizations to pull a private
read-write set and a collection store that just returns an instance of
this collection type.

Change-Id: I9a589c1609a719a593918896623586583568a262
Signed-off-by: Matthias Neugschwandtner <eug@zurich.ibm.com>
  • Loading branch information
Matthias Neugschwandtner committed Sep 28, 2017
1 parent 6cc7444 commit 4a3c528
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 263 deletions.
66 changes: 66 additions & 0 deletions core/common/privdata/collection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package privdata

import (
"github.com/hyperledger/fabric/protos/common"
)

// Collection defines a common interface for collections
type Collection interface {
// SetTxContext configures the tx-specific ephemeral collection info, such
// as txid, nonce, creator -- for future use
// SetTxContext(parameters ...interface{})

// GetCollectionID returns this collection's ID
GetCollectionID() string

// GetEndorsementPolicy returns the endorsement policy for validation -- for
// future use
// GetEndorsementPolicy() string

// GetMemberOrgs returns the collection's members as MSP IDs. This serves as
// a human-readable way of quickly identifying who is part of a collection.
GetMemberOrgs() []string
}

// CollectionAccess encapsulates functions for the access policy of a collection
type CollectionAccessPolicy interface {
// GetAccessFilter returns a member filter function for a collection
GetAccessFilter() Filter

// RequiredExternalPeerCount returns the minimum number of external peers
// required to hold private data
RequiredExternalPeerCount() int

// RequiredExternalPeerCount returns the minimum number of internal peers
// required to hold private data
RequiredInternalPeerCount() int
}

// Filter defines a rule that filters peers according to data signed by them.
// The Identity in the SignedData is a SerializedIdentity of a peer.
// The Data is a message the peer signed, and the Signature is the corresponding
// Signature on that Data.
// Returns: True, if the policy holds for the given signed data.
// False otherwise
type Filter func(common.SignedData) bool

// CollectionStore retrieves stored collections based on the collection's
// properties. It works as a collection object factory and takes care of
// returning a collection object of an appropriate collection type.
type CollectionStore interface {
// GetCollection retrieves the collection in the following way:
// If the TxID exists in the ledger, the collection that is returned has the
// latest configuration that was committed into the ledger before this txID
// was committed.
// Else - it's the latest configuration for the collection.
GetCollection(common.CollectionCriteria) Collection

// GetCollectionAccessPolicy retrieves a collection's access policy
GetCollectionAccessPolicy(common.CollectionCriteria) CollectionAccessPolicy
}
53 changes: 53 additions & 0 deletions core/common/privdata/nopcollection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package privdata

import (
"github.com/hyperledger/fabric/protos/common"
)

// NopCollection implements an allow-all collection which all orgs are a member of
type NopCollection struct {
}

func (nc *NopCollection) GetCollectionID() string {
return ""
}

func (nc *NopCollection) GetEndorsementPolicy() string {
return ""
}

func (nc *NopCollection) GetMemberOrgs() []string {
return nil
}

func (nc *NopCollection) RequiredExternalPeerCount() int {
return 0
}

func (nc *NopCollection) RequiredInternalPeerCount() int {
return 0
}

func (nc *NopCollection) GetAccessFilter() Filter {
// return true for all
return func(common.SignedData) bool {
return true
}
}

type NopCollectionStore struct {
}

func (*NopCollectionStore) GetCollection(common.CollectionCriteria) Collection {
return &NopCollection{}
}

func (*NopCollectionStore) GetCollectionAccessPolicy(common.CollectionCriteria) CollectionAccessPolicy {
return &NopCollection{}
}
44 changes: 0 additions & 44 deletions core/common/privdata/policies.go

This file was deleted.

32 changes: 1 addition & 31 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,7 @@ func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {
Validator: validator,
Committer: c,
Store: store,
Pp: &noopPolicyParser{},
Ps: &noopPolicyStore{},
Cs: &privdata.NopCollectionStore{},
})

chains.Lock()
Expand Down Expand Up @@ -625,32 +624,3 @@ func CreatePeerServer(listenAddress string,
func GetPeerServer() comm.GRPCServer {
return peerServer
}

// TODO: This is a temporary implementation until the PolicyParser would be implemented
type noopPolicyParser struct {
}

func (*noopPolicyParser) Parse(privdata.SerializedPolicy) privdata.Filter {
return func(common.SignedData) bool {
return true
}
}

// TODO: This is a temporary implementation until the PolicyStore would be implemented
type noopPolicyStore struct {
}

func (*noopPolicyStore) CollectionPolicy(common.CollectionCriteria) privdata.SerializedPolicy {
return &serializedPolicy{}
}

type serializedPolicy struct {
}

func (*serializedPolicy) Channel() string {
panic("implement me")
}

func (*serializedPolicy) Raw() []byte {
panic("implement me")
}
11 changes: 5 additions & 6 deletions gossip/privdata/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ type Fetcher interface {
}

type Support struct {
privdata.PolicyParser
privdata.PolicyStore
privdata.CollectionStore
txvalidator.Validator
committer.Committer
TransientStore
Expand Down Expand Up @@ -503,12 +502,12 @@ func (c *coordinator) isEligible(chdr *common.ChannelHeader, namespace string, c
Collection: col,
TxId: chdr.TxId,
}
sp := c.PolicyStore.CollectionPolicy(cp)
sp := c.CollectionStore.GetCollectionAccessPolicy(cp)
if sp == nil {
logger.Warning("Failed obtaining policy for", cp, "skipping collection")
return false
}
filt := c.PolicyParser.Parse(sp)
filt := sp.GetAccessFilter()
if filt == nil {
logger.Warning("Failed parsing policy for", cp, "skipping collection")
return false
Expand Down Expand Up @@ -586,12 +585,12 @@ func (c *coordinator) GetPvtDataAndBlockByNum(seqNum uint64, peerAuthInfo common
Namespace: ns.Namespace,
Collection: col.CollectionName,
}
sp := c.PolicyStore.CollectionPolicy(cc)
sp := c.CollectionStore.GetCollectionAccessPolicy(cc)
if sp == nil {
logger.Warning("Failed obtaining policy for", cc)
continue
}
isAuthorized := c.PolicyParser.Parse(sp)
isAuthorized := sp.GetAccessFilter()
if isAuthorized == nil {
logger.Warning("Failed obtaining filter for", cc)
continue
Expand Down
Loading

0 comments on commit 4a3c528

Please sign in to comment.