github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/committer/txvalidator/v14/validator_test.go (about)

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