Skip to content

Commit

Permalink
[FAB-5458] wrong type check in validator
Browse files Browse the repository at this point in the history
Validator is sending peer.TxValidationCode_INVALID_OTHER_REASON instead of
peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE due to a wrong type check.

Added UT to cover the switch and ensure correct tx flag been assigned.

Change-Id: I7abe8828323780d527b24905f54d9a06e5f70b4e
Signed-off-by: Srinivasan Muralidharan <muralisr@us.ibm.com>
Signed-off-by: Artem Barger <bartem@il.ibm.com>
  • Loading branch information
Srinivasan Muralidharan authored and C0rWin committed Jul 26, 2017
1 parent e5b46d1 commit e7b20bd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
4 changes: 2 additions & 2 deletions core/committer/txvalidator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ func (v *vsccValidatorImpl) VSCCValidateTx(payload *common.Payload, envBytes []b
// do VSCC validation
if err = v.VSCCValidateTxForCC(envBytes, chdr.TxId, chdr.ChannelId, vscc.ChaincodeName, vscc.ChaincodeVersion, policy); err != nil {
switch err.(type) {
case VSCCEndorsementPolicyError:
case *VSCCEndorsementPolicyError:
return err, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE
default:
return err, peer.TxValidationCode_INVALID_OTHER_REASON
Expand Down Expand Up @@ -588,7 +588,7 @@ func (v *vsccValidatorImpl) VSCCValidateTx(payload *common.Payload, envBytes []b
// they have to modify VSCC to provide appropriate validation
if err = v.VSCCValidateTxForCC(envBytes, chdr.TxId, vscc.ChainID, vscc.ChaincodeName, vscc.ChaincodeVersion, policy); err != nil {
switch err.(type) {
case VSCCEndorsementPolicyError:
case *VSCCEndorsementPolicyError:
return err, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE
default:
return err, peer.TxValidationCode_INVALID_OTHER_REASON
Expand Down
64 changes: 63 additions & 1 deletion core/committer/txvalidator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/hyperledger/fabric/common/ledger/testutil"
"github.com/hyperledger/fabric/common/mocks/scc"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/chaincode/shim"
ccp "github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric/core/common/sysccprovider"
"github.com/hyperledger/fabric/core/ledger"
Expand Down Expand Up @@ -531,12 +532,73 @@ func TestLedgerIsNoAvailable(t *testing.T) {
assertion.NotNil(err.(*VSCCInfoLookupFailureError))
}

func TestValidationInvalidEndorsing(t *testing.T) {
theLedger := new(mockLedger)
validator := NewTxValidator(&mockSupport{l: theLedger})

ccID := "mycc"
tx := getEnv(ccID, createRWset(t, ccID), t)

theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, errors.New("Cannot find the transaction"))

cd := &ccp.ChaincodeData{
Name: ccID,
Version: ccVersion,
Vscc: "vscc",
Policy: signedByAnyMember([]string{"DEFAULT"}),
}

cdbytes := utils.MarshalOrPanic(cd)

queryExecutor := new(mockQueryExecutor)
queryExecutor.On("GetState", "lscc", ccID).Return(cdbytes, nil)
theLedger.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)

b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}

// Keep default callback
c := executeChaincodeProvider.getCallback()
executeChaincodeProvider.setCallback(func() (*peer.Response, *peer.ChaincodeEvent, error) {
return &peer.Response{Status: shim.ERROR}, nil, nil
})
err := validator.Validate(b)
// Restore default callback
executeChaincodeProvider.setCallback(c)
assert.NoError(t, err)
assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
}

type ccResultCallback func() (*peer.Response, *peer.ChaincodeEvent, error)

type ccExecuteChaincode struct {
executeChaincodeCalback ccResultCallback
}

func (cc *ccExecuteChaincode) ExecuteChaincodeResult() (*peer.Response, *peer.ChaincodeEvent, error) {
return cc.executeChaincodeCalback()
}

func (cc *ccExecuteChaincode) getCallback() ccResultCallback {
return cc.executeChaincodeCalback
}

func (cc *ccExecuteChaincode) setCallback(calback ccResultCallback) {
cc.executeChaincodeCalback = calback
}

var signer msp.SigningIdentity

var signerSerialized []byte

var executeChaincodeProvider = &ccExecuteChaincode{
executeChaincodeCalback: func() (*peer.Response, *peer.ChaincodeEvent, error) {
return &peer.Response{Status: shim.OK}, nil, nil
},
}

func TestMain(m *testing.M) {
sysccprovider.RegisterSystemChaincodeProviderFactory(&scc.MocksccProviderFactory{})
ccp.RegisterChaincodeProviderFactory(&ccprovider.MockCcProviderFactory{})
ccp.RegisterChaincodeProviderFactory(&ccprovider.MockCcProviderFactory{executeChaincodeProvider})

msptesttools.LoadMSPSetupForTesting()

Expand Down
11 changes: 10 additions & 1 deletion core/mocks/ccprovider/ccprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,24 @@ import (
"github.com/hyperledger/fabric/protos/peer"
)

type ExecuteChaincodeResultProvider interface {
ExecuteChaincodeResult() (*peer.Response, *peer.ChaincodeEvent, error)
}

// MockCcProviderFactory is a factory that returns
// mock implementations of the ccprovider.ChaincodeProvider interface
type MockCcProviderFactory struct {
ExecuteResultProvider ExecuteChaincodeResultProvider
}

// NewChaincodeProvider returns a mock implementation of the ccprovider.ChaincodeProvider interface
func (c *MockCcProviderFactory) NewChaincodeProvider() ccprovider.ChaincodeProvider {
return &mockCcProviderImpl{}
return &mockCcProviderImpl{c.ExecuteResultProvider}
}

// mockCcProviderImpl is a mock implementation of the chaincode provider
type mockCcProviderImpl struct {
executeResultProvider ExecuteChaincodeResultProvider
}

type mockCcProviderContextImpl struct {
Expand All @@ -59,6 +65,9 @@ func (c *mockCcProviderImpl) GetCCValidationInfoFromLSCC(ctxt context.Context, t

// ExecuteChaincode does nothing
func (c *mockCcProviderImpl) ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*peer.Response, *peer.ChaincodeEvent, error) {
if c.executeResultProvider != nil {
return c.executeResultProvider.ExecuteChaincodeResult()
}
return &peer.Response{Status: shim.OK}, nil, nil
}

Expand Down

0 comments on commit e7b20bd

Please sign in to comment.