github.com/ewagmig/fabric@v2.1.1+incompatible/core/committer/txvalidator/v14/validator_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package txvalidator_test
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"strconv"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/hyperledger/fabric-protos-go/common"
    19  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    20  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    21  	mb "github.com/hyperledger/fabric-protos-go/msp"
    22  	"github.com/hyperledger/fabric-protos-go/peer"
    23  	pb "github.com/hyperledger/fabric-protos-go/peer"
    24  	"github.com/hyperledger/fabric/bccsp/sw"
    25  	ctxt "github.com/hyperledger/fabric/common/configtx/test"
    26  	commonerrors "github.com/hyperledger/fabric/common/errors"
    27  	ledger2 "github.com/hyperledger/fabric/common/ledger"
    28  	"github.com/hyperledger/fabric/common/ledger/testutil"
    29  	"github.com/hyperledger/fabric/common/policydsl"
    30  	"github.com/hyperledger/fabric/common/semaphore"
    31  	"github.com/hyperledger/fabric/common/util"
    32  	"github.com/hyperledger/fabric/core/committer/txvalidator"
    33  	tmocks "github.com/hyperledger/fabric/core/committer/txvalidator/mocks"
    34  	vp "github.com/hyperledger/fabric/core/committer/txvalidator/plugin"
    35  	txvalidatorv14 "github.com/hyperledger/fabric/core/committer/txvalidator/v14"
    36  	"github.com/hyperledger/fabric/core/committer/txvalidator/v14/mocks"
    37  	"github.com/hyperledger/fabric/core/committer/txvalidator/v14/testdata"
    38  	ccp "github.com/hyperledger/fabric/core/common/ccprovider"
    39  	validation "github.com/hyperledger/fabric/core/handlers/validation/api"
    40  	"github.com/hyperledger/fabric/core/handlers/validation/builtin"
    41  	"github.com/hyperledger/fabric/core/ledger"
    42  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
    43  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    44  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt/ledgermgmttest"
    45  	lutils "github.com/hyperledger/fabric/core/ledger/util"
    46  	mocktxvalidator "github.com/hyperledger/fabric/core/mocks/txvalidator"
    47  	mocks2 "github.com/hyperledger/fabric/discovery/support/mocks"
    48  	"github.com/hyperledger/fabric/msp"
    49  	"github.com/hyperledger/fabric/msp/mgmt"
    50  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    51  	"github.com/hyperledger/fabric/protoutil"
    52  	"github.com/stretchr/testify/assert"
    53  	"github.com/stretchr/testify/mock"
    54  )
    55  
    56  func signedByAnyMember(ids []string) []byte {
    57  	p := policydsl.SignedByAnyMember(ids)
    58  	return protoutil.MarshalOrPanic(p)
    59  }
    60  
    61  func preV12Capabilities() *tmocks.ApplicationCapabilities {
    62  	ac := &tmocks.ApplicationCapabilities{}
    63  	ac.On("V1_2Validation").Return(false)
    64  	ac.On("V1_3Validation").Return(false)
    65  	ac.On("V2_0Validation").Return(false)
    66  	ac.On("PrivateChannelData").Return(false)
    67  	ac.On("ForbidDuplicateTXIdInBlock").Return(false)
    68  	ac.On("KeyLevelEndorsement").Return(false)
    69  	return ac
    70  }
    71  
    72  func v12Capabilities() *tmocks.ApplicationCapabilities {
    73  	ac := &tmocks.ApplicationCapabilities{}
    74  	ac.On("V1_2Validation").Return(true)
    75  	ac.On("V1_3Validation").Return(false)
    76  	ac.On("V2_0Validation").Return(false)
    77  	ac.On("PrivateChannelData").Return(true)
    78  	ac.On("ForbidDuplicateTXIdInBlock").Return(false)
    79  	ac.On("KeyLevelEndorsement").Return(false)
    80  	return ac
    81  }
    82  
    83  func v13Capabilities() *tmocks.ApplicationCapabilities {
    84  	ac := &tmocks.ApplicationCapabilities{}
    85  	ac.On("V1_2Validation").Return(true)
    86  	ac.On("V1_3Validation").Return(true)
    87  	ac.On("V2_0Validation").Return(false)
    88  	ac.On("PrivateChannelData").Return(true)
    89  	ac.On("ForbidDuplicateTXIdInBlock").Return(true)
    90  	ac.On("KeyLevelEndorsement").Return(true)
    91  	return ac
    92  }
    93  
    94  func setupLedgerAndValidatorExplicit(t *testing.T, cpb *tmocks.ApplicationCapabilities, plugin validation.Plugin) (ledger.PeerLedger, txvalidator.Validator, func()) {
    95  	return setupLedgerAndValidatorExplicitWithMSP(t, cpb, plugin, nil)
    96  }
    97  
    98  func setupLedgerAndValidatorWithPreV12Capabilities(t *testing.T) (ledger.PeerLedger, txvalidator.Validator, func()) {
    99  	return setupLedgerAndValidatorWithCapabilities(t, preV12Capabilities())
   100  }
   101  
   102  func setupLedgerAndValidatorWithV12Capabilities(t *testing.T) (ledger.PeerLedger, txvalidator.Validator, func()) {
   103  	return setupLedgerAndValidatorWithCapabilities(t, v12Capabilities())
   104  }
   105  
   106  func setupLedgerAndValidatorWithV13Capabilities(t *testing.T) (ledger.PeerLedger, txvalidator.Validator, func()) {
   107  	return setupLedgerAndValidatorWithCapabilities(t, v13Capabilities())
   108  }
   109  
   110  func setupLedgerAndValidatorWithCapabilities(t *testing.T, c *tmocks.ApplicationCapabilities) (ledger.PeerLedger, txvalidator.Validator, func()) {
   111  	mspmgr := &mocks2.MSPManager{}
   112  	idThatSatisfiesPrincipal := &mocks2.Identity{}
   113  	idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(nil)
   114  	idThatSatisfiesPrincipal.GetIdentifierReturns(&msp.IdentityIdentifier{})
   115  	mspmgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil)
   116  
   117  	return setupLedgerAndValidatorExplicitWithMSP(t, c, &builtin.DefaultValidation{}, mspmgr)
   118  }
   119  
   120  func setupLedgerAndValidatorExplicitWithMSP(t *testing.T, cpb *tmocks.ApplicationCapabilities, plugin validation.Plugin, mspMgr msp.MSPManager) (ledger.PeerLedger, txvalidator.Validator, func()) {
   121  	ledgerMgr, cleanup := constructLedgerMgrWithTestDefaults(t, "txvalidator")
   122  	gb, err := ctxt.MakeGenesisBlock("TestLedger")
   123  	assert.NoError(t, err)
   124  	theLedger, err := ledgerMgr.CreateLedger("TestLedger", gb)
   125  	assert.NoError(t, err)
   126  	pm := &mocks.Mapper{}
   127  	factory := &mocks.PluginFactory{}
   128  	pm.On("FactoryByName", vp.Name("vscc")).Return(factory)
   129  	factory.On("New").Return(plugin)
   130  
   131  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   132  	assert.NoError(t, err)
   133  	theValidator := txvalidatorv14.NewTxValidator(
   134  		"",
   135  		semaphore.New(10),
   136  		&mocktxvalidator.Support{LedgerVal: theLedger, ACVal: cpb, MSPManagerVal: mspMgr},
   137  		pm,
   138  		cryptoProvider,
   139  	)
   140  
   141  	return theLedger,
   142  		theValidator,
   143  		func() {
   144  			theLedger.Close()
   145  			cleanup()
   146  		}
   147  }
   148  
   149  func createRWset(t *testing.T, ccnames ...string) []byte {
   150  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   151  	for _, ccname := range ccnames {
   152  		rwsetBuilder.AddToWriteSet(ccname, "key", []byte("value"))
   153  	}
   154  	rwset, err := rwsetBuilder.GetTxSimulationResults()
   155  	assert.NoError(t, err)
   156  	rwsetBytes, err := rwset.GetPubSimulationBytes()
   157  	return rwsetBytes
   158  }
   159  
   160  func getProposalWithType(ccID string, pType common.HeaderType) (*peer.Proposal, error) {
   161  	cis := &peer.ChaincodeInvocationSpec{
   162  		ChaincodeSpec: &peer.ChaincodeSpec{
   163  			ChaincodeId: &peer.ChaincodeID{Name: ccID, Version: ccVersion},
   164  			Input:       &peer.ChaincodeInput{Args: [][]byte{[]byte("func")}},
   165  			Type:        peer.ChaincodeSpec_GOLANG}}
   166  
   167  	proposal, _, err := protoutil.CreateProposalFromCIS(pType, "testchannelid", cis, signerSerialized)
   168  	return proposal, err
   169  }
   170  
   171  const ccVersion = "1.0"
   172  
   173  func getEnvWithType(ccID string, event []byte, res []byte, pType common.HeaderType, t *testing.T) *common.Envelope {
   174  	// get a toy proposal
   175  	prop, err := getProposalWithType(ccID, pType)
   176  	assert.NoError(t, err)
   177  
   178  	response := &peer.Response{Status: 200}
   179  
   180  	// endorse it to get a proposal response
   181  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, response, res, event, &peer.ChaincodeID{Name: ccID, Version: ccVersion}, signer)
   182  	assert.NoError(t, err)
   183  
   184  	// assemble a transaction from that proposal and endorsement
   185  	tx, err := protoutil.CreateSignedTx(prop, signer, presp)
   186  	assert.NoError(t, err)
   187  
   188  	return tx
   189  }
   190  
   191  func getEnv(ccID string, event []byte, res []byte, t *testing.T) *common.Envelope {
   192  	return getEnvWithType(ccID, event, res, common.HeaderType_ENDORSER_TRANSACTION, t)
   193  }
   194  
   195  func getEnvWithSigner(ccID string, event []byte, res []byte, sig msp.SigningIdentity, t *testing.T) *common.Envelope {
   196  	// get a toy proposal
   197  	pType := common.HeaderType_ENDORSER_TRANSACTION
   198  	cis := &peer.ChaincodeInvocationSpec{
   199  		ChaincodeSpec: &peer.ChaincodeSpec{
   200  			ChaincodeId: &peer.ChaincodeID{Name: ccID, Version: ccVersion},
   201  			Input:       &peer.ChaincodeInput{Args: [][]byte{[]byte("func")}},
   202  			Type:        peer.ChaincodeSpec_GOLANG,
   203  		},
   204  	}
   205  
   206  	sID, err := sig.Serialize()
   207  	assert.NoError(t, err)
   208  	prop, _, err := protoutil.CreateProposalFromCIS(pType, "foochain", cis, sID)
   209  	assert.NoError(t, err)
   210  
   211  	response := &peer.Response{Status: 200}
   212  
   213  	// endorse it to get a proposal response
   214  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, response, res, event, &peer.ChaincodeID{Name: ccID, Version: ccVersion}, sig)
   215  	assert.NoError(t, err)
   216  
   217  	// assemble a transaction from that proposal and endorsement
   218  	tx, err := protoutil.CreateSignedTx(prop, sig, presp)
   219  	assert.NoError(t, err)
   220  
   221  	return tx
   222  }
   223  
   224  func putCCInfoWithVSCCAndVer(theLedger ledger.PeerLedger, ccname, vscc, ver string, policy []byte, t *testing.T) {
   225  	cd := &ccp.ChaincodeData{
   226  		Name:    ccname,
   227  		Version: ver,
   228  		Vscc:    vscc,
   229  		Policy:  policy,
   230  	}
   231  
   232  	cdbytes := protoutil.MarshalOrPanic(cd)
   233  
   234  	txid := util.GenerateUUID()
   235  	simulator, err := theLedger.NewTxSimulator(txid)
   236  	assert.NoError(t, err)
   237  	simulator.SetState("lscc", ccname, cdbytes)
   238  	simulator.Done()
   239  
   240  	simRes, err := simulator.GetTxSimulationResults()
   241  	assert.NoError(t, err)
   242  	pubSimulationBytes, err := simRes.GetPubSimulationBytes()
   243  	assert.NoError(t, err)
   244  	bcInfo, err := theLedger.GetBlockchainInfo()
   245  	assert.NoError(t, err)
   246  	block0 := testutil.ConstructBlock(t, 1, bcInfo.CurrentBlockHash, [][]byte{pubSimulationBytes}, true)
   247  	err = theLedger.CommitLegacy(&ledger.BlockAndPvtData{Block: block0}, &ledger.CommitOptions{})
   248  	assert.NoError(t, err)
   249  }
   250  
   251  func putSBEP(theLedger ledger.PeerLedger, cc, key string, policy []byte, t *testing.T) {
   252  	vpMetadataKey := peer.MetaDataKeys_VALIDATION_PARAMETER.String()
   253  	txid := util.GenerateUUID()
   254  	simulator, err := theLedger.NewTxSimulator(txid)
   255  	assert.NoError(t, err)
   256  	simulator.SetStateMetadata(cc, key, map[string][]byte{vpMetadataKey: policy})
   257  	simulator.SetState(cc, key, []byte("I am a man who walks alone"))
   258  	simulator.Done()
   259  
   260  	simRes, err := simulator.GetTxSimulationResults()
   261  	assert.NoError(t, err)
   262  	pubSimulationBytes, err := simRes.GetPubSimulationBytes()
   263  	assert.NoError(t, err)
   264  	bcInfo, err := theLedger.GetBlockchainInfo()
   265  	assert.NoError(t, err)
   266  	block0 := testutil.ConstructBlock(t, 2, bcInfo.CurrentBlockHash, [][]byte{pubSimulationBytes}, true)
   267  	err = theLedger.CommitLegacy(&ledger.BlockAndPvtData{Block: block0}, &ledger.CommitOptions{})
   268  	assert.NoError(t, err)
   269  }
   270  
   271  func putCCInfo(theLedger ledger.PeerLedger, ccname string, policy []byte, t *testing.T) {
   272  	putCCInfoWithVSCCAndVer(theLedger, ccname, "vscc", ccVersion, policy, t)
   273  }
   274  
   275  func assertInvalid(block *common.Block, t *testing.T, code peer.TxValidationCode) {
   276  	txsFilter := lutils.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   277  	assert.True(t, txsFilter.IsInvalid(0))
   278  	assert.True(t, txsFilter.IsSetTo(0, code))
   279  }
   280  
   281  func assertValid(block *common.Block, t *testing.T) {
   282  	txsFilter := lutils.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   283  	assert.False(t, txsFilter.IsInvalid(0))
   284  }
   285  
   286  func TestInvokeBadRWSet(t *testing.T) {
   287  	t.Run("1.2Capability", func(t *testing.T) {
   288  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   289  		defer cleanup()
   290  
   291  		testInvokeBadRWSet(t, l, v)
   292  	})
   293  
   294  	t.Run("1.3Capability", func(t *testing.T) {
   295  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   296  		defer cleanup()
   297  
   298  		testInvokeBadRWSet(t, l, v)
   299  	})
   300  }
   301  
   302  func testInvokeBadRWSet(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   303  	ccID := "mycc"
   304  
   305  	tx := getEnv(ccID, nil, []byte("barf"), t)
   306  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 1}}
   307  
   308  	err := v.Validate(b)
   309  	assert.NoError(t, err)
   310  	assertInvalid(b, t, peer.TxValidationCode_BAD_RWSET)
   311  }
   312  
   313  func TestInvokeNoPolicy(t *testing.T) {
   314  	t.Run("1.2Capability", func(t *testing.T) {
   315  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   316  		defer cleanup()
   317  
   318  		testInvokeNoPolicy(t, l, v)
   319  	})
   320  
   321  	t.Run("1.3Capability", func(t *testing.T) {
   322  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   323  		defer cleanup()
   324  
   325  		testInvokeNoPolicy(t, l, v)
   326  	})
   327  }
   328  
   329  func testInvokeNoPolicy(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   330  	ccID := "mycc"
   331  
   332  	putCCInfo(l, ccID, nil, t)
   333  
   334  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
   335  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   336  
   337  	err := v.Validate(b)
   338  	assert.NoError(t, err)
   339  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   340  }
   341  
   342  func TestInvokeOK(t *testing.T) {
   343  	t.Run("1.2Capability", func(t *testing.T) {
   344  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   345  		defer cleanup()
   346  
   347  		testInvokeOK(t, l, v)
   348  	})
   349  
   350  	t.Run("1.3Capability", func(t *testing.T) {
   351  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   352  		defer cleanup()
   353  
   354  		testInvokeOK(t, l, v)
   355  	})
   356  }
   357  
   358  func testInvokeOK(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   359  	ccID := "mycc"
   360  
   361  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   362  
   363  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
   364  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   365  
   366  	err := v.Validate(b)
   367  	assert.NoError(t, err)
   368  	assertValid(b, t)
   369  }
   370  
   371  func TestInvokeNOKDuplicateNs(t *testing.T) {
   372  	t.Run("1.2Capability", func(t *testing.T) {
   373  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   374  		defer cleanup()
   375  
   376  		testInvokeNOKDuplicateNs(t, l, v)
   377  	})
   378  
   379  	t.Run("1.3Capability", func(t *testing.T) {
   380  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   381  		defer cleanup()
   382  
   383  		testInvokeNOKDuplicateNs(t, l, v)
   384  	})
   385  }
   386  
   387  func testInvokeNOKDuplicateNs(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   388  	ccID := "mycc"
   389  
   390  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   391  
   392  	// note that this read-write set has two read-write sets for the same namespace and key
   393  	txrws := &rwset.TxReadWriteSet{
   394  		DataModel: rwset.TxReadWriteSet_KV,
   395  		NsRwset: []*rwset.NsReadWriteSet{
   396  			{
   397  				Namespace: "mycc",
   398  				Rwset: protoutil.MarshalOrPanic(&kvrwset.KVRWSet{
   399  					Writes: []*kvrwset.KVWrite{
   400  						{
   401  							Key:   "foo",
   402  							Value: []byte("bar1"),
   403  						},
   404  					},
   405  				}),
   406  			},
   407  			{
   408  				Namespace: "mycc",
   409  				Rwset: protoutil.MarshalOrPanic(&kvrwset.KVRWSet{
   410  					Writes: []*kvrwset.KVWrite{
   411  						{
   412  							Key:   "foo",
   413  							Value: []byte("bar2"),
   414  						},
   415  					},
   416  				}),
   417  			},
   418  		},
   419  	}
   420  
   421  	tx := getEnv(ccID, nil, protoutil.MarshalOrPanic(txrws), t)
   422  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   423  
   424  	err := v.Validate(b)
   425  	assert.NoError(t, err)
   426  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
   427  }
   428  
   429  func TestInvokeNoRWSet(t *testing.T) {
   430  	plugin := &mocks.Plugin{}
   431  	plugin.On("Init", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   432  
   433  	t.Run("Pre-1.2Capability", func(t *testing.T) {
   434  		l, v, cleanup := setupLedgerAndValidatorExplicit(t, preV12Capabilities(), plugin)
   435  		defer cleanup()
   436  
   437  		ccID := "mycc"
   438  
   439  		putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   440  
   441  		tx := getEnv(ccID, nil, createRWset(t), t)
   442  		b := &common.Block{
   443  			Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
   444  			Header: &common.BlockHeader{},
   445  		}
   446  
   447  		err := v.Validate(b)
   448  		assert.NoError(t, err)
   449  		assertValid(b, t)
   450  	})
   451  
   452  	mspmgr := &mocks2.MSPManager{}
   453  	idThatSatisfiesPrincipal := &mocks2.Identity{}
   454  	idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(errors.New("principal not satisfied"))
   455  	idThatSatisfiesPrincipal.GetIdentifierReturns(&msp.IdentityIdentifier{})
   456  	mspmgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil)
   457  
   458  	// No need to define validation behavior for the previous test case because pre 1.2 we don't validate transactions
   459  	// that have no write set.
   460  	t.Run("Post-1.2Capability", func(t *testing.T) {
   461  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v12Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   462  		defer cleanup()
   463  
   464  		testInvokeNoRWSet(t, l, v)
   465  	})
   466  
   467  	// Here we test that if we have the 1.3 capability, we still reject a transaction that only contains
   468  	// reads if it doesn't comply with the endorsement policy
   469  	t.Run("Post-1.3Capability", func(t *testing.T) {
   470  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v13Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   471  		defer cleanup()
   472  
   473  		testInvokeNoRWSet(t, l, v)
   474  	})
   475  }
   476  
   477  func testInvokeNoRWSet(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   478  	ccID := "mycc"
   479  
   480  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   481  
   482  	tx := getEnv(ccID, nil, createRWset(t), t)
   483  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   484  
   485  	err := v.Validate(b)
   486  	assert.NoError(t, err)
   487  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
   488  }
   489  
   490  // SerializedIdentity mock for the parallel validation test
   491  type mockSI struct {
   492  	SerializedID []byte
   493  	MspID        string
   494  	SatPrinError error
   495  }
   496  
   497  func (msi *mockSI) ExpiresAt() time.Time {
   498  	return time.Now()
   499  }
   500  
   501  func (msi *mockSI) GetIdentifier() *msp.IdentityIdentifier {
   502  	return &msp.IdentityIdentifier{
   503  		Mspid: msi.MspID,
   504  		Id:    "",
   505  	}
   506  }
   507  
   508  func (msi *mockSI) GetMSPIdentifier() string {
   509  	return msi.MspID
   510  }
   511  
   512  func (msi *mockSI) Validate() error {
   513  	return nil
   514  }
   515  
   516  func (msi *mockSI) GetOrganizationalUnits() []*msp.OUIdentifier {
   517  	return nil
   518  }
   519  
   520  func (msi *mockSI) Anonymous() bool {
   521  	return false
   522  }
   523  
   524  func (msi *mockSI) Verify(msg []byte, sig []byte) error {
   525  	return nil
   526  }
   527  
   528  func (msi *mockSI) Serialize() ([]byte, error) {
   529  	sid := &mb.SerializedIdentity{
   530  		Mspid:   msi.MspID,
   531  		IdBytes: msi.SerializedID,
   532  	}
   533  	sidBytes := protoutil.MarshalOrPanic(sid)
   534  	return sidBytes, nil
   535  }
   536  
   537  func (msi *mockSI) SatisfiesPrincipal(principal *mb.MSPPrincipal) error {
   538  	return msi.SatPrinError
   539  }
   540  
   541  func (msi *mockSI) Sign(msg []byte) ([]byte, error) {
   542  	return msg, nil
   543  }
   544  
   545  func (msi *mockSI) GetPublicVersion() msp.Identity {
   546  	return msi
   547  }
   548  
   549  // MSP mock for the parallel validation test
   550  type mockMSP struct {
   551  	ID           msp.Identity
   552  	SatPrinError error
   553  	MspID        string
   554  }
   555  
   556  func (fake *mockMSP) DeserializeIdentity(serializedIdentity []byte) (msp.Identity, error) {
   557  	return fake.ID, nil
   558  }
   559  
   560  func (fake *mockMSP) IsWellFormed(identity *mb.SerializedIdentity) error {
   561  	return nil
   562  }
   563  func (fake *mockMSP) Setup(config *mb.MSPConfig) error {
   564  	return nil
   565  }
   566  
   567  func (fake *mockMSP) GetVersion() msp.MSPVersion {
   568  	return msp.MSPv1_3
   569  }
   570  
   571  func (fake *mockMSP) GetType() msp.ProviderType {
   572  	return msp.FABRIC
   573  }
   574  
   575  func (fake *mockMSP) GetIdentifier() (string, error) {
   576  	return fake.MspID, nil
   577  }
   578  
   579  func (fake *mockMSP) GetSigningIdentity(identifier *msp.IdentityIdentifier) (msp.SigningIdentity, error) {
   580  	return nil, nil
   581  }
   582  
   583  func (fake *mockMSP) GetDefaultSigningIdentity() (msp.SigningIdentity, error) {
   584  	return nil, nil
   585  }
   586  
   587  func (fake *mockMSP) GetTLSRootCerts() [][]byte {
   588  	return nil
   589  }
   590  
   591  func (fake *mockMSP) GetTLSIntermediateCerts() [][]byte {
   592  	return nil
   593  }
   594  
   595  func (fake *mockMSP) Validate(id msp.Identity) error {
   596  	return nil
   597  }
   598  
   599  func (fake *mockMSP) SatisfiesPrincipal(id msp.Identity, principal *mb.MSPPrincipal) error {
   600  	return fake.SatPrinError
   601  }
   602  
   603  // parallel validation on a block with a high number of transactions and sbe dependencies among those
   604  func TestParallelValidation(t *testing.T) {
   605  	// number of transactions in the block
   606  	txCnt := 100
   607  
   608  	// create two MSPs to control the policy evaluation result, one of them returning an error on SatisfiesPrincipal()
   609  	msp1 := &mockMSP{
   610  		ID: &mockSI{
   611  			MspID:        "Org1",
   612  			SerializedID: []byte("signer0"),
   613  			SatPrinError: nil,
   614  		},
   615  		SatPrinError: nil,
   616  		MspID:        "Org1",
   617  	}
   618  	msp2 := &mockMSP{
   619  		ID: &mockSI{
   620  			MspID:        "Org2",
   621  			SerializedID: []byte("signer1"),
   622  			SatPrinError: errors.New("nope"),
   623  		},
   624  		SatPrinError: errors.New("nope"),
   625  		MspID:        "Org2",
   626  	}
   627  	mgmt.GetManagerForChain("foochain")
   628  	mgr := mgmt.GetManagerForChain("foochain")
   629  	mgr.Setup([]msp.MSP{msp1, msp2})
   630  
   631  	vpKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   632  	l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(
   633  		t,
   634  		v13Capabilities(),
   635  		&builtin.DefaultValidation{},
   636  		mgr,
   637  	)
   638  	defer cleanup()
   639  
   640  	ccID := "mycc"
   641  
   642  	policy := policydsl.SignedByMspPeer("Org1")
   643  	polBytes := protoutil.MarshalOrPanic(policy)
   644  	putCCInfo(l, ccID, polBytes, t)
   645  
   646  	// create a number of txes
   647  	blockData := make([][]byte, 0, txCnt)
   648  	col := "col1"
   649  	sigID0 := &mockSI{
   650  		SerializedID: []byte("signer0"),
   651  		MspID:        "Org1",
   652  	}
   653  	sigID1 := &mockSI{
   654  		SerializedID: []byte("signer1"),
   655  		MspID:        "Org2",
   656  	}
   657  	for txNum := 0; txNum < txCnt; txNum++ {
   658  		var sig msp.SigningIdentity
   659  		// create rwset for the tx - KVS key depends on the txnum
   660  		key := strconv.Itoa(txNum % 10)
   661  		rwsetBuilder := rwsetutil.NewRWSetBuilder()
   662  		// pick action that we want to do: read / modify the value or the ep
   663  		switch uint(txNum / 10) {
   664  		case 0:
   665  			// set the value of the key (valid)
   666  			rwsetBuilder.AddToWriteSet(ccID, key, []byte("value1"))
   667  			sig = sigID0
   668  		case 1:
   669  			// set the ep of the key (invalid, because Org2's MSP returns principal not satisfied)
   670  			metadata := make(map[string][]byte)
   671  			metadata[vpKey] = signedByAnyMember([]string{"SampleOrg"})
   672  			rwsetBuilder.AddToMetadataWriteSet(ccID, key, metadata)
   673  			sig = sigID1
   674  		case 2:
   675  			// set the value of the key (valid, because the ep change before was invalid)
   676  			rwsetBuilder.AddToWriteSet(ccID, key, []byte("value2"))
   677  			sig = sigID0
   678  		case 3:
   679  			// set the ep of the key (valid)
   680  			metadata := make(map[string][]byte)
   681  			metadata[vpKey] = signedByAnyMember([]string{"Org2"})
   682  			rwsetBuilder.AddToMetadataWriteSet(ccID, key, metadata)
   683  			sig = sigID0
   684  		case 4:
   685  			// set the value of the key (invalid, because the ep change before was valid)
   686  			rwsetBuilder.AddToWriteSet(ccID, key, []byte("value3"))
   687  			sig = &mockSI{
   688  				SerializedID: []byte("signer0"),
   689  				MspID:        "Org1",
   690  			}
   691  		// do the same txes for private data
   692  		case 5:
   693  			// set the value of the key (valid)
   694  			rwsetBuilder.AddToPvtAndHashedWriteSet(ccID, col, key, []byte("value1"))
   695  			sig = sigID0
   696  		case 6:
   697  			// set the ep of the key (invalid, because Org2's MSP returns principal not satisfied)
   698  			metadata := make(map[string][]byte)
   699  			metadata[vpKey] = signedByAnyMember([]string{"SampleOrg"})
   700  			rwsetBuilder.AddToHashedMetadataWriteSet(ccID, col, key, metadata)
   701  			sig = sigID1
   702  		case 7:
   703  			// set the value of the key (valid, because the ep change before was invalid)
   704  			rwsetBuilder.AddToPvtAndHashedWriteSet(ccID, col, key, []byte("value2"))
   705  			sig = sigID0
   706  		case 8:
   707  			// set the ep of the key (valid)
   708  			metadata := make(map[string][]byte)
   709  			metadata[vpKey] = signedByAnyMember([]string{"Org2"})
   710  			rwsetBuilder.AddToHashedMetadataWriteSet(ccID, col, key, metadata)
   711  			sig = sigID0
   712  		case 9:
   713  			// set the value of the key (invalid, because the ep change before was valid)
   714  			rwsetBuilder.AddToPvtAndHashedWriteSet(ccID, col, key, []byte("value3"))
   715  			sig = sigID0
   716  		}
   717  		rwset, err := rwsetBuilder.GetTxSimulationResults()
   718  		assert.NoError(t, err)
   719  		rwsetBytes, err := rwset.GetPubSimulationBytes()
   720  		tx := getEnvWithSigner(ccID, nil, rwsetBytes, sig, t)
   721  		blockData = append(blockData, protoutil.MarshalOrPanic(tx))
   722  	}
   723  
   724  	// assemble block from all those txes
   725  	b := &common.Block{Data: &common.BlockData{Data: blockData}, Header: &common.BlockHeader{Number: uint64(txCnt)}}
   726  
   727  	// validate the block
   728  	err := v.Validate(b)
   729  	assert.NoError(t, err)
   730  
   731  	// Block metadata array position to store serialized bit array filter of invalid transactions
   732  	txsFilter := lutils.TxValidationFlags(b.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   733  	// tx validity
   734  	for txNum := 0; txNum < txCnt; txNum += 1 {
   735  		switch uint(txNum / 10) {
   736  		case 1:
   737  			fallthrough
   738  		case 4:
   739  			fallthrough
   740  		case 6:
   741  			fallthrough
   742  		case 9:
   743  			assert.True(t, txsFilter.IsInvalid(txNum))
   744  		default:
   745  			assert.False(t, txsFilter.IsInvalid(txNum))
   746  		}
   747  	}
   748  }
   749  
   750  func TestChaincodeEvent(t *testing.T) {
   751  	t.Run("PreV1.2", func(t *testing.T) {
   752  		t.Run("MisMatchedName", func(t *testing.T) {
   753  			l, v, cleanup := setupLedgerAndValidatorWithPreV12Capabilities(t)
   754  			defer cleanup()
   755  
   756  			ccID := "mycc"
   757  
   758  			putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   759  
   760  			tx := getEnv(ccID, protoutil.MarshalOrPanic(&peer.ChaincodeEvent{ChaincodeId: "wrong"}), createRWset(t), t)
   761  			b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   762  
   763  			err := v.Validate(b)
   764  			assert.NoError(t, err)
   765  			assertValid(b, t)
   766  		})
   767  
   768  		t.Run("BadBytes", func(t *testing.T) {
   769  			l, v, cleanup := setupLedgerAndValidatorWithPreV12Capabilities(t)
   770  			defer cleanup()
   771  
   772  			ccID := "mycc"
   773  
   774  			putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   775  
   776  			tx := getEnv(ccID, []byte("garbage"), createRWset(t), t)
   777  			b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   778  
   779  			err := v.Validate(b)
   780  			assert.NoError(t, err)
   781  			assertValid(b, t)
   782  		})
   783  
   784  		t.Run("GoodPath", func(t *testing.T) {
   785  			l, v, cleanup := setupLedgerAndValidatorWithPreV12Capabilities(t)
   786  			defer cleanup()
   787  
   788  			ccID := "mycc"
   789  
   790  			putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   791  
   792  			tx := getEnv(ccID, protoutil.MarshalOrPanic(&peer.ChaincodeEvent{ChaincodeId: ccID}), createRWset(t), t)
   793  			b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   794  
   795  			err := v.Validate(b)
   796  			assert.NoError(t, err)
   797  			assertValid(b, t)
   798  		})
   799  	})
   800  
   801  	t.Run("PostV1.2", func(t *testing.T) {
   802  		t.Run("MisMatchedName", func(t *testing.T) {
   803  			l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   804  			defer cleanup()
   805  
   806  			testCCEventMismatchedName(t, l, v)
   807  		})
   808  
   809  		t.Run("BadBytes", func(t *testing.T) {
   810  			l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   811  			defer cleanup()
   812  
   813  			testCCEventBadBytes(t, l, v)
   814  		})
   815  
   816  		t.Run("GoodPath", func(t *testing.T) {
   817  			l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
   818  			defer cleanup()
   819  
   820  			testCCEventGoodPath(t, l, v)
   821  		})
   822  	})
   823  
   824  	t.Run("V1.3", func(t *testing.T) {
   825  		t.Run("MisMatchedName", func(t *testing.T) {
   826  			l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   827  			defer cleanup()
   828  
   829  			testCCEventMismatchedName(t, l, v)
   830  		})
   831  
   832  		t.Run("BadBytes", func(t *testing.T) {
   833  			l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   834  			defer cleanup()
   835  
   836  			testCCEventBadBytes(t, l, v)
   837  		})
   838  
   839  		t.Run("GoodPath", func(t *testing.T) {
   840  			l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
   841  			defer cleanup()
   842  
   843  			testCCEventGoodPath(t, l, v)
   844  		})
   845  	})
   846  }
   847  
   848  func testCCEventMismatchedName(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   849  	ccID := "mycc"
   850  
   851  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   852  
   853  	tx := getEnv(ccID, protoutil.MarshalOrPanic(&peer.ChaincodeEvent{ChaincodeId: "wrong"}), createRWset(t), t)
   854  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   855  
   856  	err := v.Validate(b)
   857  	assert.NoError(t, err) // TODO, convert test so it can check the error text for INVALID_OTHER_REASON
   858  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   859  }
   860  
   861  func testCCEventBadBytes(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   862  	ccID := "mycc"
   863  
   864  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   865  
   866  	tx := getEnv(ccID, []byte("garbage"), createRWset(t), t)
   867  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   868  
   869  	err := v.Validate(b)
   870  	assert.NoError(t, err) // TODO, convert test so it can check the error text for INVALID_OTHER_REASON
   871  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
   872  }
   873  
   874  func testCCEventGoodPath(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   875  	ccID := "mycc"
   876  
   877  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   878  
   879  	tx := getEnv(ccID, protoutil.MarshalOrPanic(&peer.ChaincodeEvent{ChaincodeId: ccID}), createRWset(t), t)
   880  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   881  
   882  	err := v.Validate(b)
   883  	assert.NoError(t, err)
   884  	assertValid(b, t)
   885  }
   886  
   887  func TestInvokeOKPvtDataOnly(t *testing.T) {
   888  	mspmgr := &mocks2.MSPManager{}
   889  	idThatSatisfiesPrincipal := &mocks2.Identity{}
   890  	idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(errors.New("principal not satisfied"))
   891  	idThatSatisfiesPrincipal.GetIdentifierReturns(&msp.IdentityIdentifier{})
   892  	mspmgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil)
   893  
   894  	t.Run("V1.2", func(t *testing.T) {
   895  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v12Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   896  		defer cleanup()
   897  
   898  		testInvokeOKPvtDataOnly(t, l, v)
   899  	})
   900  
   901  	t.Run("V1.3", func(t *testing.T) {
   902  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v13Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   903  		defer cleanup()
   904  
   905  		testInvokeOKPvtDataOnly(t, l, v)
   906  	})
   907  }
   908  
   909  func testInvokeOKPvtDataOnly(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   910  	ccID := "mycc"
   911  
   912  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   913  
   914  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   915  	rwsetBuilder.AddToPvtAndHashedWriteSet(ccID, "mycollection", "somekey", nil)
   916  	rwset, err := rwsetBuilder.GetTxSimulationResults()
   917  	assert.NoError(t, err)
   918  	rwsetBytes, err := rwset.GetPubSimulationBytes()
   919  	assert.NoError(t, err)
   920  
   921  	tx := getEnv(ccID, nil, rwsetBytes, t)
   922  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   923  
   924  	err = v.Validate(b)
   925  	assert.NoError(t, err)
   926  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
   927  }
   928  
   929  func TestInvokeOKMetaUpdateOnly(t *testing.T) {
   930  	mspmgr := &mocks2.MSPManager{}
   931  	idThatSatisfiesPrincipal := &mocks2.Identity{}
   932  	idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(errors.New("principal not satisfied"))
   933  	idThatSatisfiesPrincipal.GetIdentifierReturns(&msp.IdentityIdentifier{})
   934  	mspmgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil)
   935  
   936  	t.Run("V1.2", func(t *testing.T) {
   937  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v12Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   938  		defer cleanup()
   939  
   940  		testInvokeOKMetaUpdateOnly(t, l, v)
   941  	})
   942  
   943  	t.Run("V1.3", func(t *testing.T) {
   944  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v13Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   945  		defer cleanup()
   946  
   947  		testInvokeOKMetaUpdateOnly(t, l, v)
   948  	})
   949  }
   950  
   951  func testInvokeOKMetaUpdateOnly(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   952  	ccID := "mycc"
   953  
   954  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   955  
   956  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   957  	rwsetBuilder.AddToMetadataWriteSet(ccID, "somekey", map[string][]byte{})
   958  	rwset, err := rwsetBuilder.GetTxSimulationResults()
   959  	assert.NoError(t, err)
   960  	rwsetBytes, err := rwset.GetPubSimulationBytes()
   961  	assert.NoError(t, err)
   962  
   963  	tx := getEnv(ccID, nil, rwsetBytes, t)
   964  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
   965  
   966  	err = v.Validate(b)
   967  	assert.NoError(t, err)
   968  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
   969  }
   970  
   971  func TestInvokeOKPvtMetaUpdateOnly(t *testing.T) {
   972  	mspmgr := &mocks2.MSPManager{}
   973  	idThatSatisfiesPrincipal := &mocks2.Identity{}
   974  	idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(errors.New("principal not satisfied"))
   975  	idThatSatisfiesPrincipal.GetIdentifierReturns(&msp.IdentityIdentifier{})
   976  	mspmgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil)
   977  
   978  	t.Run("V1.2", func(t *testing.T) {
   979  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v12Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   980  		defer cleanup()
   981  
   982  		testInvokeOKPvtMetaUpdateOnly(t, l, v)
   983  	})
   984  
   985  	t.Run("V1.3", func(t *testing.T) {
   986  		l, v, cleanup := setupLedgerAndValidatorExplicitWithMSP(t, v13Capabilities(), &builtin.DefaultValidation{}, mspmgr)
   987  		defer cleanup()
   988  
   989  		testInvokeOKPvtMetaUpdateOnly(t, l, v)
   990  	})
   991  }
   992  
   993  func testInvokeOKPvtMetaUpdateOnly(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
   994  	ccID := "mycc"
   995  
   996  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
   997  
   998  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   999  	rwsetBuilder.AddToHashedMetadataWriteSet(ccID, "mycollection", "somekey", map[string][]byte{})
  1000  	rwset, err := rwsetBuilder.GetTxSimulationResults()
  1001  	assert.NoError(t, err)
  1002  	rwsetBytes, err := rwset.GetPubSimulationBytes()
  1003  	assert.NoError(t, err)
  1004  
  1005  	tx := getEnv(ccID, nil, rwsetBytes, t)
  1006  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
  1007  
  1008  	err = v.Validate(b)
  1009  	assert.NoError(t, err)
  1010  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
  1011  }
  1012  
  1013  func TestInvokeOKSCC(t *testing.T) {
  1014  	t.Run("1.2Capability", func(t *testing.T) {
  1015  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1016  		defer cleanup()
  1017  
  1018  		testInvokeOKSCC(t, l, v)
  1019  	})
  1020  
  1021  	t.Run("1.3Capability", func(t *testing.T) {
  1022  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1023  		defer cleanup()
  1024  
  1025  		testInvokeOKSCC(t, l, v)
  1026  	})
  1027  }
  1028  
  1029  func testInvokeOKSCC(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1030  	cds := protoutil.MarshalOrPanic(&peer.ChaincodeDeploymentSpec{
  1031  		ChaincodeSpec: &peer.ChaincodeSpec{
  1032  			Type:        peer.ChaincodeSpec_GOLANG,
  1033  			ChaincodeId: &peer.ChaincodeID{Name: "cc", Version: "ver"},
  1034  			Input:       &peer.ChaincodeInput{},
  1035  		},
  1036  	})
  1037  	cis := &peer.ChaincodeInvocationSpec{
  1038  		ChaincodeSpec: &peer.ChaincodeSpec{
  1039  			ChaincodeId: &peer.ChaincodeID{Name: "lscc", Version: ccVersion},
  1040  			Input:       &peer.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte("testchannelid"), cds}},
  1041  			Type:        peer.ChaincodeSpec_GOLANG}}
  1042  
  1043  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, signerSerialized)
  1044  	assert.NoError(t, err)
  1045  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
  1046  	rwsetBuilder.AddToWriteSet("lscc", "cc", protoutil.MarshalOrPanic(&ccp.ChaincodeData{Name: "cc", Version: "ver", InstantiationPolicy: policydsl.MarshaledAcceptAllPolicy}))
  1047  	rwset, err := rwsetBuilder.GetTxSimulationResults()
  1048  	assert.NoError(t, err)
  1049  	rwsetBytes, err := rwset.GetPubSimulationBytes()
  1050  	assert.NoError(t, err)
  1051  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, rwsetBytes, nil, &peer.ChaincodeID{Name: "lscc", Version: ccVersion}, signer)
  1052  	assert.NoError(t, err)
  1053  	tx, err := protoutil.CreateSignedTx(prop, signer, presp)
  1054  	assert.NoError(t, err)
  1055  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 1}}
  1056  
  1057  	err = v.Validate(b)
  1058  	assert.NoError(t, err)
  1059  	assertValid(b, t)
  1060  }
  1061  
  1062  func TestInvokeNOKWritesToLSCC(t *testing.T) {
  1063  	t.Run("1.2Capability", func(t *testing.T) {
  1064  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1065  		defer cleanup()
  1066  
  1067  		testInvokeNOKWritesToLSCC(t, l, v)
  1068  	})
  1069  
  1070  	t.Run("1.3Capability", func(t *testing.T) {
  1071  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1072  		defer cleanup()
  1073  
  1074  		testInvokeNOKWritesToLSCC(t, l, v)
  1075  	})
  1076  }
  1077  
  1078  func testInvokeNOKWritesToLSCC(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1079  	ccID := "mycc"
  1080  
  1081  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1082  
  1083  	tx := getEnv(ccID, nil, createRWset(t, ccID, "lscc"), t)
  1084  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 2}}
  1085  
  1086  	err := v.Validate(b)
  1087  	assert.NoError(t, err)
  1088  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
  1089  }
  1090  
  1091  func TestInvokeNOKWritesToESCC(t *testing.T) {
  1092  	t.Run("1.2Capability", func(t *testing.T) {
  1093  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1094  		defer cleanup()
  1095  
  1096  		testInvokeNOKWritesToESCC(t, l, v)
  1097  	})
  1098  
  1099  	t.Run("1.3Capability", func(t *testing.T) {
  1100  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1101  		defer cleanup()
  1102  
  1103  		testInvokeNOKWritesToESCC(t, l, v)
  1104  	})
  1105  }
  1106  
  1107  func testInvokeNOKWritesToESCC(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1108  	ccID := "mycc"
  1109  
  1110  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1111  
  1112  	tx := getEnv(ccID, nil, createRWset(t, ccID, "escc"), t)
  1113  	b := &common.Block{
  1114  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1115  		Header: &common.BlockHeader{},
  1116  	}
  1117  
  1118  	err := v.Validate(b)
  1119  	assert.NoError(t, err)
  1120  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
  1121  }
  1122  
  1123  func TestInvokeNOKWritesToNotExt(t *testing.T) {
  1124  	t.Run("1.2Capability", func(t *testing.T) {
  1125  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1126  		defer cleanup()
  1127  
  1128  		testInvokeNOKWritesToNotExt(t, l, v)
  1129  	})
  1130  
  1131  	t.Run("1.3Capability", func(t *testing.T) {
  1132  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1133  		defer cleanup()
  1134  
  1135  		testInvokeNOKWritesToNotExt(t, l, v)
  1136  	})
  1137  }
  1138  
  1139  func testInvokeNOKWritesToNotExt(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1140  	ccID := "mycc"
  1141  
  1142  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1143  
  1144  	tx := getEnv(ccID, nil, createRWset(t, ccID, "escc"), t)
  1145  	b := &common.Block{
  1146  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1147  		Header: &common.BlockHeader{},
  1148  	}
  1149  
  1150  	err := v.Validate(b)
  1151  	assert.NoError(t, err)
  1152  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
  1153  }
  1154  
  1155  func TestInvokeNOKInvokesNotExt(t *testing.T) {
  1156  	t.Run("1.2Capability", func(t *testing.T) {
  1157  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1158  		defer cleanup()
  1159  
  1160  		testInvokeNOKInvokesNotExt(t, l, v)
  1161  	})
  1162  
  1163  	t.Run("1.3Capability", func(t *testing.T) {
  1164  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1165  		defer cleanup()
  1166  
  1167  		testInvokeNOKInvokesNotExt(t, l, v)
  1168  	})
  1169  }
  1170  
  1171  func testInvokeNOKInvokesNotExt(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1172  	ccID := "escc"
  1173  
  1174  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1175  
  1176  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1177  	b := &common.Block{
  1178  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1179  		Header: &common.BlockHeader{},
  1180  	}
  1181  
  1182  	err := v.Validate(b)
  1183  	assert.NoError(t, err)
  1184  	assertInvalid(b, t, peer.TxValidationCode_ILLEGAL_WRITESET)
  1185  }
  1186  
  1187  func TestInvokeNOKInvokesEmptyCCName(t *testing.T) {
  1188  	t.Run("1.2Capability", func(t *testing.T) {
  1189  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1190  		defer cleanup()
  1191  
  1192  		testInvokeNOKInvokesEmptyCCName(t, l, v)
  1193  	})
  1194  
  1195  	t.Run("1.3Capability", func(t *testing.T) {
  1196  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1197  		defer cleanup()
  1198  
  1199  		testInvokeNOKInvokesEmptyCCName(t, l, v)
  1200  	})
  1201  }
  1202  
  1203  func testInvokeNOKInvokesEmptyCCName(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1204  	ccID := ""
  1205  
  1206  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1207  
  1208  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1209  	b := &common.Block{
  1210  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1211  		Header: &common.BlockHeader{},
  1212  	}
  1213  
  1214  	err := v.Validate(b)
  1215  	assert.NoError(t, err)
  1216  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
  1217  }
  1218  
  1219  func TestInvokeNOKExpiredCC(t *testing.T) {
  1220  	t.Run("1.2Capability", func(t *testing.T) {
  1221  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1222  		defer cleanup()
  1223  
  1224  		testInvokeNOKExpiredCC(t, l, v)
  1225  	})
  1226  
  1227  	t.Run("1.3Capability", func(t *testing.T) {
  1228  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1229  		defer cleanup()
  1230  
  1231  		testInvokeNOKExpiredCC(t, l, v)
  1232  	})
  1233  }
  1234  
  1235  func testInvokeNOKExpiredCC(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1236  	ccID := "mycc"
  1237  
  1238  	putCCInfoWithVSCCAndVer(l, ccID, "vscc", "badversion", signedByAnyMember([]string{"SampleOrg"}), t)
  1239  
  1240  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1241  	b := &common.Block{
  1242  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1243  		Header: &common.BlockHeader{},
  1244  	}
  1245  
  1246  	err := v.Validate(b)
  1247  	assert.NoError(t, err)
  1248  	assertInvalid(b, t, peer.TxValidationCode_EXPIRED_CHAINCODE)
  1249  }
  1250  
  1251  func TestInvokeNOKBogusActions(t *testing.T) {
  1252  	t.Run("1.2Capability", func(t *testing.T) {
  1253  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1254  		defer cleanup()
  1255  
  1256  		testInvokeNOKBogusActions(t, l, v)
  1257  	})
  1258  
  1259  	t.Run("1.3Capability", func(t *testing.T) {
  1260  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1261  		defer cleanup()
  1262  
  1263  		testInvokeNOKBogusActions(t, l, v)
  1264  	})
  1265  }
  1266  
  1267  func testInvokeNOKBogusActions(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1268  	ccID := "mycc"
  1269  
  1270  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1271  
  1272  	tx := getEnv(ccID, nil, []byte("barf"), t)
  1273  	b := &common.Block{
  1274  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1275  		Header: &common.BlockHeader{},
  1276  	}
  1277  
  1278  	err := v.Validate(b)
  1279  	assert.NoError(t, err)
  1280  	assertInvalid(b, t, peer.TxValidationCode_BAD_RWSET)
  1281  }
  1282  
  1283  func TestInvokeNOKCCDoesntExist(t *testing.T) {
  1284  	t.Run("1.2Capability", func(t *testing.T) {
  1285  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1286  		defer cleanup()
  1287  
  1288  		testInvokeNOKCCDoesntExist(t, l, v)
  1289  	})
  1290  
  1291  	t.Run("1.3Capability", func(t *testing.T) {
  1292  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1293  		defer cleanup()
  1294  
  1295  		testInvokeNOKCCDoesntExist(t, l, v)
  1296  	})
  1297  }
  1298  
  1299  func testInvokeNOKCCDoesntExist(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1300  	ccID := "mycc"
  1301  
  1302  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1303  	b := &common.Block{
  1304  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1305  		Header: &common.BlockHeader{},
  1306  	}
  1307  
  1308  	err := v.Validate(b)
  1309  	assert.NoError(t, err)
  1310  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
  1311  }
  1312  
  1313  func TestInvokeNOKVSCCUnspecified(t *testing.T) {
  1314  	t.Run("1.2Capability", func(t *testing.T) {
  1315  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1316  		defer cleanup()
  1317  
  1318  		testInvokeNOKVSCCUnspecified(t, l, v)
  1319  	})
  1320  
  1321  	t.Run("1.3Capability", func(t *testing.T) {
  1322  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1323  		defer cleanup()
  1324  
  1325  		testInvokeNOKVSCCUnspecified(t, l, v)
  1326  	})
  1327  }
  1328  
  1329  func testInvokeNOKVSCCUnspecified(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1330  	ccID := "mycc"
  1331  
  1332  	putCCInfoWithVSCCAndVer(l, ccID, "", ccVersion, signedByAnyMember([]string{"SampleOrg"}), t)
  1333  
  1334  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1335  	b := &common.Block{
  1336  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1337  		Header: &common.BlockHeader{},
  1338  	}
  1339  
  1340  	err := v.Validate(b)
  1341  	assert.NoError(t, err)
  1342  	assertInvalid(b, t, peer.TxValidationCode_INVALID_OTHER_REASON)
  1343  }
  1344  
  1345  func TestInvokeNoBlock(t *testing.T) {
  1346  	t.Run("1.2Capability", func(t *testing.T) {
  1347  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1348  		defer cleanup()
  1349  
  1350  		testInvokeNoBlock(t, l, v)
  1351  	})
  1352  
  1353  	t.Run("1.3Capability", func(t *testing.T) {
  1354  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1355  		defer cleanup()
  1356  
  1357  		testInvokeNoBlock(t, l, v)
  1358  	})
  1359  }
  1360  
  1361  func testInvokeNoBlock(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) {
  1362  	err := v.Validate(&common.Block{
  1363  		Data:   &common.BlockData{Data: [][]byte{}},
  1364  		Header: &common.BlockHeader{},
  1365  	})
  1366  	assert.NoError(t, err)
  1367  }
  1368  
  1369  func TestValidateTxWithStateBasedEndorsement(t *testing.T) {
  1370  
  1371  	// SCENARIO: we validate a transaction that writes to key "key". This key
  1372  	// has a state-based endorsement policy that cannot be satisfied, while
  1373  	// the chaincode endorseemnt policy is satisfied by this transaction.
  1374  	// When we run with the 1.2 capability we expect the transaction to be
  1375  	// successfully validated, while when we run with the 1.3 capability,
  1376  	// validation is expected to fail owing to the unsatisfiable SBEP.
  1377  	// Notice that this corner case should never occur in practice, since
  1378  	// capabilities also determine whether honest peers will endorse
  1379  	// chaincodes that set state-based endorsement policies. Still, the test
  1380  	// is valuable as it shows how transactions that are affected by state-based
  1381  	// endorsement policies are handled by the 1.3 validation, and simply
  1382  	// ignored by 1.2.
  1383  
  1384  	t.Run("1.2Capability", func(t *testing.T) {
  1385  		l, v, cleanup := setupLedgerAndValidatorWithV12Capabilities(t)
  1386  		defer cleanup()
  1387  
  1388  		err, b := validateTxWithStateBasedEndorsement(t, l, v)
  1389  
  1390  		assert.NoError(t, err)
  1391  		assertValid(b, t)
  1392  	})
  1393  
  1394  	t.Run("1.3Capability", func(t *testing.T) {
  1395  		l, v, cleanup := setupLedgerAndValidatorWithV13Capabilities(t)
  1396  		defer cleanup()
  1397  
  1398  		err, b := validateTxWithStateBasedEndorsement(t, l, v)
  1399  
  1400  		assert.NoError(t, err)
  1401  		assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
  1402  	})
  1403  }
  1404  
  1405  func validateTxWithStateBasedEndorsement(t *testing.T, l ledger.PeerLedger, v txvalidator.Validator) (error, *common.Block) {
  1406  	ccID := "mycc"
  1407  
  1408  	putCCInfoWithVSCCAndVer(l, ccID, "vscc", ccVersion, signedByAnyMember([]string{"SampleOrg"}), t)
  1409  	putSBEP(l, ccID, "key", policydsl.MarshaledRejectAllPolicy, t)
  1410  
  1411  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1412  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}}, Header: &common.BlockHeader{Number: 3}}
  1413  
  1414  	err := v.Validate(b)
  1415  
  1416  	return err, b
  1417  }
  1418  
  1419  // mockLedger structure used to test ledger
  1420  // failure, therefore leveraging mocking
  1421  // library as need to simulate ledger which not
  1422  // able to get access to state db
  1423  type mockLedger struct {
  1424  	mock.Mock
  1425  }
  1426  
  1427  // GetTransactionByID returns transaction by ud
  1428  func (m *mockLedger) GetTransactionByID(txID string) (*peer.ProcessedTransaction, error) {
  1429  	args := m.Called(txID)
  1430  	return args.Get(0).(*peer.ProcessedTransaction), args.Error(1)
  1431  }
  1432  
  1433  // GetBlockByHash returns block using its hash value
  1434  func (m *mockLedger) GetBlockByHash(blockHash []byte) (*common.Block, error) {
  1435  	args := m.Called(blockHash)
  1436  	return args.Get(0).(*common.Block), nil
  1437  }
  1438  
  1439  // GetBlockByTxID given transaction id return block transaction was committed with
  1440  func (m *mockLedger) GetBlockByTxID(txID string) (*common.Block, error) {
  1441  	args := m.Called(txID)
  1442  	return args.Get(0).(*common.Block), nil
  1443  }
  1444  
  1445  // GetTxValidationCodeByTxID returns validation code of give tx
  1446  func (m *mockLedger) GetTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error) {
  1447  	args := m.Called(txID)
  1448  	return args.Get(0).(peer.TxValidationCode), nil
  1449  }
  1450  
  1451  // NewTxSimulator creates new transaction simulator
  1452  func (m *mockLedger) NewTxSimulator(txid string) (ledger.TxSimulator, error) {
  1453  	args := m.Called()
  1454  	return args.Get(0).(ledger.TxSimulator), nil
  1455  }
  1456  
  1457  // NewQueryExecutor creates query executor
  1458  func (m *mockLedger) NewQueryExecutor() (ledger.QueryExecutor, error) {
  1459  	args := m.Called()
  1460  	return args.Get(0).(ledger.QueryExecutor), nil
  1461  }
  1462  
  1463  // NewHistoryQueryExecutor history query executor
  1464  func (m *mockLedger) NewHistoryQueryExecutor() (ledger.HistoryQueryExecutor, error) {
  1465  	args := m.Called()
  1466  	return args.Get(0).(ledger.HistoryQueryExecutor), nil
  1467  }
  1468  
  1469  // GetPvtDataAndBlockByNum retrieves pvt data and block
  1470  func (m *mockLedger) GetPvtDataAndBlockByNum(blockNum uint64, filter ledger.PvtNsCollFilter) (*ledger.BlockAndPvtData, error) {
  1471  	args := m.Called()
  1472  	return args.Get(0).(*ledger.BlockAndPvtData), nil
  1473  }
  1474  
  1475  // GetPvtDataByNum retrieves the pvt data
  1476  func (m *mockLedger) GetPvtDataByNum(blockNum uint64, filter ledger.PvtNsCollFilter) ([]*ledger.TxPvtData, error) {
  1477  	args := m.Called()
  1478  	return args.Get(0).([]*ledger.TxPvtData), nil
  1479  }
  1480  
  1481  // CommitLegacy commits the block and the corresponding pvt data in an atomic operation
  1482  func (m *mockLedger) CommitLegacy(pvtDataAndBlock *ledger.BlockAndPvtData, commitOpts *ledger.CommitOptions) error {
  1483  	return nil
  1484  }
  1485  
  1486  func (m *mockLedger) GetBlockchainInfo() (*common.BlockchainInfo, error) {
  1487  	args := m.Called()
  1488  	return args.Get(0).(*common.BlockchainInfo), nil
  1489  }
  1490  
  1491  func (m *mockLedger) GetBlockByNumber(blockNumber uint64) (*common.Block, error) {
  1492  	args := m.Called(blockNumber)
  1493  	return args.Get(0).(*common.Block), nil
  1494  }
  1495  
  1496  func (m *mockLedger) GetBlocksIterator(startBlockNumber uint64) (ledger2.ResultsIterator, error) {
  1497  	args := m.Called(startBlockNumber)
  1498  	return args.Get(0).(ledger2.ResultsIterator), nil
  1499  }
  1500  
  1501  func (m *mockLedger) DoesPvtDataInfoExist(blkNum uint64) (bool, error) {
  1502  	args := m.Called()
  1503  	return args.Get(0).(bool), args.Error(1)
  1504  }
  1505  
  1506  func (m *mockLedger) Close() {
  1507  
  1508  }
  1509  
  1510  func (m *mockLedger) Commit(block *common.Block) error {
  1511  	return nil
  1512  }
  1513  
  1514  // GetConfigHistoryRetriever returns the ConfigHistoryRetriever
  1515  func (m *mockLedger) GetConfigHistoryRetriever() (ledger.ConfigHistoryRetriever, error) {
  1516  	args := m.Called()
  1517  	return args.Get(0).(ledger.ConfigHistoryRetriever), nil
  1518  }
  1519  
  1520  func (m *mockLedger) CommitPvtDataOfOldBlocks(reconciledPvtdata []*ledger.ReconciledPvtdata) ([]*ledger.PvtdataHashMismatch, error) {
  1521  	return nil, nil
  1522  }
  1523  
  1524  func (m *mockLedger) GetMissingPvtDataTracker() (ledger.MissingPvtDataTracker, error) {
  1525  	args := m.Called()
  1526  	return args.Get(0).(ledger.MissingPvtDataTracker), nil
  1527  }
  1528  
  1529  // mockQueryExecutor mock of the query executor,
  1530  // needed to simulate inability to access state db, e.g.
  1531  // the case where due to db failure it's not possible to
  1532  // query for state, for example if we would like to query
  1533  // the lccc for VSCC info and db is not avaible we expect
  1534  // to stop validating block and fail commit procedure with
  1535  // an error.
  1536  type mockQueryExecutor struct {
  1537  	mock.Mock
  1538  }
  1539  
  1540  func (exec *mockQueryExecutor) GetState(namespace string, key string) ([]byte, error) {
  1541  	args := exec.Called(namespace, key)
  1542  	return args.Get(0).([]byte), args.Error(1)
  1543  }
  1544  
  1545  func (exec *mockQueryExecutor) GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error) {
  1546  	args := exec.Called(namespace, keys)
  1547  	return args.Get(0).([][]byte), args.Error(1)
  1548  }
  1549  
  1550  func (exec *mockQueryExecutor) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ledger2.ResultsIterator, error) {
  1551  	args := exec.Called(namespace, startKey, endKey)
  1552  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
  1553  }
  1554  
  1555  func (exec *mockQueryExecutor) GetStateRangeScanIteratorWithMetadata(namespace, startKey, endKey string, metadata map[string]interface{}) (ledger.QueryResultsIterator, error) {
  1556  	args := exec.Called(namespace, startKey, endKey, metadata)
  1557  	return args.Get(0).(ledger.QueryResultsIterator), args.Error(1)
  1558  }
  1559  
  1560  func (exec *mockQueryExecutor) ExecuteQuery(namespace, query string) (ledger2.ResultsIterator, error) {
  1561  	args := exec.Called(namespace)
  1562  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
  1563  }
  1564  
  1565  func (exec *mockQueryExecutor) ExecuteQueryWithMetadata(namespace, query string, metadata map[string]interface{}) (ledger.QueryResultsIterator, error) {
  1566  	args := exec.Called(namespace, query, metadata)
  1567  	return args.Get(0).(ledger.QueryResultsIterator), args.Error(1)
  1568  }
  1569  
  1570  func (exec *mockQueryExecutor) GetPrivateData(namespace, collection, key string) ([]byte, error) {
  1571  	args := exec.Called(namespace, collection, key)
  1572  	return args.Get(0).([]byte), args.Error(1)
  1573  }
  1574  
  1575  func (exec *mockQueryExecutor) GetPrivateDataHash(namespace, collection, key string) ([]byte, error) {
  1576  	args := exec.Called(namespace, collection, key)
  1577  	return args.Get(0).([]byte), args.Error(1)
  1578  }
  1579  
  1580  func (exec *mockQueryExecutor) GetPrivateDataMetadataByHash(namespace, collection string, keyhash []byte) (map[string][]byte, error) {
  1581  	args := exec.Called(namespace, collection, keyhash)
  1582  	return args.Get(0).(map[string][]byte), args.Error(1)
  1583  }
  1584  
  1585  func (exec *mockQueryExecutor) GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([][]byte, error) {
  1586  	args := exec.Called(namespace, collection, keys)
  1587  	return args.Get(0).([][]byte), args.Error(1)
  1588  }
  1589  
  1590  func (exec *mockQueryExecutor) GetPrivateDataRangeScanIterator(namespace, collection, startKey, endKey string) (ledger2.ResultsIterator, error) {
  1591  	args := exec.Called(namespace, collection, startKey, endKey)
  1592  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
  1593  }
  1594  
  1595  func (exec *mockQueryExecutor) ExecuteQueryOnPrivateData(namespace, collection, query string) (ledger2.ResultsIterator, error) {
  1596  	args := exec.Called(namespace, collection, query)
  1597  	return args.Get(0).(ledger2.ResultsIterator), args.Error(1)
  1598  }
  1599  
  1600  func (exec *mockQueryExecutor) Done() {
  1601  }
  1602  
  1603  func (exec *mockQueryExecutor) GetStateMetadata(namespace, key string) (map[string][]byte, error) {
  1604  	return nil, nil
  1605  }
  1606  
  1607  func (exec *mockQueryExecutor) GetPrivateDataMetadata(namespace, collection, key string) (map[string][]byte, error) {
  1608  	return nil, nil
  1609  }
  1610  
  1611  func createCustomSupportAndLedger(t *testing.T) (*mocktxvalidator.Support, ledger.PeerLedger, func()) {
  1612  	ledgerMgr, cleanup := constructLedgerMgrWithTestDefaults(t, "txvalidator")
  1613  	gb, err := ctxt.MakeGenesisBlock("TestLedger")
  1614  	assert.NoError(t, err)
  1615  	l, err := ledgerMgr.CreateLedger("TestLedger", gb)
  1616  	assert.NoError(t, err)
  1617  
  1618  	identity := &mocks2.Identity{}
  1619  	identity.GetIdentifierReturns(&msp.IdentityIdentifier{
  1620  		Mspid: "SampleOrg",
  1621  		Id:    "foo",
  1622  	})
  1623  	mspManager := &mocks2.MSPManager{}
  1624  	mspManager.DeserializeIdentityReturns(identity, nil)
  1625  	support := &mocktxvalidator.Support{LedgerVal: l, ACVal: preV12Capabilities(), MSPManagerVal: mspManager}
  1626  	return support, l, cleanup
  1627  }
  1628  
  1629  func TestDynamicCapabilitiesAndMSP(t *testing.T) {
  1630  	factory := &mocks.PluginFactory{}
  1631  	factory.On("New").Return(testdata.NewSampleValidationPlugin(t))
  1632  	pm := &mocks.Mapper{}
  1633  	pm.On("FactoryByName", vp.Name("vscc")).Return(factory)
  1634  
  1635  	support, l, cleanup := createCustomSupportAndLedger(t)
  1636  	defer cleanup()
  1637  
  1638  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1639  	assert.NoError(t, err)
  1640  	v := txvalidatorv14.NewTxValidator("", semaphore.New(10), support, pm, cryptoProvider)
  1641  
  1642  	ccID := "mycc"
  1643  
  1644  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1645  
  1646  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1647  	b := &common.Block{
  1648  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1649  		Header: &common.BlockHeader{},
  1650  	}
  1651  
  1652  	// Perform a validation of a block
  1653  	err = v.Validate(b)
  1654  	assert.NoError(t, err)
  1655  	assertValid(b, t)
  1656  	// Record the number of times the capabilities and the MSP Manager were invoked
  1657  	capabilityInvokeCount := support.CapabilitiesInvokeCount()
  1658  	mspManagerInvokeCount := support.MSPManagerInvokeCount()
  1659  
  1660  	// Perform another validation pass, and ensure it is valid
  1661  	err = v.Validate(b)
  1662  	assert.NoError(t, err)
  1663  	assertValid(b, t)
  1664  
  1665  	// Ensure that the capabilities were retrieved from the support twice,
  1666  	// which proves that the capabilities are dynamically retrieved from the support each time
  1667  	assert.Equal(t, 2*capabilityInvokeCount, support.CapabilitiesInvokeCount())
  1668  	// Ensure that the MSP Manager was retrieved from the support twice,
  1669  	// which proves that the MSP Manager is dynamically retrieved from the support each time
  1670  	assert.Equal(t, 2*mspManagerInvokeCount, support.MSPManagerInvokeCount())
  1671  }
  1672  
  1673  // TestLedgerIsNoAvailable simulates and provides a test for following scenario,
  1674  // which is based on FAB-535. Test checks the validation path which expects that
  1675  // DB won't available while trying to lookup for VSCC from LCCC and therefore
  1676  // transaction validation will have to fail. In such case the outcome should be
  1677  // the error return from validate block method and processing of transactions
  1678  // has to stop. There is suppose to be clear indication of the failure with error
  1679  // returned from the function call.
  1680  func TestLedgerIsNoAvailable(t *testing.T) {
  1681  	theLedger := new(mockLedger)
  1682  	pm := &mocks.Mapper{}
  1683  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1684  	assert.NoError(t, err)
  1685  	validator := txvalidatorv14.NewTxValidator(
  1686  		"",
  1687  		semaphore.New(10),
  1688  		&mocktxvalidator.Support{LedgerVal: theLedger, ACVal: preV12Capabilities()},
  1689  		pm,
  1690  		cryptoProvider,
  1691  	)
  1692  
  1693  	ccID := "mycc"
  1694  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1695  
  1696  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, ledger.NotFoundInIndexErr(""))
  1697  
  1698  	queryExecutor := new(mockQueryExecutor)
  1699  	queryExecutor.On("GetState", mock.Anything, mock.Anything).Return([]byte{}, errors.New("Unable to connect to DB"))
  1700  	theLedger.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)
  1701  
  1702  	b := &common.Block{
  1703  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1704  		Header: &common.BlockHeader{},
  1705  	}
  1706  
  1707  	err = validator.Validate(b)
  1708  
  1709  	assertion := assert.New(t)
  1710  	// We suppose to get the error which indicates we cannot commit the block
  1711  	assertion.Error(err)
  1712  	// The error exptected to be of type VSCCInfoLookupFailureError
  1713  	assertion.NotNil(err.(*commonerrors.VSCCInfoLookupFailureError))
  1714  }
  1715  
  1716  func TestLedgerIsNotAvailableForCheckingTxidDuplicate(t *testing.T) {
  1717  	theLedger := new(mockLedger)
  1718  	pm := &mocks.Mapper{}
  1719  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1720  	assert.NoError(t, err)
  1721  	validator := txvalidatorv14.NewTxValidator(
  1722  		"",
  1723  		semaphore.New(10),
  1724  		&mocktxvalidator.Support{LedgerVal: theLedger, ACVal: preV12Capabilities()},
  1725  		pm,
  1726  		cryptoProvider,
  1727  	)
  1728  
  1729  	ccID := "mycc"
  1730  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1731  
  1732  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, errors.New("Unable to connect to DB"))
  1733  
  1734  	b := &common.Block{
  1735  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1736  		Header: &common.BlockHeader{},
  1737  	}
  1738  
  1739  	err = validator.Validate(b)
  1740  
  1741  	assertion := assert.New(t)
  1742  	// We expect a validation error because the ledger wasn't ready to tell us whether there was a tx with that ID or not
  1743  	assertion.Error(err)
  1744  }
  1745  
  1746  func TestDuplicateTxId(t *testing.T) {
  1747  	theLedger := new(mockLedger)
  1748  	pm := &mocks.Mapper{}
  1749  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1750  	assert.NoError(t, err)
  1751  	validator := txvalidatorv14.NewTxValidator(
  1752  		"",
  1753  		semaphore.New(10),
  1754  		&mocktxvalidator.Support{LedgerVal: theLedger, ACVal: preV12Capabilities()},
  1755  		pm,
  1756  		cryptoProvider,
  1757  	)
  1758  
  1759  	ccID := "mycc"
  1760  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1761  
  1762  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, nil)
  1763  
  1764  	b := &common.Block{
  1765  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1766  		Header: &common.BlockHeader{},
  1767  	}
  1768  
  1769  	err = validator.Validate(b)
  1770  
  1771  	assertion := assert.New(t)
  1772  	// We expect no validation error because we simply mark the tx as invalid
  1773  	assertion.NoError(err)
  1774  
  1775  	// We expect the tx to be invalid because of a duplicate txid
  1776  	txsfltr := lutils.TxValidationFlags(b.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
  1777  	assertion.True(txsfltr.IsInvalid(0))
  1778  	assertion.True(txsfltr.Flag(0) == peer.TxValidationCode_DUPLICATE_TXID)
  1779  }
  1780  
  1781  func TestValidationInvalidEndorsing(t *testing.T) {
  1782  	theLedger := new(mockLedger)
  1783  	pm := &mocks.Mapper{}
  1784  	factory := &mocks.PluginFactory{}
  1785  	plugin := &mocks.Plugin{}
  1786  	factory.On("New").Return(plugin)
  1787  	plugin.On("Init", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
  1788  	plugin.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("invalid tx"))
  1789  	pm.On("FactoryByName", vp.Name("vscc")).Return(factory)
  1790  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1791  	assert.NoError(t, err)
  1792  	validator := txvalidatorv14.NewTxValidator(
  1793  		"",
  1794  		semaphore.New(10),
  1795  		&mocktxvalidator.Support{LedgerVal: theLedger, ACVal: preV12Capabilities()},
  1796  		pm,
  1797  		cryptoProvider,
  1798  	)
  1799  
  1800  	ccID := "mycc"
  1801  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1802  
  1803  	theLedger.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, ledger.NotFoundInIndexErr(""))
  1804  
  1805  	cd := &ccp.ChaincodeData{
  1806  		Name:    ccID,
  1807  		Version: ccVersion,
  1808  		Vscc:    "vscc",
  1809  		Policy:  signedByAnyMember([]string{"SampleOrg"}),
  1810  	}
  1811  
  1812  	cdbytes := protoutil.MarshalOrPanic(cd)
  1813  
  1814  	queryExecutor := new(mockQueryExecutor)
  1815  	queryExecutor.On("GetState", "lscc", ccID).Return(cdbytes, nil)
  1816  	theLedger.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)
  1817  
  1818  	b := &common.Block{
  1819  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1820  		Header: &common.BlockHeader{},
  1821  	}
  1822  
  1823  	// Keep default callback
  1824  	err = validator.Validate(b)
  1825  	// Restore default callback
  1826  	assert.NoError(t, err)
  1827  	assertInvalid(b, t, peer.TxValidationCode_ENDORSEMENT_POLICY_FAILURE)
  1828  }
  1829  
  1830  func createMockLedger(t *testing.T, ccID string) *mockLedger {
  1831  	l := new(mockLedger)
  1832  	l.On("GetTransactionByID", mock.Anything).Return(&peer.ProcessedTransaction{}, ledger.NotFoundInIndexErr(""))
  1833  	cd := &ccp.ChaincodeData{
  1834  		Name:    ccID,
  1835  		Version: ccVersion,
  1836  		Vscc:    "vscc",
  1837  		Policy:  signedByAnyMember([]string{"SampleOrg"}),
  1838  	}
  1839  
  1840  	cdbytes := protoutil.MarshalOrPanic(cd)
  1841  	queryExecutor := new(mockQueryExecutor)
  1842  	queryExecutor.On("GetState", "lscc", ccID).Return(cdbytes, nil)
  1843  	l.On("NewQueryExecutor", mock.Anything).Return(queryExecutor, nil)
  1844  	return l
  1845  }
  1846  
  1847  func TestValidationPluginExecutionError(t *testing.T) {
  1848  	plugin := &mocks.Plugin{}
  1849  	plugin.On("Init", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
  1850  
  1851  	l, v, cleanup := setupLedgerAndValidatorExplicit(t, preV12Capabilities(), plugin)
  1852  	defer cleanup()
  1853  
  1854  	ccID := "mycc"
  1855  	putCCInfo(l, ccID, signedByAnyMember([]string{"SampleOrg"}), t)
  1856  
  1857  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1858  	b := &common.Block{
  1859  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1860  		Header: &common.BlockHeader{},
  1861  	}
  1862  
  1863  	plugin.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&validation.ExecutionFailureError{
  1864  		Reason: "I/O error",
  1865  	})
  1866  
  1867  	err := v.Validate(b)
  1868  	executionErr := err.(*commonerrors.VSCCExecutionFailureError)
  1869  	assert.Contains(t, executionErr.Error(), "I/O error")
  1870  }
  1871  
  1872  func TestValidationPluginNotFound(t *testing.T) {
  1873  	ccID := "mycc"
  1874  	tx := getEnv(ccID, nil, createRWset(t, ccID), t)
  1875  	l := createMockLedger(t, ccID)
  1876  
  1877  	b := &common.Block{
  1878  		Data:   &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(tx)}},
  1879  		Header: &common.BlockHeader{},
  1880  	}
  1881  
  1882  	pm := &mocks.Mapper{}
  1883  	pm.On("FactoryByName", vp.Name("vscc")).Return(nil)
  1884  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1885  	assert.NoError(t, err)
  1886  	validator := txvalidatorv14.NewTxValidator(
  1887  		"",
  1888  		semaphore.New(10),
  1889  		&mocktxvalidator.Support{LedgerVal: l, ACVal: preV12Capabilities()},
  1890  		pm,
  1891  		cryptoProvider,
  1892  	)
  1893  	err = validator.Validate(b)
  1894  	executionErr := err.(*commonerrors.VSCCExecutionFailureError)
  1895  	assert.Contains(t, executionErr.Error(), "plugin with name vscc wasn't found")
  1896  }
  1897  
  1898  var signer msp.SigningIdentity
  1899  
  1900  var signerSerialized []byte
  1901  
  1902  func TestMain(m *testing.M) {
  1903  	msptesttools.LoadMSPSetupForTesting()
  1904  
  1905  	var err error
  1906  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1907  	if err != nil {
  1908  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
  1909  		os.Exit(-1)
  1910  		return
  1911  	}
  1912  
  1913  	signer, err = mgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
  1914  	if err != nil {
  1915  		fmt.Println("Could not get signer")
  1916  		os.Exit(-1)
  1917  		return
  1918  	}
  1919  
  1920  	signerSerialized, err = signer.Serialize()
  1921  	if err != nil {
  1922  		fmt.Println("Could not serialize identity")
  1923  		os.Exit(-1)
  1924  		return
  1925  	}
  1926  
  1927  	os.Exit(m.Run())
  1928  }
  1929  
  1930  func ToHex(q uint64) string {
  1931  	return "0x" + strconv.FormatUint(q, 16)
  1932  }
  1933  
  1934  func constructLedgerMgrWithTestDefaults(t *testing.T, testDir string) (*ledgermgmt.LedgerMgr, func()) {
  1935  	testDir, err := ioutil.TempDir("", testDir)
  1936  	if err != nil {
  1937  		t.Fatalf("Failed to create ledger directory: %s", err)
  1938  	}
  1939  	initializer := ledgermgmttest.NewInitializer(testDir)
  1940  	ledgerMgr := ledgermgmt.NewLedgerMgr(initializer)
  1941  	cleanup := func() {
  1942  		ledgerMgr.Close()
  1943  		os.RemoveAll(testDir)
  1944  	}
  1945  	return ledgerMgr, cleanup
  1946  }