Skip to content

Commit

Permalink
[FAB-11780] added membership provider to ledger
Browse files Browse the repository at this point in the history
had to refactor a bit, as membership provider creation was
dependant on collectionStore, which is created per channel,
therefore membership provider was also created per channel.

changed it such that we can create a single membership provider

FAB-11780 - #done

Change-Id: I2c44ebf00d6eea1fc1d713b3168328f95074c6b5
Signed-off-by: nirro <nirro@il.ibm.com>
  • Loading branch information
nirrozenbaum authored and manish-sethi committed Sep 26, 2018
1 parent 46546b3 commit a02124e
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 35 deletions.
17 changes: 11 additions & 6 deletions core/common/privdata/membershipinfo.go
Expand Up @@ -7,25 +7,30 @@ SPDX-License-Identifier: Apache-2.0
package privdata

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

// MembershipProvider can be used to check whether a peer is eligible to a collection or not
type MembershipProvider struct {
selfSignedData common.SignedData
cf CollectionFilter
selfSignedData common.SignedData
IdentityDeserializerFactory func(chainID string) msp.IdentityDeserializer
}

// NewMembershipInfoProvider returns MembershipProvider
func NewMembershipInfoProvider(selfSignedData common.SignedData, filter CollectionFilter) *MembershipProvider {
return &MembershipProvider{selfSignedData: selfSignedData, cf: filter}
func NewMembershipInfoProvider(selfSignedData common.SignedData, identityDeserializerFunc func(chainID string) msp.IdentityDeserializer) *MembershipProvider {
return &MembershipProvider{selfSignedData: selfSignedData, IdentityDeserializerFactory: identityDeserializerFunc}
}

// AmMemberOf checks whether the current peer is a member of the given collection config
func (m *MembershipProvider) AmMemberOf(channelName string, collectionPolicyConfig *common.CollectionPolicyConfig) (bool, error) {
filt, err := m.cf.AccessFilter(channelName, collectionPolicyConfig)
deserializer := m.IdentityDeserializerFactory(channelName)
accessPolicy, err := getPolicy(collectionPolicyConfig, deserializer)
if err != nil {
return false, err
}
return filt(m.selfSignedData), nil
if err := accessPolicy.Evaluate([]*common.SignedData{&m.selfSignedData}); err != nil {
return false, nil
}
return true, nil
}
12 changes: 7 additions & 5 deletions core/common/privdata/membershipinfo_test.go
Expand Up @@ -10,22 +10,24 @@ import (
"testing"

"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
"github.com/stretchr/testify/assert"
)

func TestMembershipInfoProvider(t *testing.T) {
// define identity of self peer as peer0
peerSelfSignedData := common.SignedData{
Identity: []byte("peer0"),
Signature: []byte{1, 2, 3},
Data: []byte{4, 5, 6},
}

collectionStore := NewSimpleCollectionStore(&mockStoreSupport{})
identityDeserializer := func(chainID string) msp.IdentityDeserializer {
return &mockDeserializer{}
}

// verify membership provider returns true
membershipProvider := NewMembershipInfoProvider(peerSelfSignedData, collectionStore)
membershipProvider := NewMembershipInfoProvider(peerSelfSignedData, identityDeserializer)
res, err := membershipProvider.AmMemberOf("test1", getAccessPolicy([]string{"peer0", "peer1"}))
assert.True(t, res)
assert.Nil(t, err)
Expand All @@ -35,11 +37,11 @@ func TestMembershipInfoProvider(t *testing.T) {
assert.False(t, res)
assert.Nil(t, err)

// verify membership provider returns nil and error
// verify membership provider returns nil and error when collection policy config is nil
res, err = membershipProvider.AmMemberOf("test1", nil)
assert.False(t, res)
assert.Error(t, err)
assert.Equal(t, "Collection config policy is nil", err.Error())
assert.Equal(t, "Collection policy config is nil", err.Error())
}

func getAccessPolicy(signers []string) *common.CollectionPolicyConfig {
Expand Down
18 changes: 2 additions & 16 deletions core/common/privdata/simplecollection.go
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
Expand Down Expand Up @@ -121,21 +120,8 @@ func (sc *SimpleCollection) Setup(collectionConfig *common.StaticCollectionConfi
// Setup configures a simple collection object based on a given
// StaticCollectionConfig proto that has all the necessary information
func (sc *SimpleCollection) setupAccessPolicy(collectionPolicyConfig *common.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) error {
if collectionPolicyConfig == nil {
return errors.New("Collection config policy is nil")
}
accessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy()
if accessPolicyEnvelope == nil {
return errors.New("Collection config access policy is nil")
}

// create access policy from the envelope
npp := cauthdsl.NewPolicyProvider(deserializer)
polBytes, err := proto.Marshal(accessPolicyEnvelope)
if err != nil {
return err
}
sc.accessPolicy, _, err = npp.NewPolicy(polBytes)
var err error
sc.accessPolicy, err = getPolicy(collectionPolicyConfig, deserializer)
return err
}

Expand Down
37 changes: 37 additions & 0 deletions core/common/privdata/util.go
@@ -0,0 +1,37 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package privdata

import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)

func getPolicy(collectionPolicyConfig *common.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) (policies.Policy, error) {
if collectionPolicyConfig == nil {
return nil, errors.New("Collection policy config is nil")
}
accessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy()
if accessPolicyEnvelope == nil {
return nil, errors.New("Collection config access policy is nil")
}
// create access policy from the envelope
npp := cauthdsl.NewPolicyProvider(deserializer)
polBytes, err := proto.Marshal(accessPolicyEnvelope)
if err != nil {
return nil, err
}
accessPolicy, _, err := npp.NewPolicy(polBytes)
if err != nil {
return nil, err
}
return accessPolicy, nil
}
3 changes: 2 additions & 1 deletion core/peer/peer.go
Expand Up @@ -195,7 +195,7 @@ var validationWorkersSemaphore *semaphore.Weighted
// Initialize sets up any chains that the peer has from the persistence. This
// function should be called at the start up when the ledger and gossip
// ready
func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider) {
func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider, membershipProvider ledger.MembershipInfoProvider) {
nWorkers := viper.GetInt("peer.validatorPoolSize")
if nWorkers <= 0 {
nWorkers = runtime.NumCPU()
Expand All @@ -211,6 +211,7 @@ func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccp
CustomTxProcessors: ConfigTxProcessors,
PlatformRegistry: pr,
DeployedChaincodeInfoProvider: deployedCCInfoProvider,
MembershipInfoProvider: membershipProvider,
})
ledgerIds, err := ledgermgmt.GetLedgerIDs()
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions core/peer/peer_impl.go
Expand Up @@ -30,7 +30,7 @@ type Operations interface {
GetMSPIDs(cid string) []string
GetPolicyManager(cid string) policies.Manager
InitChain(cid string)
Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider)
Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider, membershipProvider ledger.MembershipInfoProvider)
}

type peerImpl struct {
Expand All @@ -42,7 +42,7 @@ type peerImpl struct {
getMSPIDs func(cid string) []string
getPolicyManager func(cid string) policies.Manager
initChain func(cid string)
initialize func(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider)
initialize func(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider, membershipProvider ledger.MembershipInfoProvider)
}

// Default provides in implementation of the Peer interface that provides
Expand Down Expand Up @@ -73,6 +73,6 @@ func (p *peerImpl) GetLedger(cid string) ledger.PeerLedger { return p.getL
func (p *peerImpl) GetMSPIDs(cid string) []string { return p.getMSPIDs(cid) }
func (p *peerImpl) GetPolicyManager(cid string) policies.Manager { return p.getPolicyManager(cid) }
func (p *peerImpl) InitChain(cid string) { p.initChain(cid) }
func (p *peerImpl) Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider) {
p.initialize(init, ccp, sccp, mapper, pr, deployedCCInfoProvider)
func (p *peerImpl) Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider, membershipProvider ledger.MembershipInfoProvider) {
p.initialize(init, ccp, sccp, mapper, pr, deployedCCInfoProvider, membershipProvider)
}
4 changes: 2 additions & 2 deletions core/peer/peer_test.go
Expand Up @@ -86,14 +86,14 @@ func TestInitialize(t *testing.T) {
cleanup := setupPeerFS(t)
defer cleanup()

Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), nil, &ledgermocks.DeployedChaincodeInfoProvider{})
Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), nil, &ledgermocks.DeployedChaincodeInfoProvider{}, nil)
}

func TestCreateChainFromBlock(t *testing.T) {
cleanup := setupPeerFS(t)
defer cleanup()

Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), &platforms.Registry{}, &ledgermocks.DeployedChaincodeInfoProvider{})
Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), &platforms.Registry{}, &ledgermocks.DeployedChaincodeInfoProvider{}, nil)
testChainID := fmt.Sprintf("mytestchainid-%d", rand.Int())
block, err := configtxtest.MakeGenesisBlock(testChainID)
if err != nil {
Expand Down
29 changes: 28 additions & 1 deletion peer/node/start.go
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/hyperledger/fabric/core/comm"
"github.com/hyperledger/fabric/core/committer/txvalidator"
"github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric/core/common/privdata"
"github.com/hyperledger/fabric/core/container"
"github.com/hyperledger/fabric/core/container/dockercontroller"
"github.com/hyperledger/fabric/core/container/inproccontroller"
Expand Down Expand Up @@ -70,6 +71,7 @@ import (
peergossip "github.com/hyperledger/fabric/peer/gossip"
"github.com/hyperledger/fabric/peer/version"
cb "github.com/hyperledger/fabric/protos/common"
common2 "github.com/hyperledger/fabric/protos/common"
discprotos "github.com/hyperledger/fabric/protos/discovery"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/hyperledger/fabric/protos/transientstore"
Expand Down Expand Up @@ -157,12 +159,19 @@ func serve(args []string) error {

deployedCCInfoProvider := &lscc.DeployedCCInfoProvider{}

identityDeserializerFactory := func(chainID string) msp.IdentityDeserializer {
return mgmt.GetManagerForChain(chainID)
}

membershipInfoProvider := privdata.NewMembershipInfoProvider(createSelfSignedData(), identityDeserializerFactory)

//initialize resource management exit
ledgermgmt.Initialize(
&ledgermgmt.Initializer{
CustomTxProcessors: peer.ConfigTxProcessors,
PlatformRegistry: pr,
DeployedChaincodeInfoProvider: deployedCCInfoProvider,
MembershipInfoProvider: membershipInfoProvider,
})

// Parameter overrides must be processed before any parameters are
Expand Down Expand Up @@ -314,7 +323,7 @@ func serve(args []string) error {
logger.Panicf("Failed subscribing to chaincode lifecycle updates")
}
cceventmgmt.GetMgr().Register(cid, sub)
}, ccp, sccp, txvalidator.MapBasedPluginMapper(validationPluginsByName), pr, deployedCCInfoProvider)
}, ccp, sccp, txvalidator.MapBasedPluginMapper(validationPluginsByName), pr, deployedCCInfoProvider, membershipInfoProvider)

if viper.GetBool("peer.discovery.enabled") {
registerDiscoveryService(peerServer, policyMgr, lifecycle)
Expand Down Expand Up @@ -373,6 +382,24 @@ func localPolicy(policyObject proto.Message) policies.Policy {
return policy
}

func createSelfSignedData() common2.SignedData {
sId := mgmt.GetLocalSigningIdentityOrPanic()
msg := make([]byte, 32)
sig, err := sId.Sign(msg)
if err != nil {
logger.Panicf("Failed creating self signed data because message signing failed: %v", err)
}
peerIdentity, err := sId.Serialize()
if err != nil {
logger.Panicf("Failed creating self signed data because peer identity couldn't be serialized: %v", err)
}
return common2.SignedData{
Data: msg,
Signature: sig,
Identity: peerIdentity,
}
}

func registerDiscoveryService(peerServer *comm.GRPCServer, polMgr policies.ChannelPolicyManagerGetter, lc *cc.Lifecycle) {
mspID := viper.GetString("peer.localMspId")
localAccessPolicy := localPolicy(cauthdsl.SignedByAnyAdmin([]string{mspID}))
Expand Down

0 comments on commit a02124e

Please sign in to comment.