Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 79f443e

Browse files
committed
[FAB-8300] Expose member mgmt through ChannelService
Change-Id: Iead4e5e51a084a1645bc043c36475b1376abe4cd Signed-off-by: Divyank Katira <Divyank.Katira@securekey.com>
1 parent 4dff6ab commit 79f443e

File tree

19 files changed

+381
-223
lines changed

19 files changed

+381
-223
lines changed

pkg/client/channel/chclient.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ import (
1111
"reflect"
1212
"time"
1313

14-
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
15-
1614
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
1715
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery"
1816
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery/greylist"
1917
"github.com/hyperledger/fabric-sdk-go/pkg/context"
18+
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
2019
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
2120
"github.com/hyperledger/fabric-sdk-go/pkg/errors/multi"
2221
"github.com/hyperledger/fabric-sdk-go/pkg/errors/retry"
@@ -40,7 +39,7 @@ type Client struct {
4039
context context.ProviderContext
4140
discovery fab.DiscoveryService
4241
selection fab.SelectionService
43-
channel fab.Channel
42+
membership fab.ChannelMembership
4443
transactor fab.Transactor
4544
eventHub fab.EventHub
4645
greylist *greylist.Filter
@@ -68,18 +67,17 @@ func New(c Context) (*Client, error) {
6867
return nil, errors.WithMessage(err, "transactor creation failed")
6968
}
7069

71-
// TODO - this should be removed once MSP is split out.
72-
channel, err := c.ChannelService.Channel()
70+
membership, err := c.ChannelService.Membership()
7371
if err != nil {
74-
return nil, errors.WithMessage(err, "channel client creation failed")
72+
return nil, errors.WithMessage(err, "membership creation failed")
7573
}
7674

7775
channelClient := Client{
7876
greylist: greylistProvider,
7977
context: c,
8078
discovery: discovery.NewDiscoveryFilterService(c.DiscoveryService, greylistProvider),
8179
selection: c.SelectionService,
82-
channel: channel,
80+
membership: membership,
8381
transactor: transactor,
8482
eventHub: eventHub,
8583
}
@@ -162,7 +160,7 @@ func (cc *Client) prepareHandlerContexts(request Request, o opts) (*invoke.Reque
162160
clientContext := &invoke.ClientContext{
163161
Selection: cc.selection,
164162
Discovery: cc.discovery,
165-
Channel: cc.channel,
163+
Membership: cc.membership,
166164
Transactor: cc.transactor,
167165
EventHub: cc.eventHub,
168166
}

pkg/client/channel/invoke/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type ClientContext struct {
5050
CryptoSuite core.CryptoSuite
5151
Discovery fab.DiscoveryService
5252
Selection fab.SelectionService
53-
Channel fab.Channel // TODO: this should be removed when we have MSP split out.
53+
Membership fab.ChannelMembership
5454
Transactor fab.Transactor
5555
EventHub fab.EventHub
5656
}

pkg/client/channel/invoke/signature.go

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@ SPDX-License-Identifier: Apache-2.0
77
package invoke
88

99
import (
10+
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1011
"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
1112

12-
"github.com/golang/protobuf/proto"
13-
1413
"github.com/pkg/errors"
1514

16-
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1715
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
18-
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/msp"
1916
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
2017
)
2118

@@ -31,7 +28,6 @@ type SignatureValidationHandler struct {
3128

3229
//Handle for Filtering proposal response
3330
func (f *SignatureValidationHandler) Handle(requestContext *RequestContext, clientContext *ClientContext) {
34-
3531
//Filter tx proposal responses
3632
err := f.validate(requestContext.Response.Responses, clientContext)
3733
if err != nil {
@@ -46,7 +42,6 @@ func (f *SignatureValidationHandler) Handle(requestContext *RequestContext, clie
4642
}
4743

4844
func (f *SignatureValidationHandler) validate(txProposalResponse []*fab.TransactionProposalResponse, ctx *ClientContext) error {
49-
5045
for _, r := range txProposalResponse {
5146
if r.ProposalResponse.GetResponse().Status != int32(common.Status_SUCCESS) {
5247
return status.NewFromProposalResponse(r.ProposalResponse, r.Endorser)
@@ -58,45 +53,15 @@ func (f *SignatureValidationHandler) validate(txProposalResponse []*fab.Transact
5853
}
5954

6055
return nil
61-
6256
}
6357

6458
func verifyProposalResponse(res *pb.ProposalResponse, ctx *ClientContext) error {
65-
6659
if res.GetEndorsement() == nil {
6760
return errors.Errorf("Missing endorsement in proposal response")
6861
}
62+
creatorID := res.GetEndorsement().Endorser
6963

70-
serializedIdentity := &msp.SerializedIdentity{}
71-
if err := proto.Unmarshal(res.GetEndorsement().Endorser, serializedIdentity); err != nil {
72-
return errors.WithMessage(err, "Unmarshal endorser error")
73-
}
74-
75-
// TODO ctx.Channel is temporary and needs to be replaced with an MSP interface from channel service.
76-
if ctx.Channel.MSPManager() == nil {
77-
return errors.Errorf("Channel %s msp manager is nil", ctx.Channel.Name())
78-
}
79-
80-
msps, err := ctx.Channel.MSPManager().GetMSPs()
81-
if err != nil {
82-
return errors.WithMessage(err, "GetMSPs return error:%v")
83-
}
84-
if len(msps) == 0 {
85-
return errors.Errorf("Channel %s msps is empty", ctx.Channel.Name())
86-
}
87-
88-
msp := msps[serializedIdentity.Mspid]
89-
if msp == nil {
90-
return errors.Errorf("MSP %s not found", serializedIdentity.Mspid)
91-
}
92-
93-
creator, err := msp.DeserializeIdentity(res.GetEndorsement().Endorser)
94-
if err != nil {
95-
return errors.WithMessage(err, "Failed to deserialize creator identity")
96-
}
97-
98-
// ensure that creator is a valid certificate
99-
err = creator.Validate()
64+
err := ctx.Membership.Validate(creatorID)
10065
if err != nil {
10166
return errors.WithMessage(err, "The creator certificate is not valid")
10267
}
@@ -105,7 +70,7 @@ func verifyProposalResponse(res *pb.ProposalResponse, ctx *ClientContext) error
10570
digest := append(res.GetPayload(), res.GetEndorsement().Endorser...)
10671

10772
// validate the signature
108-
err = creator.Verify(digest, res.GetEndorsement().Signature)
73+
err = ctx.Membership.Verify(creatorID, digest, res.GetEndorsement().Signature)
10974
if err != nil {
11075
return errors.WithMessage(err, "The creator's signature over the proposal is not valid")
11176
}

pkg/client/channel/invoke/signature_test.go

Lines changed: 14 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import (
1111
"strings"
1212
"testing"
1313

14-
"github.com/stretchr/testify/assert"
15-
16-
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/msp"
1714
txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/client/common/mocks"
1815
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1916
fcmocks "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
17+
"github.com/stretchr/testify/assert"
2018
)
2119

2220
func TestSignatureValidationHandlerSuccess(t *testing.T) {
@@ -27,97 +25,29 @@ func TestSignatureValidationHandlerSuccess(t *testing.T) {
2725

2826
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
2927

30-
// Add mock msp to msp manager
31-
msps := make(map[string]msp.MSP)
32-
msps["Org1MSP"] = fcmocks.NewMockMSP(nil)
33-
34-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
28+
clientContext := setupContextForSignatureValidation(nil, nil, []fab.Peer{mockPeer1}, t)
3529

3630
handler := NewQueryHandler()
3731
handler.Handle(requestContext, clientContext)
3832
assert.Nil(t, requestContext.Error)
3933
}
4034

41-
func TestSignatureValidationMspErrors(t *testing.T) {
42-
43-
// Sample request
44-
request := Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}
45-
requestContext := prepareRequestContext(request, Opts{}, t)
46-
handler := NewQueryHandler()
47-
48-
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
49-
50-
// Test #1: GetMSPs error
51-
msps := make(map[string]msp.MSP)
52-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManagerWithError(msps, errors.New("GetMSPs")), []fab.Peer{mockPeer1}, t)
53-
handler.Handle(requestContext, clientContext)
54-
verifyExpectedError(requestContext, "GetMSPs return error", t)
55-
56-
// Test #2: MPS manager has no mps
57-
clientContext = setupContextForSignatureValidation(fcmocks.NewMockMSPManager(nil), []fab.Peer{mockPeer1}, t)
58-
handler.Handle(requestContext, clientContext)
59-
verifyExpectedError(requestContext, "is empty", t)
60-
61-
// Test #3: MSP not found
62-
msps = make(map[string]msp.MSP)
63-
msps["NotOrg1MSP"] = fcmocks.NewMockMSP(nil)
64-
clientContext = setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
65-
handler.Handle(requestContext, clientContext)
66-
verifyExpectedError(requestContext, "not found", t)
67-
}
68-
69-
func TestSignatureValidationUnmarshallEndorserError(t *testing.T) {
70-
71-
// Sample request
72-
request := Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}
73-
requestContext := prepareRequestContext(request, Opts{}, t)
74-
handler := NewQueryHandler()
75-
76-
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
77-
78-
// Unmarshall endorser error
79-
msps := make(map[string]msp.MSP)
80-
msps["Org1MSP"] = fcmocks.NewMockMSP(nil)
81-
mockPeer1.Endorser = []byte("Invalid")
82-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
83-
handler.Handle(requestContext, clientContext)
84-
verifyExpectedError(requestContext, "Unmarshal endorser error", t)
85-
86-
}
87-
88-
func TestSignatureValidationDeserializeIdentityError(t *testing.T) {
89-
90-
// Sample request
91-
request := Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}
92-
requestContext := prepareRequestContext(request, Opts{}, t)
93-
handler := NewQueryHandler()
94-
95-
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
96-
97-
msps := make(map[string]msp.MSP)
98-
msps["Org1MSP"] = fcmocks.NewMockMSP(errors.New("DeserializeIdentity"))
99-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
100-
handler.Handle(requestContext, clientContext)
101-
verifyExpectedError(requestContext, "Failed to deserialize creator identity", t)
102-
}
103-
10435
func TestSignatureValidationCreatorValidateError(t *testing.T) {
105-
36+
validateErr := errors.New("ValidateErr")
10637
// Sample request
10738
request := Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}
10839
requestContext := prepareRequestContext(request, Opts{}, t)
10940
handler := NewQueryHandler()
11041

11142
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
11243

113-
msps := make(map[string]msp.MSP)
114-
msps["Org1MSP"] = fcmocks.NewMockMSP(errors.New("Validate"))
115-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
44+
clientContext := setupContextForSignatureValidation(nil, validateErr, []fab.Peer{mockPeer1}, t)
11645
handler.Handle(requestContext, clientContext)
117-
verifyExpectedError(requestContext, "The creator certificate is not valid", t)
46+
verifyExpectedError(requestContext, validateErr.Error(), t)
11847
}
11948

12049
func TestSignatureValidationCreatorVerifyError(t *testing.T) {
50+
verifyErr := errors.New("Verify")
12151

12252
// Sample request
12353
request := Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}
@@ -126,11 +56,9 @@ func TestSignatureValidationCreatorVerifyError(t *testing.T) {
12656

12757
mockPeer1 := &fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, MockMSP: "Org1MSP", Status: 200, Payload: []byte("value")}
12858

129-
msps := make(map[string]msp.MSP)
130-
msps["Org1MSP"] = fcmocks.NewMockMSP(errors.New("Verify"))
131-
clientContext := setupContextForSignatureValidation(fcmocks.NewMockMSPManager(msps), []fab.Peer{mockPeer1}, t)
59+
clientContext := setupContextForSignatureValidation(verifyErr, nil, []fab.Peer{mockPeer1}, t)
13260
handler.Handle(requestContext, clientContext)
133-
verifyExpectedError(requestContext, "The creator's signature over the proposal is not valid", t)
61+
verifyExpectedError(requestContext, verifyErr.Error(), t)
13462
}
13563

13664
func verifyExpectedError(requestContext *RequestContext, expected string, t *testing.T) {
@@ -140,17 +68,11 @@ func verifyExpectedError(requestContext *RequestContext, expected string, t *tes
14068
}
14169
}
14270

143-
func setupContextForSignatureValidation(mspMgr *fcmocks.MockMSPManager, peers []fab.Peer, t *testing.T) *ClientContext {
144-
145-
testChannel, err := setupTestChannel()
146-
if err != nil {
147-
t.Fatalf("Failed to setup test channel: %s", err)
148-
}
149-
150-
testChannel.SetMSPManager(mspMgr)
151-
152-
orderer := fcmocks.NewMockOrderer("", nil)
153-
testChannel.AddOrderer(orderer)
71+
func setupContextForSignatureValidation(verifyErr, validateErr error, peers []fab.Peer, t *testing.T) *ClientContext {
72+
ctx := setupTestContext()
73+
membership := fcmocks.NewMockMembership()
74+
membership.ValidateErr = validateErr
75+
membership.VerifyErr = verifyErr
15476

15577
discoveryService, err := setupTestDiscovery(nil, nil)
15678
if err != nil {
@@ -162,36 +84,16 @@ func setupContextForSignatureValidation(mspMgr *fcmocks.MockMSPManager, peers []
16284
t.Fatalf("Failed to setup discovery service: %s", err)
16385
}
16486

165-
ctx := setupTestContext()
16687
transactor := txnmocks.MockTransactor{
16788
Ctx: ctx,
16889
ChannelID: "",
16990
}
17091

17192
return &ClientContext{
172-
Channel: testChannel,
93+
Membership: membership,
17394
Discovery: discoveryService,
17495
Selection: selectionService,
17596
Transactor: &transactor,
17697
}
17798

17899
}
179-
180-
var certPem = `-----BEGIN CERTIFICATE-----
181-
MIIC5TCCAkagAwIBAgIUMYhiY5MS3jEmQ7Fz4X/e1Dx33J0wCgYIKoZIzj0EAwQw
182-
gYwxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMRAwDgYDVQQHEwdUb3Jv
183-
bnRvMREwDwYDVQQKEwhsaW51eGN0bDEMMAoGA1UECxMDTGFiMTgwNgYDVQQDEy9s
184-
aW51eGN0bCBFQ0MgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAoTGFiKTAe
185-
Fw0xNzEyMDEyMTEzMDBaFw0xODEyMDEyMTEzMDBaMGMxCzAJBgNVBAYTAkNBMRAw
186-
DgYDVQQIEwdPbnRhcmlvMRAwDgYDVQQHEwdUb3JvbnRvMREwDwYDVQQKEwhsaW51
187-
eGN0bDEMMAoGA1UECxMDTGFiMQ8wDQYDVQQDDAZzZGtfZ28wdjAQBgcqhkjOPQIB
188-
BgUrgQQAIgNiAAT6I1CGNrkchIAEmeJGo53XhDsoJwRiohBv2PotEEGuO6rMyaOu
189-
pulj2VOj+YtgWw4ZtU49g4Nv6rq1QlKwRYyMwwRJSAZHIUMhYZjcDi7YEOZ3Fs1h
190-
xKmIxR+TTR2vf9KjgZAwgY0wDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG
191-
AQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDwS3xhpAWs81OVWvZt+iUNL
192-
z26DMB8GA1UdIwQYMBaAFLRasbknomawJKuQGiyKs/RzTCujMBgGA1UdEQQRMA+C
193-
DWZhYnJpY19zZGtfZ28wCgYIKoZIzj0EAwQDgYwAMIGIAkIAk1MxMogtMtNO0rM8
194-
gw2rrxqbW67ulwmMQzp6EJbm/28T2pIoYWWyIwpzrquypI7BOuf8is5b7Jcgn9oz
195-
7sdMTggCQgF7/8ZFl+wikAAPbciIL1I+LyCXKwXosdFL6KMT6/myYjsGNeeDeMbg
196-
3YkZ9DhdH1tN4U/h+YulG/CkKOtUATtQxg==
197-
-----END CERTIFICATE-----`

0 commit comments

Comments
 (0)