Skip to content

Commit

Permalink
[FAB-9062] set the response status on chaincode success
Browse files Browse the repository at this point in the history
Change-Id: I84b16cbcd8c7275670bbe3174c2aed41b58dbd30
Signed-off-by: Pavan Kappara <[email protected]>
  • Loading branch information
Pavan Kappara committed Mar 23, 2018
1 parent 8757ff3 commit 02c85b3
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 3 deletions.
4 changes: 3 additions & 1 deletion pkg/client/channel/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ type Response struct {
TransactionID fab.TransactionID
TxValidationCode pb.TxValidationCode
Proposal *fab.TransactionProposal
Responses []*fab.TransactionProposalResponse
// ChaincodeStatus is the status returned by Chaincode
ChaincodeStatus int32
Responses []*fab.TransactionProposalResponse
}

//WithTargets encapsulates ProposalProcessors to Option
Expand Down
4 changes: 3 additions & 1 deletion pkg/client/channel/invoke/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ type Response struct {
TransactionID fab.TransactionID
TxValidationCode pb.TxValidationCode
Proposal *fab.TransactionProposal
Responses []*fab.TransactionProposalResponse
// ChaincodeStatus is the status returned by Chaincode
ChaincodeStatus int32
Responses []*fab.TransactionProposalResponse
}

//Handler for chaining transaction executions
Expand Down
2 changes: 2 additions & 0 deletions pkg/client/channel/invoke/txnhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func (e *EndorsementHandler) Handle(requestContext *RequestContext, clientContex
requestContext.Response.Responses = transactionProposalResponses
if len(transactionProposalResponses) > 0 {
requestContext.Response.Payload = transactionProposalResponses[0].ProposalResponse.GetResponse().Payload
requestContext.Response.ChaincodeStatus = transactionProposalResponses[0].ChaincodeStatus
}

//Delegate to next step if any
Expand Down Expand Up @@ -255,5 +256,6 @@ func createAndSendTransactionProposal(transactor fab.ProposalSender, chrequest *
}

transactionProposalResponses, err := transactor.SendTransactionProposal(proposal, targets)

return transactionProposalResponses, proposal, err
}
5 changes: 4 additions & 1 deletion pkg/common/providers/fab/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ type ProcessProposalRequest struct {
// TransactionProposalResponse respresents the result of transaction proposal processing.
type TransactionProposalResponse struct {
Endorser string
Status int32
// Status is the EndorserStatus
Status int32
// ChaincodeStatus is the status returned by Chaincode
ChaincodeStatus int32
*pb.ProposalResponse
}
15 changes: 15 additions & 0 deletions pkg/fab/peer/peerendorser.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/comm"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint"
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
protos_utils "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/utils"
)

const (
Expand Down Expand Up @@ -104,6 +105,7 @@ func (p *peerEndorser) ProcessTransactionProposal(ctx reqContext.Context, reques
tpr := fab.TransactionProposalResponse{
ProposalResponse: proposalResponse,
Endorser: p.target,
ChaincodeStatus: getChaincodeResponseStatus(proposalResponse),
Status: proposalResponse.GetResponse().Status,
}
return &tpr, nil
Expand Down Expand Up @@ -143,6 +145,7 @@ func (p *peerEndorser) sendProposal(ctx reqContext.Context, proposal fab.Process

endorserClient := pb.NewEndorserClient(conn)
resp, err := endorserClient.ProcessProposal(ctx, proposal.SignedProposal)

if err != nil {
logger.Errorf("process proposal failed [%s]", err)
rpcStatus, ok := grpcstatus.FromError(err)
Expand Down Expand Up @@ -194,3 +197,15 @@ func extractChaincodeError(status *grpcstatus.Status) (int, string, error) {
}
return code, message, errors.Errorf("Unable to parse GRPC Status Message Code: %v Message: %v", code, message)
}

// getChaincodeResponseStatus gets the actual response status from response.Payload.extension.Response.status, as fabric always returns actual 200
func getChaincodeResponseStatus(response *pb.ProposalResponse) int32 {
if response.Payload != nil {
payload, _ := protos_utils.GetProposalResponsePayload(response.Payload)
extension, _ := protos_utils.GetChaincodeAction(payload.Extension)
if extension != nil && extension.Response != nil {
return extension.Response.Status
}
}
return response.Response.Status
}
16 changes: 16 additions & 0 deletions test/integration/orgs/multiple_orgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int {
}
initial, _ := strconv.Atoi(string(response.Payload))

if response.ChaincodeStatus == 0 {
t.Fatalf("Expected ChaincodeStatus")
}

if response.Responses[0].ChaincodeStatus != response.ChaincodeStatus {
t.Fatalf("Expected the chaincode status returned by successful Peer Endorsement to be same as Chaincode status for client response")
}

// Ledger client will verify blockchain info
ledgerClient, err := ledger.New(org1AdminChannelContext)

Expand Down Expand Up @@ -262,6 +270,14 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int {
t.Fatalf("Failed to move funds: %s", err)
}

if response.ChaincodeStatus == 0 {
t.Fatalf("Expected ChaincodeStatus")
}

if response.Responses[0].ChaincodeStatus != response.ChaincodeStatus {
t.Fatalf("Expected the chaincode status returned by successful Peer Endorsement to be same as Chaincode status for client response")
}

// Assert that funds have changed value on org1 peer
verifyValue(t, chClientOrg1User, initial+1)

Expand Down

0 comments on commit 02c85b3

Please sign in to comment.