Skip to content

Commit

Permalink
Merge "[FAB-6387] Fix error code missing in endorser"
Browse files Browse the repository at this point in the history
  • Loading branch information
mastersingh24 authored and Gerrit Code Review committed Apr 30, 2018
2 parents 5892a4c + 916b42a commit 9015790
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 70 deletions.
39 changes: 13 additions & 26 deletions core/endorser/endorser.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@ import (
"golang.org/x/net/context"
)

// >>>>> begin errors section >>>>>
//chaincodeError is a fabric error signifying error from chaincode
type chaincodeError struct {
status int32
msg string
}

func (ce chaincodeError) Error() string {
return fmt.Sprintf("chaincode error (status: %d, message: %s)", ce.status, ce.msg)
}

// <<<<< end errors section <<<<<<

var endorserLogger = flogging.MustGetLogger("endorser")

// The Jira issue that documents Endorser flow along with its relationship to
Expand Down Expand Up @@ -424,7 +411,9 @@ func (e *Endorser) preProcess(signedProp *pb.SignedProposal) (*validateResult, e
if chainID != "" {
// here we handle uniqueness check and ACLs for proposals targeting a chain
if _, err = e.s.GetTransactionByID(chainID, txid); err == nil {
return vr, errors.Errorf("duplicate transaction found [%s]. Creator [%x]", txid, shdr.Creator)
err = errors.Errorf("duplicate transaction found [%s]. Creator [%x]", txid, shdr.Creator)
vr.resp = &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}
return vr, err
}

// check ACL only for application chaincodes; ACLs
Expand Down Expand Up @@ -469,10 +458,10 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro
var historyQueryExecutor ledger.HistoryQueryExecutor
if chainID != "" {
if txsim, err = e.s.GetTxSimulator(chainID, txid); err != nil {
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil
}
if historyQueryExecutor, err = e.s.GetHistoryQueryExecutor(chainID); err != nil {
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil
}
// Add the historyQueryExecutor to context
// TODO shouldn't we also add txsim to context here as well? Rather than passing txsim parameter
Expand All @@ -491,7 +480,7 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro
//1 -- simulate
cd, res, simulationResult, ccevent, err := e.simulateProposal(ctx, chainID, txid, signedProp, prop, hdrExt.ChaincodeId, txsim)
if err != nil {
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil
}
if res != nil {
if res.Status >= shim.ERROR {
Expand All @@ -505,10 +494,10 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro
}
pResp, err := putils.CreateProposalResponseFailure(prop.Header, prop.Payload, res, simulationResult, cceventBytes, hdrExt.ChaincodeId, hdrExt.PayloadVisibility)
if err != nil {
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil
}

return pResp, &chaincodeError{res.Status, res.Message}
return pResp, nil
}
}

Expand All @@ -522,20 +511,18 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro
} else {
pResp, err = e.endorseProposal(ctx, chainID, txid, signedProp, prop, res, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeId, txsim, cd)
if err != nil {
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err
return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil
}
if pResp != nil {
if res.Status >= shim.ERRORTHRESHOLD {
endorserLogger.Debugf("[%s][%s] endorseProposal() resulted in chaincode %s error for txid: %s", chainID, shorttxid(txid), hdrExt.ChaincodeId, txid)
return pResp, &chaincodeError{res.Status, res.Message}
}
if pResp.Response.Status >= shim.ERRORTHRESHOLD {
endorserLogger.Debugf("[%s][%s] endorseProposal() resulted in chaincode %s error for txid: %s", chainID, shorttxid(txid), hdrExt.ChaincodeId, txid)
return pResp, nil
}
}

// Set the proposal response payload - it
// contains the "return value" from the
// chaincode invocation
pResp.Response.Payload = res.Payload
pResp.Response = res

return pResp, nil
}
Expand Down
91 changes: 57 additions & 34 deletions core/endorser/endorser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ func TestEndorserNilProp(t *testing.T) {
GetTxSimulatorRv: &ccprovider.MockTxSim{&ledger.TxSimulationResults{PubSimulationResults: &rwset.TxReadWriteSet{}}},
})

_, err := es.ProcessProposal(context.Background(), nil)
pResp, err := es.ProcessProposal(context.Background(), nil)
assert.Error(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "nil arguments", pResp.Response.Message)
}

func TestEndorserUninvokableSysCC(t *testing.T) {
Expand All @@ -83,8 +85,10 @@ func TestEndorserUninvokableSysCC(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "chaincode ccid cannot be invoked through a proposal", pResp.Response.Message)
}

func TestEndorserCCInvocationFailed(t *testing.T) {
Expand All @@ -95,14 +99,16 @@ func TestEndorserCCInvocationFailed(t *testing.T) {
GetApplicationConfigRv: &mc.MockApplication{CapabilitiesRv: &mc.MockApplicationCapabilities{}},
GetTransactionByIDErr: errors.New(""),
ChaincodeDefinitionRv: &resourceconfig.MockChaincodeDefinition{EndorsementStr: "ESCC"},
ExecuteResp: &pb.Response{Status: 1000, Payload: utils.MarshalOrPanic(&pb.ProposalResponse{Response: &pb.Response{}})},
ExecuteResp: &pb.Response{Status: 1000, Payload: utils.MarshalOrPanic(&pb.ProposalResponse{Response: &pb.Response{}}), Message: "Chaincode Error"},
GetTxSimulatorRv: &ccprovider.MockTxSim{&ledger.TxSimulationResults{PubSimulationResults: &rwset.TxReadWriteSet{}}},
})

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 1000, pResp.Response.Status)
assert.Regexp(t, "Chaincode Error", pResp.Response.Message)
}

func TestEndorserNoCCDef(t *testing.T) {
Expand All @@ -119,8 +125,10 @@ func TestEndorserNoCCDef(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Regexp(t, "make sure the chaincode", pResp.Response.Message)
}

func TestEndorserBadInstPolicy(t *testing.T) {
Expand All @@ -138,8 +146,9 @@ func TestEndorserBadInstPolicy(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
}

func TestEndorserSysCC(t *testing.T) {
Expand All @@ -157,8 +166,9 @@ func TestEndorserSysCC(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 200, pResp.Response.Status)
}

func TestEndorserCCInvocationError(t *testing.T) {
Expand All @@ -175,8 +185,9 @@ func TestEndorserCCInvocationError(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
}

func TestEndorserLSCCBadType(t *testing.T) {
Expand All @@ -201,8 +212,10 @@ func TestEndorserLSCCBadType(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "Unknown chaincodeType: UNDEFINED", pResp.Response.Message)
}

func TestEndorserDupTXId(t *testing.T) {
Expand All @@ -218,8 +231,10 @@ func TestEndorserDupTXId(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Regexp(t, "duplicate transaction found", pResp.Response.Message)
}

func TestEndorserBadACL(t *testing.T) {
Expand All @@ -237,8 +252,9 @@ func TestEndorserBadACL(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
}

func TestEndorserGoodPathEmptyChannel(t *testing.T) {
Expand All @@ -255,8 +271,9 @@ func TestEndorserGoodPathEmptyChannel(t *testing.T) {

signedProp := getSignedPropWithCHIdAndArgs("", "ccid", "0", [][]byte{[]byte("args")}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 200, pResp.Response.Status)
}

func TestEndorserLSCCInitFails(t *testing.T) {
Expand All @@ -282,8 +299,9 @@ func TestEndorserLSCCInitFails(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
}

func TestEndorserLSCCDeploySysCC(t *testing.T) {
Expand Down Expand Up @@ -312,8 +330,10 @@ func TestEndorserLSCCDeploySysCC(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "attempting to deploy a system chaincode barf/testchainid", pResp.Response.Message)
}

func TestEndorserLSCCJava1(t *testing.T) {
Expand Down Expand Up @@ -343,8 +363,10 @@ func TestEndorserLSCCJava1(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "Java chaincode is work-in-progress and disabled", pResp.Response.Message)
}

func TestEndorserLSCCJava2(t *testing.T) {
Expand Down Expand Up @@ -374,8 +396,9 @@ func TestEndorserLSCCJava2(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
}

func TestEndorserGoodPathWEvents(t *testing.T) {
Expand All @@ -393,8 +416,9 @@ func TestEndorserGoodPathWEvents(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 200, pResp.Response.Status)
}

func TestEndorserBadChannel(t *testing.T) {
Expand All @@ -411,8 +435,10 @@ func TestEndorserBadChannel(t *testing.T) {

signedProp := getSignedPropWithCHID("ccid", "0", "barfchain", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.Error(t, err)
assert.EqualValues(t, 500, pResp.Response.Status)
assert.Equal(t, "access denied: channel [barfchain] creator org [SampleOrg]", pResp.Response.Message)
}

func TestEndorserGoodPath(t *testing.T) {
Expand All @@ -429,8 +455,9 @@ func TestEndorserGoodPath(t *testing.T) {

signedProp := getSignedProp("ccid", "0", t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 200, pResp.Response.Status)
}

func TestEndorserLSCC(t *testing.T) {
Expand All @@ -455,8 +482,9 @@ func TestEndorserLSCC(t *testing.T) {
)
signedProp := getSignedPropWithCHIdAndArgs(util.GetTestChainID(), "lscc", "0", [][]byte{[]byte("deploy"), []byte("a"), cds}, t)

_, err := es.ProcessProposal(context.Background(), signedProp)
pResp, err := es.ProcessProposal(context.Background(), signedProp)
assert.NoError(t, err)
assert.EqualValues(t, 200, pResp.Response.Status)
}

func TestSimulateProposal(t *testing.T) {
Expand Down Expand Up @@ -501,11 +529,6 @@ func TestEndorserJavaChecks(t *testing.T) {
assert.Error(t, err)
}

func TestChaincodeError_Error(t *testing.T) {
ce := &chaincodeError{status: 1, msg: "foo"}
assert.Equal(t, ce.Error(), "chaincode error (status: 1, message: foo)")
}

var signer msp.SigningIdentity

func TestMain(m *testing.M) {
Expand Down
2 changes: 1 addition & 1 deletion core/scc/escc/endorser_onevalidsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) pb.
}

if response.Status >= shim.ERRORTHRESHOLD {
return shim.Error(fmt.Sprintf("Status code less than %d will be endorsed, received status code: %d", shim.ERRORTHRESHOLD, response.Status))
return *response
}

// handle simulation results
Expand Down
6 changes: 3 additions & 3 deletions core/scc/escc/endorser_onevalidsignature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,14 @@ func TestInvoke(t *testing.T) {
// Failed path: status code = 500
args = [][]byte{[]byte("test"), []byte("test"), []byte("test"), ccidBytes, failRes, []byte("test")}
res := stub.MockInvoke("1", args)
assert.NotEqual(t, res.Status, shim.OK, "Invoke should have failed with status code: %d", ccFailResponse.Status)
assert.Contains(t, res.Message, fmt.Sprintf("Status code less than %d will be endorsed", shim.ERRORTHRESHOLD))
assert.NotEqual(t, res.Status, shim.OK, "Invoke should have failed with status code: %d", failResponse.Status)
assert.Equal(t, res, *failResponse)

// Failed path: status code = 400
args = [][]byte{[]byte("test"), []byte("test"), []byte("test"), ccidBytes, ccFailRes, []byte("test")}
res = stub.MockInvoke("1", args)
assert.NotEqual(t, res.Status, shim.OK, "Invoke should have failed with status code: %d", ccFailResponse.Status)
assert.Contains(t, res.Message, fmt.Sprintf("Status code less than %d will be endorsed", shim.ERRORTHRESHOLD))
assert.Equal(t, res, *ccFailResponse)

// Successful path - create a proposal
cs := &pb.ChaincodeSpec{
Expand Down
6 changes: 4 additions & 2 deletions peer/chaincode/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func chaincodeInvokeOrQuery(cmd *cobra.Command, invoke bool, cf *ChaincodeCmdFac
}

if invoke {
if proposalResp.Response.Status >= shim.ERROR {
if proposalResp.Response.Status >= shim.ERRORTHRESHOLD {
logger.Debugf("ESCC invoke result: %v", proposalResp)
pRespPayload, err := putils.GetProposalResponsePayload(proposalResp.Payload)
if err != nil {
Expand All @@ -140,6 +140,8 @@ func chaincodeInvokeOrQuery(cmd *cobra.Command, invoke bool, cf *ChaincodeCmdFac
} else {
if proposalResp == nil {
return fmt.Errorf("error query %s by endorsing: %s", chainFuncName, err)
} else if proposalResp.Response.Status >= shim.ERRORTHRESHOLD {
return fmt.Errorf("error query %s by endorsing: %s", chainFuncName, proposalResp.Response)
}

if chaincodeQueryRaw && chaincodeQueryHex {
Expand Down Expand Up @@ -473,7 +475,7 @@ func ChaincodeInvokeOrQuery(

if invoke {
if proposalResp != nil {
if proposalResp.Response.Status >= shim.ERROR {
if proposalResp.Response.Status >= shim.ERRORTHRESHOLD {
return proposalResp, nil
}
// assemble a signed transaction (it's an Envelope message)
Expand Down
Loading

0 comments on commit 9015790

Please sign in to comment.