Commit 1e89f005 authored by Gari Singh's avatar Gari Singh Committed by Gerrit Code Review
Browse files

Merge "[FAB-10027] Discovery cc2cc Implementation"

parents 79aa506e f7996763
......@@ -130,6 +130,15 @@ func (cp *ComparablePrincipal) ToRole() *ComparablePrincipal {
// ComparablePrincipalSet aggregates ComparablePrincipals
type ComparablePrincipalSet []*ComparablePrincipal
// ToPrincipalSet converts this ComparablePrincipalSet to a PrincipalSet
func (cps ComparablePrincipalSet) ToPrincipalSet() policies.PrincipalSet {
var res policies.PrincipalSet
for _, cp := range cps {
res = append(res, cp.principal)
}
return res
}
// String returns a string representation of this ComparablePrincipalSet
func (cps ComparablePrincipalSet) String() string {
buff := bytes.Buffer{}
......
......@@ -15,6 +15,31 @@ import (
"github.com/stretchr/testify/assert"
)
func TestToPrincipalSet(t *testing.T) {
var cps ComparablePrincipalSet
cps = append(cps, NewComparablePrincipal(member("Org1MSP")))
cps = append(cps, NewComparablePrincipal(member("Org2MSP")))
expected := policies.PrincipalSet{member("Org1MSP"), member("Org2MSP")}
assert.Equal(t, expected, cps.ToPrincipalSet())
}
func TestToPrincipalSets(t *testing.T) {
var cps, cps2 ComparablePrincipalSet
cps = append(cps, NewComparablePrincipal(member("Org1MSP")))
cps = append(cps, NewComparablePrincipal(member("Org2MSP")))
cps2 = append(cps2, NewComparablePrincipal(member("Org3MSP")))
cps2 = append(cps2, NewComparablePrincipal(member("Org4MSP")))
expected := policies.PrincipalSets{
{member("Org1MSP"), member("Org2MSP")},
{member("Org3MSP"), member("Org4MSP")},
}
assert.Equal(t, expected, ComparablePrincipalSets{cps, cps2}.ToPrincipalSets())
}
func TestNewComparablePrincipal(t *testing.T) {
mspID := "Org1MSP"
......
......@@ -8,11 +8,22 @@ package inquire
import (
"reflect"
"github.com/hyperledger/fabric/common/policies"
)
// ComparablePrincipalSets aggregate ComparablePrincipalSets
type ComparablePrincipalSets []ComparablePrincipalSet
// ToPrincipalSets converts this ComparablePrincipalSets to a PrincipalSets
func (cps ComparablePrincipalSets) ToPrincipalSets() policies.PrincipalSets {
var res policies.PrincipalSets
for _, cp := range cps {
res = append(res, cp.ToPrincipalSet())
}
return res
}
// Merge returns ComparablePrincipalSets that the underlying PrincipalSets consist of
// PrincipalSets that satisfy the endorsement policies that both ComparablePrincipalSets were derived of.
// More formally speaking, let EP1 and EP2 be endorsement policies, and
......
......@@ -15,7 +15,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/protos/msp"
logging "github.com/op/go-logging"
"github.com/op/go-logging"
"github.com/pkg/errors"
)
......
......@@ -13,6 +13,7 @@ import (
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/graph"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/policies/inquire"
"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/common"
discovery2 "github.com/hyperledger/fabric/gossip/discovery"
......@@ -79,12 +80,6 @@ type peerPrincipalEvaluator func(member discovery2.NetworkMember, principal *msp
// PeersForEndorsement returns an EndorsementDescriptor for a given set of peers, channel, and chaincode
func (ea *endorsementAnalyzer) PeersForEndorsement(chainID common.ChainID, interest *discovery.ChaincodeInterest) (*discovery.EndorsementDescriptor, error) {
// For now we only support a single chaincode
if len(interest.Chaincodes) != 1 {
return nil, errors.New("only a single chaincode is supported")
}
interest.Chaincodes = []*discovery.ChaincodeCall{interest.Chaincodes[0]}
metadataAndCollectionFilters, err := loadMetadataAndFilters(chainID, interest, ea)
if err != nil {
return nil, errors.WithStack(err)
......@@ -98,20 +93,12 @@ func (ea *endorsementAnalyzer) PeersForEndorsement(chainID common.ChainID, inter
// Compute a mapping between the PKI-IDs of members to their identities
identities := ea.IdentityInfo()
identitiesOfMembers := computeIdentitiesOfMembers(identities, membersById)
// Retrieve the policies for the chaincodes
pols, err := ea.loadPolicies(chainID, interest)
filter := ea.excludeIfCCNotInstalled(membersById, identities.ByID())
principalsSets, err := ea.computePrincipalSets(chainID, interest, filter)
if err != nil {
logger.Warningf("Principal set computation failed: %v", err)
return nil, errors.WithStack(err)
}
// For now we take the first policy and ignore the rest
pol := pols[0]
// Compute the combinations of principals (principal sets) that satisfy the endorsement policy
principalsSets := policies.PrincipalSets(pol.SatisfiedBy())
// Filter out principal sets that contain MSP IDs for peers that don't have the chaincode(s) installed
principalsSets = ea.excludeIfCCNotInstalled(principalsSets, membersById, identities.ByID())
// Filter the principal sets by the collections (if applicable)
principalsSets, err = metadataAndCollectionFilters.filter(principalsSets)
......@@ -169,43 +156,60 @@ func (ea *endorsementAnalyzer) computeEndorsementResponse(ctx *context) (*discov
}, nil
}
func (ea *endorsementAnalyzer) excludeIfCCNotInstalled(principalsSets policies.PrincipalSets, membersById map[string]discovery2.NetworkMember, identitiesByID map[string]api.PeerIdentityInfo) policies.PrincipalSets {
type principalFilter func(policies.PrincipalSet) bool
func (ea *endorsementAnalyzer) excludeIfCCNotInstalled(membersById map[string]discovery2.NetworkMember, identitiesByID map[string]api.PeerIdentityInfo) principalFilter {
// Obtain the MSP IDs of the members of the channel that are alive
mspIDsOfChannelPeers := mspIDsOfMembers(membersById, identitiesByID)
principalsSets = ea.excludePrincipals(func(principal *msp.MSPPrincipal) bool {
// Create an exclusion filter for MSP Principals which their peers don't have the chaincode installed
excludeMSPsWithoutChaincodeInstalled := func(principal *msp.MSPPrincipal) bool {
mspID := ea.MSPOfPrincipal(principal)
_, exists := mspIDsOfChannelPeers[mspID]
return mspID != "" && exists
}, principalsSets)
return principalsSets
}
func (ea *endorsementAnalyzer) excludePrincipals(filter func(principal *msp.MSPPrincipal) bool, sets ...policies.PrincipalSets) policies.PrincipalSets {
var res []policies.PrincipalSets
for _, principalSets := range sets {
principalSets = principalSets.ContainingOnly(filter)
if len(principalSets) == 0 {
continue
}
res = append(res, principalSets)
}
if len(res) == 0 {
return nil
return func(principalsSet policies.PrincipalSet) bool {
return principalsSet.ContainingOnly(excludeMSPsWithoutChaincodeInstalled)
}
return res[0]
}
func (ea *endorsementAnalyzer) loadPolicies(chainID common.ChainID, interest *discovery.ChaincodeInterest) ([]policies.InquireablePolicy, error) {
var res []policies.InquireablePolicy
func (ea *endorsementAnalyzer) computePrincipalSets(chainID common.ChainID, interest *discovery.ChaincodeInterest, filter principalFilter) (policies.PrincipalSets, error) {
var inquireablePolicies []policies.InquireablePolicy
for _, chaincode := range interest.Chaincodes {
pol := ea.PolicyByChaincode(string(chainID), chaincode.Name)
if pol == nil {
logger.Debug("Policy for chaincode '", chaincode, "'doesn't exist")
return nil, errors.New("policy not found")
}
res = append(res, pol)
inquireablePolicies = append(inquireablePolicies, pol)
}
var cpss []inquire.ComparablePrincipalSets
for _, policy := range inquireablePolicies {
var cmpsets inquire.ComparablePrincipalSets
for _, ps := range policy.SatisfiedBy() {
if !filter(ps) {
logger.Debug(ps, "filtered out due to chaincodes not being installed on the corresponding organizations")
continue
}
cps := inquire.NewComparablePrincipalSet(ps)
if cps == nil {
return nil, errors.New("failed creating a comparable principal set")
}
cmpsets = append(cmpsets, cps)
}
if len(cmpsets) == 0 {
return nil, errors.New("chaincode isn't installed on sufficient organizations required by the endorsement policy")
}
cpss = append(cpss, cmpsets)
}
cps, err := mergePrincipalSets(cpss)
if err != nil {
return nil, errors.WithStack(err)
}
return res, nil
return cps.ToPrincipalSets(), nil
}
type filterFunc func(policies.PrincipalSets) (policies.PrincipalSets, error)
......@@ -517,3 +521,25 @@ func mspIDsOfMembers(membersById map[string]discovery2.NetworkMember, identities
}
return res
}
func mergePrincipalSets(cpss []inquire.ComparablePrincipalSets) (inquire.ComparablePrincipalSets, error) {
// Obtain the first ComparablePrincipalSet first
var cps inquire.ComparablePrincipalSets
cps, cpss, err := popComparablePrincipalSets(cpss)
if err != nil {
return nil, errors.WithStack(err)
}
for _, cps2 := range cpss {
cps = inquire.Merge(cps, cps2)
}
return cps, nil
}
func popComparablePrincipalSets(sets []inquire.ComparablePrincipalSets) (inquire.ComparablePrincipalSets, []inquire.ComparablePrincipalSets, error) {
if len(sets) == 0 {
return nil, nil, errors.New("no principal sets remained after filtering")
}
cps, cpss := sets[0], sets[1:]
return cps, cpss, nil
}
......@@ -13,10 +13,11 @@ import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/chaincode"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/policies/inquire"
"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/common"
"github.com/hyperledger/fabric/gossip/discovery"
discovery2 "github.com/hyperledger/fabric/protos/discovery"
discoveryprotos "github.com/hyperledger/fabric/protos/discovery"
"github.com/hyperledger/fabric/protos/gossip"
"github.com/hyperledger/fabric/protos/msp"
"github.com/hyperledger/fabric/protos/utils"
......@@ -51,7 +52,7 @@ func TestPeersForEndorsement(t *testing.T) {
}),
}
}
extractPeers := func(desc *discovery2.EndorsementDescriptor) map[string]struct{} {
extractPeers := func(desc *discoveryprotos.EndorsementDescriptor) map[string]struct{} {
res := make(map[string]struct{})
for _, endorsers := range desc.EndorsersByGroups {
for _, p := range endorsers.Peers {
......@@ -75,6 +76,7 @@ func TestPeersForEndorsement(t *testing.T) {
newPeer(6),
newPeer(8),
newPeer(10),
newPeer(11),
newPeer(12),
}
......@@ -85,6 +87,7 @@ func TestPeersForEndorsement(t *testing.T) {
newPeer(3).withChaincode(cc, "1.0"),
newPeer(6).withChaincode(cc, "1.0"),
newPeer(9).withChaincode(cc, "1.0"),
newPeer(11).withChaincode(cc, "1.0"),
newPeer(12).withChaincode(cc, "1.0"),
}
g.On("Peers").Return(alivePeers.toMembers())
......@@ -96,7 +99,7 @@ func TestPeersForEndorsement(t *testing.T) {
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
mf.On("Metadata").Return(&chaincode.Metadata{Name: cc, Version: "1.0"}).Once()
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: ccWithMissingPolicy}}})
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: ccWithMissingPolicy}}})
assert.Nil(t, desc)
assert.Equal(t, "policy not found", err.Error())
})
......@@ -105,14 +108,15 @@ func TestPeersForEndorsement(t *testing.T) {
// Scenario II: Policy is found but not enough peers to satisfy the policy.
// The policy requires a signature from:
// p1 and p6, or
// p11
// p11 x2 (twice), but we only have a single peer in the alive view for p11
pb := principalBuilder{}
policy := pb.newSet().addPrincipal(peerRole("p1")).addPrincipal(peerRole("p6")).newSet().addPrincipal(peerRole("p11")).buildPolicy()
policy := pb.newSet().addPrincipal(peerRole("p1")).addPrincipal(peerRole("p6")).
newSet().addPrincipal(peerRole("p11")).addPrincipal(peerRole("p11")).buildPolicy()
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
mf.On("Metadata").Return(&chaincode.Metadata{Name: cc, Version: "1.0"}).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
pf.On("PolicyByChaincode", cc).Return(policy).Once()
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.Nil(t, desc)
assert.Equal(t, err.Error(), "cannot satisfy any principal combination")
})
......@@ -127,9 +131,9 @@ func TestPeersForEndorsement(t *testing.T) {
newSet().addPrincipal(peerRole("p10")).addPrincipal(peerRole("p12")).buildPolicy()
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
mf.On("Metadata").Return(&chaincode.Metadata{Name: cc, Version: "1.0"}).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
pf.On("PolicyByChaincode", cc).Return(policy).Once()
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.NoError(t, err)
assert.NotNil(t, desc)
assert.Len(t, desc.Layouts, 1)
......@@ -150,9 +154,9 @@ func TestPeersForEndorsement(t *testing.T) {
newSet().addPrincipal(peerRole("p12")).buildPolicy()
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
mf.On("Metadata").Return(&chaincode.Metadata{Name: cc, Version: "1.0"}).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
pf.On("PolicyByChaincode", cc).Return(policy).Once()
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.NoError(t, err)
assert.NotNil(t, desc)
assert.Len(t, desc.Layouts, 2)
......@@ -166,7 +170,7 @@ func TestPeersForEndorsement(t *testing.T) {
})
t.Run("WrongVersionInstalled", func(t *testing.T) {
// Scenario V: Policy is found, but there are enough peers to satisfy policy combinations,
// Scenario V: Policy is found, and there are enough peers to satisfy policy combinations,
// but all peers have the wrong version installed on them.
mf.On("Metadata").Return(&chaincode.Metadata{
Name: cc, Version: "1.1",
......@@ -176,10 +180,10 @@ func TestPeersForEndorsement(t *testing.T) {
newSet().addPrincipal(peerRole("p12")).buildPolicy()
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
pf.On("PolicyByChaincode", cc).Return(policy).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.Nil(t, desc)
assert.Equal(t, err.Error(), "cannot satisfy any principal combination")
assert.Equal(t, err.Error(), "chaincode isn't installed on sufficient organizations required by the endorsement policy")
// Scenario VI: Policy is found, there are enough peers to satisfy policy combinations,
// but some peers have the wrong chaincode version, and some don't even have it installed.
......@@ -197,22 +201,22 @@ func TestPeersForEndorsement(t *testing.T) {
mf.On("Metadata").Return(&chaincode.Metadata{
Name: cc, Version: "1.0",
}).Once()
desc, err = analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
desc, err = analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.Nil(t, desc)
assert.Equal(t, err.Error(), "cannot satisfy any principal combination")
assert.Equal(t, err.Error(), "chaincode isn't installed on sufficient organizations required by the endorsement policy")
})
t.Run("NoChaincodeMetadataFromLedger", func(t *testing.T) {
// Scenario VII: Policy is found, there are enough peers to satisfy the policy,
// but the chaincode metadata cannot be fetched from the ledger.
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
//g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
pb := principalBuilder{}
policy := pb.newSet().addPrincipal(peerRole("p0")).addPrincipal(peerRole("p6")).
newSet().addPrincipal(peerRole("p12")).buildPolicy()
pf.On("PolicyByChaincode", cc).Return(policy).Once()
mf.On("Metadata").Return(nil).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{Chaincodes: []*discovery2.ChaincodeCall{{Name: cc}}})
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{Chaincodes: []*discoveryprotos.ChaincodeCall{{Name: cc}}})
assert.Nil(t, desc)
assert.Equal(t, err.Error(), "No metadata was found for chaincode chaincode in channel test")
})
......@@ -235,9 +239,9 @@ func TestPeersForEndorsement(t *testing.T) {
addPrincipal(peerRole("p12")).buildPolicy()
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
pf.On("PolicyByChaincode", cc).Return(policy).Once()
analyzer := NewEndorsementAnalyzer(g, pf, policy.ToPrincipalEvaluator(pkiID2MSPID), mf)
desc, err := analyzer.PeersForEndorsement(channel, &discovery2.ChaincodeInterest{
Chaincodes: []*discovery2.ChaincodeCall{
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{
{
Name: cc,
CollectionNames: []string{"collection"},
......@@ -252,6 +256,128 @@ func TestPeersForEndorsement(t *testing.T) {
peerIdentityString("p12"): {},
}, extractPeers(desc))
})
t.Run("Chaincode2Chaincode", func(t *testing.T) {
// Scenario IX: A chaincode-to-chaincode query is made.
// Total organizations are 0, 2, 4, 6, 10, 12
// and the endorsement policies of the chaincodes are as follows:
// cc1: OR(AND(0, 2), AND(6, 10))
// cc2: AND(6, 10, 12)
// cc3: AND(4, 12)
// Therefore, the result should be: 4, 6, 10, 12
chanPeers := peerSet{}
for _, id := range []int{0, 2, 4, 6, 10, 12} {
peer := newPeer(id).withChaincode("cc1", "1.0").withChaincode("cc2", "1.0").withChaincode("cc3", "1.0")
chanPeers = append(chanPeers, peer)
}
g.On("PeersOfChannel").Return(chanPeers.toMembers()).Once()
mf.On("Metadata").Return(&chaincode.Metadata{
Name: "cc1", Version: "1.0",
}).Once()
mf.On("Metadata").Return(&chaincode.Metadata{
Name: "cc2", Version: "1.0",
}).Once()
mf.On("Metadata").Return(&chaincode.Metadata{
Name: "cc3", Version: "1.0",
}).Once()
pb := principalBuilder{}
cc1policy := pb.newSet().addPrincipal(peerRole("p0")).addPrincipal(peerRole("p2")).
newSet().addPrincipal(peerRole("p6")).addPrincipal(peerRole("p10")).buildPolicy()
pf.On("PolicyByChaincode", "cc1").Return(cc1policy).Once()
cc2policy := pb.newSet().addPrincipal(peerRole("p6")).
addPrincipal(peerRole("p10")).addPrincipal(peerRole("p12")).buildPolicy()
pf.On("PolicyByChaincode", "cc2").Return(cc2policy).Once()
cc3policy := pb.newSet().addPrincipal(peerRole("p4")).
addPrincipal(peerRole("p12")).buildPolicy()
pf.On("PolicyByChaincode", "cc3").Return(cc3policy).Once()
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
desc, err := analyzer.PeersForEndorsement(channel, &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{
{
Name: "cc1",
},
{
Name: "cc2",
},
{
Name: "cc3",
},
},
})
assert.NoError(t, err)
assert.NotNil(t, desc)
assert.Len(t, desc.Layouts, 1)
assert.Len(t, desc.Layouts[0].QuantitiesByGroup, 4)
assert.Equal(t, map[string]struct{}{
peerIdentityString("p4"): {},
peerIdentityString("p6"): {},
peerIdentityString("p10"): {},
peerIdentityString("p12"): {},
}, extractPeers(desc))
})
}
func TestPop(t *testing.T) {
slice := []inquire.ComparablePrincipalSets{{}, {}}
assert.Len(t, slice, 2)
_, slice, err := popComparablePrincipalSets(slice)
assert.NoError(t, err)
assert.Len(t, slice, 1)
_, slice, err = popComparablePrincipalSets(slice)
assert.Len(t, slice, 0)
_, slice, err = popComparablePrincipalSets(slice)
assert.Error(t, err)
assert.Equal(t, "no principal sets remained after filtering", err.Error())
}
func TestMergePrincipalSetsNilInput(t *testing.T) {
_, err := mergePrincipalSets(nil)
assert.Error(t, err)
assert.Equal(t, "no principal sets remained after filtering", err.Error())
}
func TestComputePrincipalSetsNoPolicies(t *testing.T) {
// Tests a hypothetical case where no chaincodes populate the chaincode interest.
interest := &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{},
}
ea := &endorsementAnalyzer{}
acceptAll := func(policies.PrincipalSet) bool {
return true
}
_, err := ea.computePrincipalSets(common.ChainID("mychannel"), interest, acceptAll)
assert.Error(t, err)
assert.Contains(t, err.Error(), "no principal sets remained after filtering")
}
func TestLoadMetadataAndFiltersInvalidCollectionData(t *testing.T) {
interest := &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{
{
Name: "mycc",
CollectionNames: []string{"col1"},
},
},
}
mdf := &metadataFetcher{}
mdf.On("Metadata").Return(&chaincode.Metadata{
Name: "mycc",
CollectionsConfig: []byte{1, 2, 3},
Policy: []byte{1, 2, 3},
})
_, err := loadMetadataAndFilters(common.ChainID("mychannel"), interest, mdf)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid collection bytes")
}
type peerSet []*peerInfo
......@@ -381,13 +507,7 @@ func (ip inquireablePolicy) SatisfiedBy() []policies.PrincipalSet {
return ip
}
func (ip inquireablePolicy) ToPrincipalEvaluator(pkiID2MSPID map[string]string) *principalEvaluatorMock {
return &principalEvaluatorMock{ip: ip, pkiID2MSPID: pkiID2MSPID}
}
type principalEvaluatorMock struct {
pkiID2MSPID map[string]string
ip []policies.PrincipalSet
}
func (pe *principalEvaluatorMock) MSPOfPrincipal(principal *msp.MSPPrincipal) string {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment