Skip to content

Commit

Permalink
[FABGW-25] Move chaincode interest to proposal response proto (#2763)
Browse files Browse the repository at this point in the history
This commit picks up the changes in pull request hyperledger/fabric-protos#59 which entail:

- Moving chaincode interest to proposal response
- Adding a policy for state based endorsement in the chaincode call in preperation for FABGW-25

Change-Id: Ia0a0d57964daad9c773135d2e6c1d3a96e4df079
Signed-off-by: Yacov Manevich <yacovm@il.ibm.com>
  • Loading branch information
yacovm authored Jul 19, 2021
1 parent ffe7d36 commit 84c1270
Show file tree
Hide file tree
Showing 20 changed files with 530 additions and 377 deletions.
5 changes: 3 additions & 2 deletions discovery/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package discovery

import (
discprotos "github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/common"
"github.com/hyperledger/fabric/gossip/discovery"
Expand Down Expand Up @@ -48,13 +49,13 @@ type GossipSupport interface {
// for chaincodes
type EndorsementSupport interface {
// PeersForEndorsement returns an EndorsementDescriptor for a given set of peers, channel, and chaincode
PeersForEndorsement(channel common.ChannelID, interest *discprotos.ChaincodeInterest) (*discprotos.EndorsementDescriptor, error)
PeersForEndorsement(channel common.ChannelID, interest *peer.ChaincodeInterest) (*discprotos.EndorsementDescriptor, error)

// PeersAuthorizedByCriteria returns the peers of the channel that are authorized by the given chaincode interest
// That is - taking in account if the chaincode(s) in the interest are installed on the peers, and also
// taking in account whether the peers are part of the collections of the chaincodes.
// If a nil interest, or an empty interest is passed - no filtering is done.
PeersAuthorizedByCriteria(chainID common.ChannelID, interest *discprotos.ChaincodeInterest) (discovery.Members, error)
PeersAuthorizedByCriteria(chainID common.ChannelID, interest *peer.ChaincodeInterest) (discovery.Members, error)
}

// ConfigSupport provides access to channel configuration
Expand Down
3 changes: 2 additions & 1 deletion discovery/client/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package discovery

import (
"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/gossip/protoext"
"github.com/pkg/errors"
"google.golang.org/grpc"
Expand Down Expand Up @@ -38,7 +39,7 @@ type ChannelResponse interface {
Config() (*discovery.ConfigResult, error)

// Peers returns a response for a peer membership query, or error if something went wrong
Peers(invocationChain ...*discovery.ChaincodeCall) ([]*Peer, error)
Peers(invocationChain ...*peer.ChaincodeCall) ([]*Peer, error)

// Endorsers returns the response for an endorser query for a given
// chaincode in a given channel context, or error if something went wrong.
Expand Down
16 changes: 9 additions & 7 deletions discovery/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"math/rand"
"time"

"github.com/hyperledger/fabric-protos-go/peer"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/msp"
Expand Down Expand Up @@ -76,7 +78,7 @@ func (req *Request) AddConfigQuery() *Request {
// AddEndorsersQuery adds to the request a query for given chaincodes
// interests are the chaincode interests that the client wants to query for.
// All interests for a given channel should be supplied in an aggregated slice
func (req *Request) AddEndorsersQuery(interests ...*discovery.ChaincodeInterest) (*Request, error) {
func (req *Request) AddEndorsersQuery(interests ...*peer.ChaincodeInterest) (*Request, error) {
if err := validateInterests(interests...); err != nil {
return nil, err
}
Expand Down Expand Up @@ -113,11 +115,11 @@ func (req *Request) AddLocalPeersQuery() *Request {
}

// AddPeersQuery adds to the request a peer query
func (req *Request) AddPeersQuery(invocationChain ...*discovery.ChaincodeCall) *Request {
func (req *Request) AddPeersQuery(invocationChain ...*peer.ChaincodeCall) *Request {
ch := req.lastChannel
q := &discovery.Query_PeerQuery{
PeerQuery: &discovery.PeerMembershipQuery{
Filter: &discovery.ChaincodeInterest{
Filter: &peer.ChaincodeInterest{
Chaincodes: invocationChain,
},
},
Expand Down Expand Up @@ -221,7 +223,7 @@ func (cr *channelResponse) Config() (*discovery.ConfigResult, error) {
return nil, res.(error)
}

func parsePeers(queryType protoext.QueryType, r response, channel string, invocationChain ...*discovery.ChaincodeCall) ([]*Peer, error) {
func parsePeers(queryType protoext.QueryType, r response, channel string, invocationChain ...*peer.ChaincodeCall) ([]*Peer, error) {
peerKeys := key{
queryType: queryType,
k: fmt.Sprintf("%s %s", channel, InvocationChain(invocationChain).String()),
Expand All @@ -239,7 +241,7 @@ func parsePeers(queryType protoext.QueryType, r response, channel string, invoca
return nil, res.(error)
}

func (cr *channelResponse) Peers(invocationChain ...*discovery.ChaincodeCall) ([]*Peer, error) {
func (cr *channelResponse) Peers(invocationChain ...*peer.ChaincodeCall) ([]*Peer, error) {
return parsePeers(protoext.PeerMembershipQueryType, cr.response, cr.channel, invocationChain...)
}

Expand Down Expand Up @@ -596,7 +598,7 @@ func validateStateInfoMessage(message *gprotoext.SignedGossipMessage) error {
return nil
}

func validateInterests(interests ...*discovery.ChaincodeInterest) error {
func validateInterests(interests ...*peer.ChaincodeInterest) error {
if len(interests) == 0 {
return errors.New("no chaincode interests given")
}
Expand All @@ -612,7 +614,7 @@ func validateInterests(interests ...*discovery.ChaincodeInterest) error {
}

// InvocationChain aggregates ChaincodeCalls
type InvocationChain []*discovery.ChaincodeCall
type InvocationChain []*peer.ChaincodeCall

// String returns a string representation of this invocation chain
func (ic InvocationChain) String() string {
Expand Down
38 changes: 19 additions & 19 deletions discovery/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,11 +703,11 @@ func TestAddEndorsersQueryInvalidInput(t *testing.T) {
_, err = NewRequest().AddEndorsersQuery(nil)
require.Contains(t, err.Error(), "chaincode interest is nil")

_, err = NewRequest().AddEndorsersQuery(&discovery.ChaincodeInterest{})
_, err = NewRequest().AddEndorsersQuery(&peer.ChaincodeInterest{})
require.Contains(t, err.Error(), "invocation chain should not be empty")

_, err = NewRequest().AddEndorsersQuery(&discovery.ChaincodeInterest{
Chaincodes: []*discovery.ChaincodeCall{{}},
_, err = NewRequest().AddEndorsersQuery(&peer.ChaincodeInterest{
Chaincodes: []*peer.ChaincodeCall{{}},
})
require.Contains(t, err.Error(), "chaincode name should not be empty")
}
Expand Down Expand Up @@ -759,11 +759,11 @@ func TestValidateStateInfoMessage(t *testing.T) {

func TestString(t *testing.T) {
var ic InvocationChain
ic = append(ic, &discovery.ChaincodeCall{
ic = append(ic, &peer.ChaincodeCall{
Name: "foo",
CollectionNames: []string{"c1", "c2"},
})
ic = append(ic, &discovery.ChaincodeCall{
ic = append(ic, &peer.ChaincodeCall{
Name: "bar",
CollectionNames: []string{"c3", "c4"},
})
Expand Down Expand Up @@ -824,9 +824,9 @@ func (pf *policyFetcher) PoliciesByChaincode(channel string, cc string, collecti
}

type endorsementAnalyzer interface {
PeersForEndorsement(chainID gossipcommon.ChannelID, interest *discovery.ChaincodeInterest) (*discovery.EndorsementDescriptor, error)
PeersForEndorsement(chainID gossipcommon.ChannelID, interest *peer.ChaincodeInterest) (*discovery.EndorsementDescriptor, error)

PeersAuthorizedByCriteria(chainID gossipcommon.ChannelID, interest *discovery.ChaincodeInterest) (gdisc.Members, error)
PeersAuthorizedByCriteria(chainID gossipcommon.ChannelID, interest *peer.ChaincodeInterest) (gdisc.Members, error)
}

type inquireablePolicy struct {
Expand Down Expand Up @@ -957,11 +957,11 @@ func (ms *mockSupport) Peers() gdisc.Members {
return ms.Called().Get(0).(gdisc.Members)
}

func (ms *mockSupport) PeersForEndorsement(channel gossipcommon.ChannelID, interest *discovery.ChaincodeInterest) (*discovery.EndorsementDescriptor, error) {
func (ms *mockSupport) PeersForEndorsement(channel gossipcommon.ChannelID, interest *peer.ChaincodeInterest) (*discovery.EndorsementDescriptor, error) {
return ms.endorsementAnalyzer.PeersForEndorsement(channel, interest)
}

func (ms *mockSupport) PeersAuthorizedByCriteria(channel gossipcommon.ChannelID, interest *discovery.ChaincodeInterest) (gdisc.Members, error) {
func (ms *mockSupport) PeersAuthorizedByCriteria(channel gossipcommon.ChannelID, interest *peer.ChaincodeInterest) (gdisc.Members, error) {
return ms.endorsementAnalyzer.PeersAuthorizedByCriteria(channel, interest)
}

Expand Down Expand Up @@ -1007,32 +1007,32 @@ func (ds *mockDiscoveryServer) Discover(context.Context, *discovery.SignedReques
return args.Get(0).(*discovery.Response), nil
}

func ccCall(ccNames ...string) []*discovery.ChaincodeCall {
var call []*discovery.ChaincodeCall
func ccCall(ccNames ...string) []*peer.ChaincodeCall {
var call []*peer.ChaincodeCall
for _, ccName := range ccNames {
call = append(call, &discovery.ChaincodeCall{
call = append(call, &peer.ChaincodeCall{
Name: ccName,
})
}
return call
}

func cc2ccInterests(invocationsChains ...[]*discovery.ChaincodeCall) []*discovery.ChaincodeInterest {
var interests []*discovery.ChaincodeInterest
func cc2ccInterests(invocationsChains ...[]*peer.ChaincodeCall) []*peer.ChaincodeInterest {
var interests []*peer.ChaincodeInterest
for _, invocationChain := range invocationsChains {
interests = append(interests, &discovery.ChaincodeInterest{
interests = append(interests, &peer.ChaincodeInterest{
Chaincodes: invocationChain,
})
}
return interests
}

func interest(ccNames ...string) *discovery.ChaincodeInterest {
interest := &discovery.ChaincodeInterest{
Chaincodes: []*discovery.ChaincodeCall{},
func interest(ccNames ...string) *peer.ChaincodeInterest {
interest := &peer.ChaincodeInterest{
Chaincodes: []*peer.ChaincodeCall{},
}
for _, cc := range ccNames {
interest.Chaincodes = append(interest.Chaincodes, &discovery.ChaincodeCall{
interest.Chaincodes = append(interest.Chaincodes, &peer.ChaincodeCall{
Name: cc,
})
}
Expand Down
8 changes: 5 additions & 3 deletions discovery/cmd/endorsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"reflect"
"strings"

"github.com/hyperledger/fabric-protos-go/peer"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/gossip"
Expand Down Expand Up @@ -90,17 +92,17 @@ func (pc *EndorsersCmd) Execute(conf common.Config) error {
return err
}

var ccCalls []*discovery.ChaincodeCall
var ccCalls []*peer.ChaincodeCall

for _, cc := range *ccAndCol.Chaincodes {
ccCalls = append(ccCalls, &discovery.ChaincodeCall{
ccCalls = append(ccCalls, &peer.ChaincodeCall{
Name: cc,
CollectionNames: cc2collections[cc],
NoPrivateReads: ccAndCol.noPrivateReads(cc),
})
}

req, err := discoveryclient.NewRequest().OfChannel(channel).AddEndorsersQuery(&discovery.ChaincodeInterest{Chaincodes: ccCalls})
req, err := discoveryclient.NewRequest().OfChannel(channel).AddEndorsersQuery(&peer.ChaincodeInterest{Chaincodes: ccCalls})
if err != nil {
return errors.Wrap(err, "failed creating request")
}
Expand Down
19 changes: 12 additions & 7 deletions discovery/cmd/mocks/channel_response.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions discovery/endorsement/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ SPDX-License-Identifier: Apache-2.0
package endorsement

import (
"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/gossip/api"
Expand Down Expand Up @@ -47,7 +46,7 @@ type principalSetsByCollectionName map[string]policies.PrincipalSet

// toIdentityFilter converts this principalSetsByCollectionName mapping to a filter
// which accepts or rejects identities of peers.
func (psbc principalSetsByCollectionName) toIdentityFilter(channel string, evaluator principalEvaluator, cc *discovery.ChaincodeCall) (identityFilter, error) {
func (psbc principalSetsByCollectionName) toIdentityFilter(channel string, evaluator principalEvaluator, cc *peer.ChaincodeCall) (identityFilter, error) {
var principalSets policies.PrincipalSets
for _, col := range cc.CollectionNames {
// Each collection we're interested in should exist in the principalSetsByCollectionName mapping.
Expand Down
5 changes: 2 additions & 3 deletions discovery/endorsement/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"testing"

"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policies"
Expand Down Expand Up @@ -98,7 +97,7 @@ func TestToIdentityFilter(t *testing.T) {
col2principals["foo"] = []*msp.MSPPrincipal{orgPrincipal("Org1MSP"), orgPrincipal("Org2MSP")}

t.Run("collection doesn't exist in mapping", func(t *testing.T) {
filter, err := col2principals.toIdentityFilter("mychannel", &principalEvaluatorMock{}, &discovery.ChaincodeCall{
filter, err := col2principals.toIdentityFilter("mychannel", &principalEvaluatorMock{}, &peer.ChaincodeCall{
Name: "mycc",
CollectionNames: []string{"bar"},
})
Expand All @@ -107,7 +106,7 @@ func TestToIdentityFilter(t *testing.T) {
})

t.Run("collection exists in mapping", func(t *testing.T) {
filter, err := col2principals.toIdentityFilter("mychannel", &principalEvaluatorMock{}, &discovery.ChaincodeCall{
filter, err := col2principals.toIdentityFilter("mychannel", &principalEvaluatorMock{}, &peer.ChaincodeCall{
Name: "mycc",
CollectionNames: []string{"foo"},
})
Expand Down
12 changes: 7 additions & 5 deletions discovery/endorsement/endorsement.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ package endorsement
import (
"fmt"

"github.com/hyperledger/fabric-protos-go/peer"

"github.com/hyperledger/fabric-protos-go/discovery"
"github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/common/chaincode"
Expand Down Expand Up @@ -79,7 +81,7 @@ func NewEndorsementAnalyzer(gs gossipSupport, pf policyFetcher, pe principalEval
type peerPrincipalEvaluator func(member gossipdiscovery.NetworkMember, principal *msp.MSPPrincipal) bool

// PeersForEndorsement returns an EndorsementDescriptor for a given set of peers, channel, and chaincode
func (ea *endorsementAnalyzer) PeersForEndorsement(channelID common.ChannelID, interest *discovery.ChaincodeInterest) (*discovery.EndorsementDescriptor, error) {
func (ea *endorsementAnalyzer) PeersForEndorsement(channelID common.ChannelID, interest *peer.ChaincodeInterest) (*discovery.EndorsementDescriptor, error) {
membersAndCC, err := ea.peersByCriteria(channelID, interest, false)
if err != nil {
return nil, errors.WithStack(err)
Expand Down Expand Up @@ -107,12 +109,12 @@ func (ea *endorsementAnalyzer) PeersForEndorsement(channelID common.ChannelID, i
})
}

func (ea *endorsementAnalyzer) PeersAuthorizedByCriteria(channelID common.ChannelID, interest *discovery.ChaincodeInterest) (gossipdiscovery.Members, error) {
func (ea *endorsementAnalyzer) PeersAuthorizedByCriteria(channelID common.ChannelID, interest *peer.ChaincodeInterest) (gossipdiscovery.Members, error) {
res, err := ea.peersByCriteria(channelID, interest, true)
return res.members, err
}

func (ea *endorsementAnalyzer) peersByCriteria(channelID common.ChannelID, interest *discovery.ChaincodeInterest, excludePeersWithoutChaincode bool) (membersChaincodeMapping, error) {
func (ea *endorsementAnalyzer) peersByCriteria(channelID common.ChannelID, interest *peer.ChaincodeInterest, excludePeersWithoutChaincode bool) (membersChaincodeMapping, error) {
peersOfChannel := ea.PeersOfChannel(channelID)
if interest == nil || len(interest.Chaincodes) == 0 {
return membersChaincodeMapping{members: peersOfChannel}, nil
Expand Down Expand Up @@ -214,7 +216,7 @@ func filterOutUnsatisfiedLayouts(endorsersByGroup map[string]*discovery.Peers, l
return filteredLayouts
}

func (ea *endorsementAnalyzer) computePrincipalSets(channelID common.ChannelID, interest *discovery.ChaincodeInterest) (policies.PrincipalSets, error) {
func (ea *endorsementAnalyzer) computePrincipalSets(channelID common.ChannelID, interest *peer.ChaincodeInterest) (policies.PrincipalSets, error) {
sessionLogger := logger.With("channel", string(channelID))
var inquireablePolicies []policies.InquireablePolicy
for _, chaincode := range interest.Chaincodes {
Expand Down Expand Up @@ -253,7 +255,7 @@ func (ea *endorsementAnalyzer) computePrincipalSets(channelID common.ChannelID,

type metadataAndFilterContext struct {
chainID common.ChannelID
interest *discovery.ChaincodeInterest
interest *peer.ChaincodeInterest
fetch chaincodeMetadataFetcher
identityInfoByID map[string]api.PeerIdentityInfo
evaluator principalEvaluator
Expand Down
Loading

0 comments on commit 84c1270

Please sign in to comment.