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