github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/core/committer/txvalidator/validator_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package txvalidator
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"os"
    23  	"testing"
    24  
    25  	"github.com/hyperledger/fabric/common/cauthdsl"
    26  	ctxt "github.com/hyperledger/fabric/common/configtx/test"
    27  	ledger2 "github.com/hyperledger/fabric/common/ledger"
    28  	"github.com/hyperledger/fabric/common/ledger/testutil"
    29  	"github.com/hyperledger/fabric/common/mocks/scc"
    30  	"github.com/hyperledger/fabric/common/util"
    31  	"github.com/hyperledger/fabric/core/chaincode/shim"
    32  	ccp "github.com/hyperledger/fabric/core/common/ccprovider"
    33  	"github.com/hyperledger/fabric/core/common/sysccprovider"
    34  	"github.com/hyperledger/fabric/core/ledger"
    35  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
    36  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    37  	lutils "github.com/hyperledger/fabric/core/ledger/util"
    38  	"github.com/hyperledger/fabric/core/mocks/ccprovider"
    39  	"github.com/hyperledger/fabric/msp"
    40  	"github.com/hyperledger/fabric/msp/mgmt"
    41  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    42  	"github.com/hyperledger/fabric/protos/common"
    43  	"github.com/hyperledger/fabric/protos/peer"
    44  	"github.com/hyperledger/fabric/protos/utils"
    45  	"github.com/spf13/viper"
    46  	"github.com/stretchr/testify/assert"
    47  	"github.com/stretchr/testify/mock"
    48  )
    49  
    50  func signedByAnyMember(ids []string) []byte {
    51  	p := cauthdsl.SignedByAnyMember(ids)
    52  	return utils.MarshalOrPanic(p)
    53  }
    54  
    55  func setupLedgerAndValidator(t *testing.T) (ledger.PeerLedger, Validator) {
    56  	viper.Set("peer.fileSystemPath", "/tmp/fabric/validatortest")
    57  	ledgermgmt.InitializeTestEnv()
    58  	gb, err := ctxt.MakeGenesisBlock("TestLedger")
    59  	assert.NoError(t, err)
    60  	theLedger, err := ledgermgmt.CreateLedger(gb)
    61  	assert.NoError(t, err)
    62  	theValidator := NewTxValidator(&mockSupport{l: theLedger})
    63  
    64  	return theLedger, theValidator
    65  }
    66  
    67  func createRWset(t *testing.T, ccnames ...string) []byte {
    68  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
    69  	for _, ccname := range ccnames {
    70  		rwsetBuilder.AddToWriteSet(ccname, "key", []byte("value"))
    71  	}
    72  	rwset := rwsetBuilder.GetTxReadWriteSet()
    73  	rws, err := rwset.ToProtoBytes()
    74  	assert.NoError(t, err)
    75  	return rws
    76  }
    77  
    78  func getProposal(ccID string) (*peer.Proposal, error) {
    79  	cis := &peer.ChaincodeInvocationSpec{
    80  		ChaincodeSpec: &peer.ChaincodeSpec{
    81  			ChaincodeId: &peer.ChaincodeID{Name: ccID, Version: ccVersion},
    82  			Input:       &peer.ChaincodeInput{Args: [][]byte{[]byte("func")}},
    83  			Type:        peer.ChaincodeSpec_GOLANG}}
    84  
    85  	proposal, _, err := utils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), cis, signerSerialized)
    86  	return proposal, err
    87  }
    88  
    89  const ccVersion = "1.0"
    90  
    91  func getEnv(ccID string, res []byte, t *testing.T) *common.Envelope {
    92  	// get a toy proposal
    93  	prop, err := getProposal(ccID)
    94  	assert.NoError(t, err)
    95  
    96  	response := &peer.Response{Status: 200}
    97  
    98  	// endorse it to get a proposal response
    99  	presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response, res, nil, &peer.ChaincodeID{Name: ccID, Version: ccVersion}, nil, signer)
   100  	assert.NoError(t, err)
   101  
   102  	// assemble a transaction from that proposal and endorsement
   103  	tx, err := utils.CreateSignedTx(prop, signer, presp)
   104  	assert.NoError(t, err)
   105  
   106  	return tx
   107  }
   108  
   109  func putCCInfoWithVSCCAndVer(theLedger ledger.PeerLedger, ccname, vscc, ver string, policy []byte, t *testing.T) {
   110  	cd := &ccp.ChaincodeData{
   111  		Name:    ccname,
   112  		Version: ver,
   113  		Vscc:    vscc,
   114  		Policy:  policy,
   115  	}
   116  
   117  	cdbytes := utils.MarshalOrPanic(cd)
   118  
   119  	simulator, err := theLedger.NewTxSimulator()
   120  	assert.NoError(t, err)
   121  	simulator.SetState("lscc", ccname, cdbytes)
   122  	simulator.Done()
   123  
   124  	simRes, err := simulator.GetTxSimulationResults()
   125  	assert.NoError(t, err)
   126  	block0 := testutil.ConstructBlock(t, 1, []byte("hash"), [][]byte{simRes}, true)
   127  	err = theLedger.Commit(block0)
   128  	assert.NoError(t, err)
   129  }
   130  
   131  func putCCInfo(theLedger ledger.PeerLedger, ccname string, policy []byte, t *testing.T) {
   132  	putCCInfoWithVSCCAndVer(theLedger, ccname, "vscc", ccVersion, policy, t)
   133  }
   134  
   135  type mockSupport struct {
   136  	l ledger.PeerLedger
   137  }
   138  
   139  func (m *mockSupport) Ledger() ledger.PeerLedger {
   140  	return m.l
   141  }
   142  
   143  func (m *mockSupport) MSPManager() msp.MSPManager {
   144  	return mgmt.GetManagerForChain(util.GetTestChainID())
   145  }
   146  
   147  func (m *mockSupport) Apply(configtx *common.ConfigEnvelope) error {
   148  	return nil
   149  }
   150  
   151  func (m *mockSupport) GetMSPIDs(cid string) []string {
   152  	return []string{"DEFAULT"}
   153  }
   154  
   155  func assertInvalid(block *common.Block, t *testing.T, code peer.TxValidationCode) {
   156  	txsFilter := lutils.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   157  	assert.True(t, txsFilter.IsInvalid(0))
   158  	assert.True(t, txsFilter.IsSetTo(0, code))
   159  }
   160  
   161  func assertValid(block *common.Block, t *testing.T) {
   162  	txsFilter := lutils.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   163  	assert.False(t, txsFilter.IsInvalid(0))
   164  }
   165  
   166  func TestInvokeBadRWSet(t *testing.T) {
   167  	l, v := setupLedgerAndValidator(t)
   168  	defer ledgermgmt.CleanupTestEnv()
   169  	defer l.Close()
   170  
   171  	ccID := "mycc"
   172  
   173  	tx := getEnv(ccID, []byte("barf"), t)
   174  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   175  
   176  	err := v.Validate(b)
   177  	assert.NoError(t, err)
   178  	assertInvalid(b, t, peer.TxValidationCode_BAD_RWSET)
   179  }
   180  
   181  func TestInvokeNoPolicy(t *testing.T) {
   182  	l, v := setupLedgerAndValidator(t)
   183  	defer ledgermgmt.CleanupTestEnv()
   184  	defer l.Close()
   185  
   186  	ccID := "mycc"
   187  
   188  	putCCInfo(l, ccID, nil, t)
   189  
   190  	tx := getEnv(ccID, createRWset(t, ccID), t)
   191  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   192  
   193  	err := v.Validate(b)
   194  	assert.NoError(t, err)
   195  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   196  }
   197  
   198  func TestInvokeOK(t *testing.T) {
   199  	l, v := setupLedgerAndValidator(t)
   200  	defer ledgermgmt.CleanupTestEnv()
   201  	defer l.Close()
   202  
   203  	ccID := "mycc"
   204  
   205  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   206  
   207  	tx := getEnv(ccID, createRWset(t, ccID), t)
   208  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   209  
   210  	err := v.Validate(b)
   211  	assert.NoError(t, err)
   212  	assertValid(b, t)
   213  }
   214  
   215  func TestInvokeOKSCC(t *testing.T) {
   216  	l, v := setupLedgerAndValidator(t)
   217  	defer ledgermgmt.CleanupTestEnv()
   218  	defer l.Close()
   219  
   220  	ccID := "lscc"
   221  
   222  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   223  
   224  	tx := getEnv(ccID, createRWset(t, ccID), t)
   225  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   226  
   227  	err := v.Validate(b)
   228  	assert.NoError(t, err)
   229  	assertValid(b, t)
   230  }
   231  
   232  func TestInvokeNOKWritesToLSCC(t *testing.T) {
   233  	l, v := setupLedgerAndValidator(t)
   234  	defer ledgermgmt.CleanupTestEnv()
   235  	defer l.Close()
   236  
   237  	ccID := "mycc"
   238  
   239  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   240  
   241  	tx := getEnv(ccID, createRWset(t, ccID, "lscc"), t)
   242  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   243  
   244  	err := v.Validate(b)
   245  	assert.NoError(t, err)
   246  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
   247  }
   248  
   249  func TestInvokeNOKWritesToESCC(t *testing.T) {
   250  	l, v := setupLedgerAndValidator(t)
   251  	defer ledgermgmt.CleanupTestEnv()
   252  	defer l.Close()
   253  
   254  	ccID := "mycc"
   255  
   256  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   257  
   258  	tx := getEnv(ccID, createRWset(t, ccID, "escc"), t)
   259  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   260  
   261  	err := v.Validate(b)
   262  	assert.NoError(t, err)
   263  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
   264  }
   265  
   266  func TestInvokeNOKWritesToNotExt(t *testing.T) {
   267  	l, v := setupLedgerAndValidator(t)
   268  	defer ledgermgmt.CleanupTestEnv()
   269  	defer l.Close()
   270  
   271  	ccID := "mycc"
   272  
   273  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   274  
   275  	tx := getEnv(ccID, createRWset(t, ccID, "notext"), t)
   276  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   277  
   278  	err := v.Validate(b)
   279  	assert.NoError(t, err)
   280  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
   281  }
   282  
   283  func TestInvokeNOKInvokesNotExt(t *testing.T) {
   284  	l, v := setupLedgerAndValidator(t)
   285  	defer ledgermgmt.CleanupTestEnv()
   286  	defer l.Close()
   287  
   288  	ccID := "notext"
   289  
   290  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   291  
   292  	tx := getEnv(ccID, createRWset(t, ccID), t)
   293  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   294  
   295  	err := v.Validate(b)
   296  	assert.NoError(t, err)
   297  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
   298  }
   299  
   300  func TestInvokeNOKInvokesEmptyCCName(t *testing.T) {
   301  	l, v := setupLedgerAndValidator(t)
   302  	defer ledgermgmt.CleanupTestEnv()
   303  	defer l.Close()
   304  
   305  	ccID := ""
   306  
   307  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   308  
   309  	tx := getEnv(ccID, createRWset(t, ccID), t)
   310  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   311  
   312  	err := v.Validate(b)
   313  	assert.NoError(t, err)
   314  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   315  }
   316  
   317  func TestInvokeNOKExpiredCC(t *testing.T) {
   318  	l, v := setupLedgerAndValidator(t)
   319  	defer ledgermgmt.CleanupTestEnv()
   320  	defer l.Close()
   321  
   322  	ccID := "mycc"
   323  
   324  	putCCInfoWithVSCCAndVer(l, ccID, "vscc", "badversion", signedByAnyMember([]string{"DEFAULT"}), t)
   325  
   326  	tx := getEnv(ccID, createRWset(t, ccID), t)
   327  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   328  
   329  	err := v.Validate(b)
   330  	assert.NoError(t, err)
   331  	assertInvalid(b, t, peer.TxValidationCode_EXPIRED_CHAINCODE)
   332  }
   333  
   334  func TestInvokeNOKBogusActions(t *testing.T) {
   335  	l, v := setupLedgerAndValidator(t)
   336  	defer ledgermgmt.CleanupTestEnv()
   337  	defer l.Close()
   338  
   339  	ccID := "mycc"
   340  
   341  	putCCInfo(l, ccID, signedByAnyMember([]string{"DEFAULT"}), t)
   342  
   343  	tx := getEnv(ccID, []byte("barf"), t)
   344  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   345  
   346  	err := v.Validate(b)
   347  	assert.NoError(t, err)
   348  	assertInvalid(b, t, peer.TxValidationCode_BAD_RWSET)
   349  }
   350  
   351  func TestInvokeNOKCCDoesntExist(t *testing.T) {
   352  	l, v := setupLedgerAndValidator(t)
   353  	defer ledgermgmt.CleanupTestEnv()
   354  	defer l.Close()
   355  
   356  	ccID := "mycc"
   357  
   358  	tx := getEnv(ccID, createRWset(t, ccID), t)
   359  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   360  
   361  	err := v.Validate(b)
   362  	assert.NoError(t, err)
   363  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   364  }
   365  
   366  func TestInvokeNOKVSCCUnspecified(t *testing.T) {
   367  	l, v := setupLedgerAndValidator(t)
   368  	defer ledgermgmt.CleanupTestEnv()
   369  	defer l.Close()
   370  
   371  	ccID := "mycc"
   372  
   373  	putCCInfoWithVSCCAndVer(l, ccID, "", ccVersion, signedByAnyMember([]string{"DEFAULT"}), t)
   374  
   375  	tx := getEnv(ccID, createRWset(t, ccID), t)
   376  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   377  
   378  	err := v.Validate(b)
   379  	assert.NoError(t, err)
   380  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   381  }
   382  
   383  func TestInvokeNoBlock(t *testing.T) {
   384  	l, v := setupLedgerAndValidator(t)
   385  	defer ledgermgmt.CleanupTestEnv()
   386  	defer l.Close()
   387  
   388  	err := v.Validate(&common.Block{Data: &common.BlockData{Data: [][]byte{}}})
   389  	assert.NoError(t, err)
   390  }
   391  
   392  // mockLedger structure used to test ledger
   393  // failure, therefore leveraging mocking
   394  // library as need to simulate ledger which not
   395  // able to get access to state db
   396  type mockLedger struct {
   397  	mock.Mock
   398  }
   399  
   400  // GetTransactionByID returns transaction by ud
   401  func (m *mockLedger) GetTransactionByID(txID string) (*peer.ProcessedTransaction, error) {
   402  	args := m.Called(txID)
   403  	return args.Get(0).(*peer.ProcessedTransaction), args.Error(1)
   404  }
   405  
   406  // GetBlockByHash returns block using its hash value
   407  func (m *mockLedger) GetBlockByHash(blockHash []byte) (*common.Block, error) {
   408  	args := m.Called(blockHash)
   409  	return args.Get(0).(*common.Block), nil
   410  }
   411  
   412  // GetBlockByTxID given transaction id return block transaction was committed with
   413  func (m *mockLedger) GetBlockByTxID(txID string) (*common.Block, error) {
   414  	args := m.Called(txID)
   415  	return args.Get(0).(*common.Block), nil
   416  }
   417  
   418  // GetTxValidationCodeByTxID returns validation code of give tx
   419  func (m *mockLedger) GetTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error) {
   420  	args := m.Called(txID)
   421  	return args.Get(0).(peer.TxValidationCode), nil
   422  }
   423  
   424  // NewTxSimulator creates new transaction simulator
   425  func (m *mockLedger) NewTxSimulator() (ledger.TxSimulator, error) {
   426  	args := m.Called()
   427  	return args.Get(0).(ledger.TxSimulator), nil
   428  }
   429  
   430  // NewQueryExecutor creates query executor
   431  func (m *mockLedger) NewQueryExecutor() (ledger.QueryExecutor, error) {
   432  	args := m.Called()
   433  	return args.Get(0).(ledger.QueryExecutor), nil
   434  }
   435  
   436  // NewHistoryQueryExecutor history query executor
   437  func (m *mockLedger) NewHistoryQueryExecutor() (ledger.HistoryQueryExecutor, error) {
   438  	args := m.Called()
   439  	return args.Get(0).(ledger.HistoryQueryExecutor), nil
   440  }
   441  
   442  // Prune prune using policy
   443  func (m *mockLedger) Prune(policy ledger2.PrunePolicy) error {
   444  	return nil
   445  }
   446  
   447  func (m *mockLedger) GetBlockchainInfo() (*common.BlockchainInfo, error) {
   448  	args := m.Called()
   449  	return args.Get(0).(*common.BlockchainInfo), nil
   450  }
   451  
   452  func (m *mockLedger) GetBlockByNumber(blockNumber uint64) (*common.Block, error) {
   453  	args := m.Called(blockNumber)
   454  	return args.Get(0).(*common.Block), nil
   455  }
   456  
   457  func (m *mockLedger) GetBlocksIterator(startBlockNumber uint64) (ledger2.ResultsIterator, error) {
   458  	args := m.Called(startBlockNumber)
   459  	return args.Get(0).(ledger2.ResultsIterator), nil
   460  }
   461  
   462  func (m *mockLedger) Close() {
   463  
   464  }
   465  
   466  func (m *mockLedger) Commit(block *common.Block) error {
   467  	return nil
   468  }
   469  
   470  // mockQueryExecutor mock of the query executor,
   471  // needed to simulate inability to access state db, e.g.
   472  // the case where due to db failure it's not possible to
   473  // query for state, for example if we would like to query
   474  // the lccc for VSCC info and db is not avaible we expect
   475  // to stop validating block and fail commit procedure with
   476  // an error.
   477  type mockQueryExecutor struct {
   478  	mock.Mock
   479  }
   480  
   481  func (exec *mockQueryExecutor) GetState(namespace string, key string) ([]byte, error) {
   482  	args := exec.Called(namespace, key)
   483  	return args.Get(0).([]byte), args.Error(1)
   484  }
   485  
   486  func (exec *mockQueryExecutor) GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error) {
   487  	args := exec.Called(namespace, keys)
   488  	return args.Get(0).([][]byte), args.Error(1)
   489  }
   490  
   491  func (exec *mockQueryExecutor) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ledger2.ResultsIterator, error) {
   492  	args := exec.Called(namespace, startKey, endKey)
   493  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
   494  }
   495  
   496  func (exec *mockQueryExecutor) ExecuteQuery(namespace, query string) (ledger2.ResultsIterator, error) {
   497  	args := exec.Called(namespace)
   498  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
   499  }
   500  
   501  func (exec *mockQueryExecutor) Done() {
   502  }
   503  
   504  // TestLedgerIsNoAvailable simulates and provides a test for following scenario,
   505  // which is based on FAB-535. Test checks the validation path which expects that
   506  // DB won't available while trying to lookup for VSCC from LCCC and therefore
   507  // transaction validation will have to fail. In such case the outcome should be
   508  // the error return from validate block method and proccessing of transactions
   509  // has to stop. There is suppose to be clear indication of the failure with error
   510  // returned from the function call.
   511  func TestLedgerIsNoAvailable(t *testing.T) {
   512  	theLedger := new(mockLedger)
   513  	validator := NewTxValidator(&mockSupport{l: theLedger})
   514  
   515  	ccID := "mycc"
   516  	tx := getEnv(ccID, createRWset(t, ccID), t)
   517  
   518  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, errors.New("Cannot find the transaction"))
   519  
   520  	queryExecutor := new(mockQueryExecutor)
   521  	queryExecutor.On("GetState", mock.Anything, mock.Anything).Return([]byte{}, errors.New("Unable to connect to DB"))
   522  	theLedger.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)
   523  
   524  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   525  
   526  	err := validator.Validate(b)
   527  
   528  	assertion := assert.New(t)
   529  	// We suppose to get the error which indicates we cannot commit the block
   530  	assertion.Error(err)
   531  	// The error exptected to be of type VSCCInfoLookupFailureError
   532  	assertion.NotNil(err.(*VSCCInfoLookupFailureError))
   533  }
   534  
   535  func TestValidationInvalidEndorsing(t *testing.T) {
   536  	theLedger := new(mockLedger)
   537  	validator := NewTxValidator(&mockSupport{l: theLedger})
   538  
   539  	ccID := "mycc"
   540  	tx := getEnv(ccID, createRWset(t, ccID), t)
   541  
   542  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, errors.New("Cannot find the transaction"))
   543  
   544  	cd := &ccp.ChaincodeData{
   545  		Name:    ccID,
   546  		Version: ccVersion,
   547  		Vscc:    "vscc",
   548  		Policy:  signedByAnyMember([]string{"DEFAULT"}),
   549  	}
   550  
   551  	cdbytes := utils.MarshalOrPanic(cd)
   552  
   553  	queryExecutor := new(mockQueryExecutor)
   554  	queryExecutor.On("GetState", "lscc", ccID).Return(cdbytes, nil)
   555  	theLedger.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)
   556  
   557  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{utils.MarshalOrPanic(tx)}}}
   558  
   559  	// Keep default callback
   560  	c := executeChaincodeProvider.getCallback()
   561  	executeChaincodeProvider.setCallback(func() (*peer.Response, *peer.ChaincodeEvent, error) {
   562  		return &peer.Response{Status: shim.ERROR}, nil, nil
   563  	})
   564  	err := validator.Validate(b)
   565  	// Restore default callback
   566  	executeChaincodeProvider.setCallback(c)
   567  	assert.NoError(t, err)
   568  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
   569  }
   570  
   571  type ccResultCallback func() (*peer.Response, *peer.ChaincodeEvent, error)
   572  
   573  type ccExecuteChaincode struct {
   574  	executeChaincodeCalback ccResultCallback
   575  }
   576  
   577  func (cc *ccExecuteChaincode) ExecuteChaincodeResult() (*peer.Response, *peer.ChaincodeEvent, error) {
   578  	return cc.executeChaincodeCalback()
   579  }
   580  
   581  func (cc *ccExecuteChaincode) getCallback() ccResultCallback {
   582  	return cc.executeChaincodeCalback
   583  }
   584  
   585  func (cc *ccExecuteChaincode) setCallback(calback ccResultCallback) {
   586  	cc.executeChaincodeCalback = calback
   587  }
   588  
   589  var signer msp.SigningIdentity
   590  
   591  var signerSerialized []byte
   592  
   593  var executeChaincodeProvider = &ccExecuteChaincode{
   594  	executeChaincodeCalback: func() (*peer.Response, *peer.ChaincodeEvent, error) {
   595  		return &peer.Response{Status: shim.OK}, nil, nil
   596  	},
   597  }
   598  
   599  func TestMain(m *testing.M) {
   600  	sysccprovider.RegisterSystemChaincodeProviderFactory(&scc.MocksccProviderFactory{})
   601  	ccp.RegisterChaincodeProviderFactory(&ccprovider.MockCcProviderFactory{executeChaincodeProvider})
   602  
   603  	msptesttools.LoadMSPSetupForTesting()
   604  
   605  	var err error
   606  	signer, err = mgmt.GetLocalMSP().GetDefaultSigningIdentity()
   607  	if err != nil {
   608  		fmt.Println("Could not get signer")
   609  		os.Exit(-1)
   610  		return
   611  	}
   612  
   613  	signerSerialized, err = signer.Serialize()
   614  	if err != nil {
   615  		fmt.Println("Could not serialize identity")
   616  		os.Exit(-1)
   617  		return
   618  	}
   619  
   620  	os.Exit(m.Run())
   621  }