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

Commit 6763ec7

Browse files
author
Pavan Kappara
committed
[FAB-8941]- extract matching logic from queryconfig
Extract Matching logic out of query configblock Change-Id: I6e5a748bbc63751053c6a41c9d8d999d0e40f7bd Signed-off-by: Pavan Kappara <pavan.kappara@securekey.com>
1 parent ec23384 commit 6763ec7

File tree

4 files changed

+85
-50
lines changed

4 files changed

+85
-50
lines changed

pkg/fab/channel/ledger.go

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,15 @@ func (c *Ledger) QueryBlockByHash(reqCtx reqContext.Context, blockHash []byte, t
8989
cir := createBlockByHashInvokeRequest(c.chName, blockHash)
9090
tprs, errs := queryChaincode(reqCtx, c.chName, cir, targets, verifier)
9191

92+
responses, errors := getConfigBlocks(tprs)
93+
errs = multi.Append(errs, errors)
94+
95+
return responses, errs
96+
}
97+
98+
func getConfigBlocks(tprs []*fab.TransactionProposalResponse) ([]*common.Block, error) {
9299
responses := []*common.Block{}
100+
var errs error
93101
for _, tpr := range tprs {
94102
r, err := createCommonBlock(tpr)
95103
if err != nil {
@@ -110,15 +118,8 @@ func (c *Ledger) QueryBlock(reqCtx reqContext.Context, blockNumber uint64, targe
110118
cir := createBlockByNumberInvokeRequest(c.chName, blockNumber)
111119
tprs, errs := queryChaincode(reqCtx, c.chName, cir, targets, verifier)
112120

113-
responses := []*common.Block{}
114-
for _, tpr := range tprs {
115-
r, err := createCommonBlock(tpr)
116-
if err != nil {
117-
errs = multi.Append(errs, errors.WithMessage(err, "From target: "+tpr.Endorser))
118-
} else {
119-
responses = append(responses, r)
120-
}
121-
}
121+
responses, errors := getConfigBlocks(tprs)
122+
errs = multi.Append(errs, errors)
122123
return responses, errs
123124
}
124125

@@ -190,50 +191,24 @@ func createChaincodeQueryResponse(tpr *fab.TransactionProposalResponse) (*pb.Cha
190191

191192
// QueryConfigBlock returns the current configuration block for the specified channel. If the
192193
// peer doesn't belong to the channel, return error
193-
func (c *Ledger) QueryConfigBlock(reqCtx reqContext.Context, targets []fab.ProposalProcessor, minResponses int, verifier ResponseVerifier) (*common.ConfigEnvelope, error) {
194+
func (c *Ledger) QueryConfigBlock(reqCtx reqContext.Context, targets []fab.ProposalProcessor, verifier ResponseVerifier) (*common.ConfigEnvelope, error) {
194195

195196
if len(targets) == 0 {
196197
return nil, errors.New("target(s) required")
197198
}
198199

199-
if minResponses <= 0 {
200-
return nil, errors.New("Minimum endorser has to be greater than zero")
201-
}
202-
203200
cir := createConfigBlockInvokeRequest(c.chName)
204201
tprs, err := queryChaincode(reqCtx, c.chName, cir, targets, verifier)
205202
if err != nil && len(tprs) == 0 {
206203
return nil, errors.WithMessage(err, "queryChaincode failed")
207204
}
208205

209-
if len(tprs) < minResponses {
210-
return nil, errors.Errorf("Required minimum %d endorsments got %d", minResponses, len(tprs))
211-
}
212-
213-
block, err := createCommonBlock(tprs[0])
214-
if err != nil {
215-
return nil, err
206+
matchErr := verifier.Match(tprs)
207+
if matchErr != nil {
208+
return nil, matchErr
216209
}
217210

218-
// Compare block data from remaining responses
219-
for _, tpr := range tprs[1:] {
220-
b, err := createCommonBlock(tpr)
221-
if err != nil {
222-
return nil, err
223-
}
224-
225-
if !proto.Equal(block.Data, b.Data) {
226-
return nil, errors.New("Payloads for config block do not match")
227-
}
228-
}
229-
230-
if block.Data == nil || block.Data.Data == nil {
231-
return nil, errors.New("config block data is nil")
232-
}
233-
234-
if len(block.Data.Data) != 1 {
235-
return nil, errors.New("config block must contain one transaction")
236-
}
211+
block, _ := createCommonBlock(tprs[0])
237212

238213
return createConfigEnvelope(block.Data.Data[0])
239214

pkg/fab/channel/ledger_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,19 @@ func TestQueryConfig(t *testing.T) {
125125
defer cancel()
126126

127127
// empty targets
128-
_, err := channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{}, 1, nil)
128+
_, err := channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{}, nil)
129129
if err == nil {
130130
t.Fatalf("Should have failed due to empty targets")
131131
}
132132

133133
// min endorsers <= 0
134-
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{mocks.NewMockPeer("Peer1", "http://peer1.com")}, 0, nil)
134+
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{mocks.NewMockPeer("Peer1", "http://peer1.com")}, &TransactionProposalResponseVerifier{})
135135
if err == nil {
136136
t.Fatalf("Should have failed due to empty targets")
137137
}
138138

139139
// peer without payload
140-
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{mocks.NewMockPeer("Peer1", "http://peer1.com")}, 1, nil)
140+
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{mocks.NewMockPeer("Peer1", "http://peer1.com")}, &TransactionProposalResponseVerifier{MinResponses: 1})
141141
if err == nil {
142142
t.Fatalf("Should have failed due to nil block metadata")
143143
}
@@ -166,13 +166,13 @@ func TestQueryConfig(t *testing.T) {
166166
peer := mocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, Payload: payload, Status: 200}
167167

168168
// fail with min endorsers
169-
res, err := channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer}, 2, nil)
169+
res, err := channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer}, &TransactionProposalResponseVerifier{MinResponses: 2})
170170
if err == nil {
171171
t.Fatalf("Should have failed with since there's one endorser and at least two are required")
172172
}
173173

174174
// success with one endorser
175-
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer}, 1, nil)
175+
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer}, &TransactionProposalResponseVerifier{MinResponses: 1})
176176
if err != nil || res == nil {
177177
t.Fatalf("Test QueryConfig failed: %v", err)
178178
}
@@ -181,7 +181,7 @@ func TestQueryConfig(t *testing.T) {
181181
peer2 := mocks.MockPeer{MockName: "Peer2", MockURL: "http://peer2.com", MockRoles: []string{}, MockCert: nil, Payload: payload, Status: 200}
182182

183183
// success with two endorsers
184-
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer, &peer2}, 2, nil)
184+
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer, &peer2}, &TransactionProposalResponseVerifier{MinResponses: 2})
185185
if err != nil || res == nil {
186186
t.Fatalf("Test QueryConfig failed: %v", err)
187187
}
@@ -207,7 +207,7 @@ func TestQueryConfig(t *testing.T) {
207207

208208
// peer 2 now had different payload; query config block should fail
209209
peer2.Payload = payload2
210-
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer, &peer2}, 2, nil)
210+
res, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer, &peer2}, &TransactionProposalResponseVerifier{MinResponses: 2})
211211
if err == nil {
212212
t.Fatalf("Should have failed for different block payloads")
213213
}
@@ -246,7 +246,7 @@ func TestQueryConfigBlockDifferentMetadata(t *testing.T) {
246246
reqCtx, cancel := context.NewRequest(setupContext(), context.WithTimeout(10*time.Second))
247247
defer cancel()
248248

249-
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer1, &peer2}, 2, nil)
249+
_, err = channel.QueryConfigBlock(reqCtx, []fab.ProposalProcessor{&peer1, &peer2}, &TransactionProposalResponseVerifier{MinResponses: 2})
250250
assert.Nil(t, err, "Expected success querying blocks with identical block data payloads")
251251
}
252252

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright SecureKey Technologies Inc. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package channel
8+
9+
import (
10+
"github.com/golang/protobuf/proto"
11+
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
12+
"github.com/pkg/errors"
13+
)
14+
15+
// TransactionProposalResponseVerifier struct is for verifying TransactionProposalResponse and matches config blocks
16+
type TransactionProposalResponseVerifier struct {
17+
MinResponses int
18+
}
19+
20+
// Verify checks transaction proposal response (empty)
21+
func (tprv *TransactionProposalResponseVerifier) Verify(response *fab.TransactionProposalResponse) error {
22+
return nil
23+
}
24+
25+
// Match verifies and matches transaction proposal responses
26+
func (tprv *TransactionProposalResponseVerifier) Match(transactionProposalResponses []*fab.TransactionProposalResponse) error {
27+
if tprv.MinResponses <= 0 {
28+
return errors.New("minimum Responses has to be greater than zero")
29+
}
30+
31+
if len(transactionProposalResponses) < tprv.MinResponses {
32+
return errors.Errorf("required minimum %d endorsments got %d", tprv.MinResponses, len(transactionProposalResponses))
33+
}
34+
35+
block, err := createCommonBlock(transactionProposalResponses[0])
36+
if err != nil {
37+
return err
38+
}
39+
40+
if block.Data == nil || block.Data.Data == nil {
41+
return errors.New("config block data is nil")
42+
}
43+
44+
if len(block.Data.Data) != 1 {
45+
return errors.New("config block must contain one transaction")
46+
}
47+
48+
// Compare block data from remaining responses
49+
for _, tpr := range transactionProposalResponses[1:] {
50+
b, err := createCommonBlock(tpr)
51+
if err != nil {
52+
return err
53+
}
54+
55+
if !proto.Equal(block.Data, b.Data) {
56+
return errors.New("payloads for config block do not match")
57+
}
58+
}
59+
60+
return nil
61+
}

pkg/fab/chconfig/chconfig.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,7 @@ func (c *ChannelConfig) queryPeers(reqCtx reqContext.Context) (*ChannelCfg, erro
156156
targets = peersToTxnProcessors(c.opts.Targets)
157157
}
158158

159-
// TODO: Verifier implementation Will be handled by different ticket
160-
configEnvelope, err := l.QueryConfigBlock(reqCtx, targets, c.opts.MinResponses, nil)
159+
configEnvelope, err := l.QueryConfigBlock(reqCtx, targets, &channel.TransactionProposalResponseVerifier{MinResponses: c.opts.MinResponses})
161160
if err != nil {
162161
return nil, errors.WithMessage(err, "QueryBlockConfig failed")
163162
}

0 commit comments

Comments
 (0)