Skip to content

Commit

Permalink
[FAB-7606] Validate endorser payload and status
Browse files Browse the repository at this point in the history
Change-Id: I926fb17b97874af0ac3e2dd64c18dbe845a95e3d
Signed-off-by: Firas Qutishat <[email protected]>
  • Loading branch information
fqutishat committed Jan 4, 2018
1 parent c0080e2 commit 2c40482
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 39 deletions.
4 changes: 2 additions & 2 deletions pkg/fabric-client/channel/txnproposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func TestAddPeerDuplicateCheck(t *testing.T) {
func TestSendTransactionProposal(t *testing.T) {
channel, _ := setupTestChannel()

peer := mocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, Payload: []byte("A")}
peer := mocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil, Status: 200, Payload: []byte("A")}
channel.AddPeer(&peer)

request := apitxn.ChaincodeInvokeRequest{
Expand All @@ -185,7 +185,7 @@ func TestSendTransactionProposal(t *testing.T) {
if err != nil {
t.Fatalf("Failed to send transaction proposal: %s", err)
}
expectedTpr := &pb.ProposalResponse{Response: &pb.Response{Message: "success", Status: 99, Payload: []byte("A")}}
expectedTpr := &pb.ProposalResponse{Response: &pb.Response{Message: "success", Status: 200, Payload: []byte("A")}}

if txnid.ID != "1234" || !reflect.DeepEqual(tpr[0].ProposalResponse, expectedTpr) {
t.Fatalf("Unexpected transaction proposal response: %v, %v", tpr, txnid)
Expand Down
18 changes: 0 additions & 18 deletions pkg/fabric-client/channel/txnsender.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,6 @@ func (c *Channel) CreateTransaction(resps []*apitxn.TransactionProposalResponse)
return nil, err
}

// This code is commented out because the ProposalResponsePayload Extension ChaincodeAction Results
// return from endorsements is different so the compare will fail

// var a1 []byte
// for n, r := range resps {
// if n == 0 {
// a1 = r.Payload
// if r.Response.Status != 200 {
// return nil, errors.Errorf("proposal response was not successful, error code %d, msg %s", r.Response.Status, r.Response.Message)
// }
// continue
// }

// if bytes.Compare(a1, r.Payload) != 0 {
// return nil, errors.New("ProposalResponsePayloads do not match")
// }
// }

for _, r := range resps {
if r.ProposalResponse.Response.Status != 200 {
return nil, errors.Errorf("proposal response was not successful, error code %d, msg %s", r.ProposalResponse.Response.Status, r.ProposalResponse.Response.Message)
Expand Down
5 changes: 3 additions & 2 deletions pkg/fabric-client/mocks/mockpeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ type MockPeer struct {
MockCert *pem.Block
Payload []byte
MockMSP string
Status int32
}

// NewMockPeer creates basic mock peer
func NewMockPeer(name string, url string) *MockPeer {
mp := &MockPeer{MockName: name, MockURL: url}
mp := &MockPeer{MockName: name, MockURL: url, Status: 200}
return mp
}

Expand Down Expand Up @@ -80,7 +81,7 @@ func (p *MockPeer) ProcessTransactionProposal(tp apitxn.TransactionProposal) (ap
return apitxn.TransactionProposalResult{
Endorser: p.MockURL,
Proposal: tp,
ProposalResponse: &pb.ProposalResponse{Response: &pb.Response{Message: "success", Status: 99, Payload: p.Payload}},
ProposalResponse: &pb.ProposalResponse{Response: &pb.Response{Message: "success", Status: p.Status, Payload: p.Payload}},
}, nil

}
16 changes: 16 additions & 0 deletions pkg/fabric-txn/chclient/chclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0
package chclient

import (
"bytes"
"reflect"
"time"

Expand Down Expand Up @@ -36,6 +37,21 @@ type txProposalResponseFilter struct {

// ProcessTxProposalResponse process transaction proposal response
func (txProposalResponseFilter *txProposalResponseFilter) ProcessTxProposalResponse(txProposalResponse []*apitxn.TransactionProposalResponse) ([]*apitxn.TransactionProposalResponse, error) {
var a1 []byte
for n, r := range txProposalResponse {
if r.ProposalResponse.GetResponse().Status != 200 {
return nil, errors.Errorf("proposal response was not successful, error code %d, msg %s", r.ProposalResponse.GetResponse().Status, r.ProposalResponse.GetResponse().Message)
}
if n == 0 {
a1 = r.ProposalResponse.GetResponse().Payload
continue
}

if bytes.Compare(a1, r.ProposalResponse.GetResponse().Payload) != 0 {
return nil, errors.Errorf("ProposalResponsePayloads do not match")
}
}

return txProposalResponse, nil
}

Expand Down
61 changes: 46 additions & 15 deletions pkg/fabric-txn/chclient/chclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package chclient

import (
"strings"
"testing"
"time"

Expand All @@ -20,9 +21,39 @@ import (
txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/mocks"
)

func TestTxProposalResponseFilter(t *testing.T) {
// failed if status not 200
testPeer1 := fcmocks.NewMockPeer("Peer1", "http://peer1.com")
testPeer2 := fcmocks.NewMockPeer("Peer2", "http://peer2.com")
testPeer2.Status = 300
peers := []apifabclient.Peer{testPeer1, testPeer2}
chClient := setupChannelClient(peers, t)

_, err := chClient.Query(apitxn.QueryRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}})
if err == nil {
t.Fatalf("Should have failed for not success status")
}
if !strings.Contains(err.Error(), "proposal response was not successful, error code 300") {
t.Fatalf("Return wrong error message %v", err)
}

testPeer2.Payload = []byte("wrongPayload")
testPeer2.Status = 200
peers = []apifabclient.Peer{testPeer1, testPeer2}
chClient = setupChannelClient(peers, t)
_, err = chClient.Query(apitxn.QueryRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}})
if err == nil {
t.Fatalf("Should have failed for not success status")
}
if !strings.Contains(err.Error(), "ProposalResponsePayloads do not match") {
t.Fatalf("Return wrong error message %v", err)
}

}

func TestQuery(t *testing.T) {

chClient := setupChannelClient(t)
chClient := setupChannelClient(nil, t)

result, err := chClient.Query(apitxn.QueryRequest{})
if err == nil {
Expand Down Expand Up @@ -52,7 +83,7 @@ func TestQuery(t *testing.T) {

func TestQueryDiscoveryError(t *testing.T) {

chClient := setupChannelClientWithError(errors.New("Test Error"), nil, t)
chClient := setupChannelClientWithError(errors.New("Test Error"), nil, nil, t)

_, err := chClient.Query(apitxn.QueryRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}})
if err == nil {
Expand All @@ -63,7 +94,7 @@ func TestQueryDiscoveryError(t *testing.T) {

func TestQuerySelectionError(t *testing.T) {

chClient := setupChannelClientWithError(nil, errors.New("Test Error"), t)
chClient := setupChannelClientWithError(nil, errors.New("Test Error"), nil, t)

_, err := chClient.Query(apitxn.QueryRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}})
if err == nil {
Expand All @@ -74,7 +105,7 @@ func TestQuerySelectionError(t *testing.T) {

func TestQueryWithOptSync(t *testing.T) {

chClient := setupChannelClient(t)
chClient := setupChannelClient(nil, t)

result, err := chClient.QueryWithOpts(apitxn.QueryRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}}, apitxn.QueryOpts{})
if err != nil {
Expand All @@ -88,7 +119,7 @@ func TestQueryWithOptSync(t *testing.T) {

func TestQueryWithOptAsync(t *testing.T) {

chClient := setupChannelClient(t)
chClient := setupChannelClient(nil, t)

notifier := make(chan apitxn.QueryResponse)

Expand Down Expand Up @@ -117,11 +148,11 @@ func TestQueryWithOptAsync(t *testing.T) {

func TestQueryWithOptTarget(t *testing.T) {

chClient := setupChannelClient(t)
chClient := setupChannelClient(nil, t)

testPeer := fcmocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil}
testPeer := fcmocks.NewMockPeer("Peer1", "http://peer1.com")

peers := []apifabclient.Peer{&testPeer}
peers := []apifabclient.Peer{testPeer}

targets := peer.PeersToTxnProcessors(peers)

Expand All @@ -137,7 +168,7 @@ func TestQueryWithOptTarget(t *testing.T) {

func TestExecuteTx(t *testing.T) {

chClient := setupChannelClient(t)
chClient := setupChannelClient(nil, t)

_, err := chClient.ExecuteTx(apitxn.ExecuteTxRequest{})
if err == nil {
Expand All @@ -159,7 +190,7 @@ func TestExecuteTx(t *testing.T) {

func TestExecuteTxDiscoveryError(t *testing.T) {

chClient := setupChannelClientWithError(errors.New("Test Error"), nil, t)
chClient := setupChannelClientWithError(errors.New("Test Error"), nil, nil, t)

_, err := chClient.ExecuteTx(apitxn.ExecuteTxRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("move"), []byte("a"), []byte("b"), []byte("1")}})
if err == nil {
Expand All @@ -170,7 +201,7 @@ func TestExecuteTxDiscoveryError(t *testing.T) {

func TestExecuteTxSelectionError(t *testing.T) {

chClient := setupChannelClientWithError(nil, errors.New("Test Error"), t)
chClient := setupChannelClientWithError(nil, errors.New("Test Error"), nil, t)

_, err := chClient.ExecuteTx(apitxn.ExecuteTxRequest{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("move"), []byte("a"), []byte("b"), []byte("1")}})
if err == nil {
Expand Down Expand Up @@ -214,12 +245,12 @@ func setupTestSelection(discErr error, peers []apifabclient.Peer) (apifabclient.
return mockSelection.NewSelectionService("mychannel")
}

func setupChannelClient(t *testing.T) *ChannelClient {
func setupChannelClient(peers []apifabclient.Peer, t *testing.T) *ChannelClient {

return setupChannelClientWithError(nil, nil, t)
return setupChannelClientWithError(nil, nil, peers, t)
}

func setupChannelClientWithError(discErr error, selectionErr error, t *testing.T) *ChannelClient {
func setupChannelClientWithError(discErr error, selectionErr error, peers []apifabclient.Peer, t *testing.T) *ChannelClient {

fcClient := setupTestClient()

Expand All @@ -236,7 +267,7 @@ func setupChannelClientWithError(discErr error, selectionErr error, t *testing.T
t.Fatalf("Failed to setup discovery service: %s", err)
}

selectionService, err := setupTestSelection(selectionErr, nil)
selectionService, err := setupTestSelection(selectionErr, peers)
if err != nil {
t.Fatalf("Failed to setup discovery service: %s", err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fabric-txn/mocks/mockselection.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ func (ds *MockSelectionService) GetEndorsersForChaincode(channelPeers []apifabcl
}

if ds.Peers == nil {
mockPeer := mocks.MockPeer{MockName: "Peer1", MockURL: "http://peer1.com", MockRoles: []string{}, MockCert: nil}
mockPeer := mocks.NewMockPeer("Peer1", "http://peer1.com")
peers := make([]apifabclient.Peer, 0)
peers = append(peers, &mockPeer)
peers = append(peers, mockPeer)
ds.Peers = peers
}

Expand Down

0 comments on commit 2c40482

Please sign in to comment.