github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/handlers/validation/builtin/v13/validation_logic_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  package v13
     7  
     8  import (
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/golang/protobuf/proto"
    15  	"github.com/hechain20/hechain/bccsp/sw"
    16  	"github.com/hechain20/hechain/common/capabilities"
    17  	"github.com/hechain20/hechain/common/channelconfig"
    18  	commonerrors "github.com/hechain20/hechain/common/errors"
    19  	"github.com/hechain20/hechain/common/policydsl"
    20  	"github.com/hechain20/hechain/core/committer/txvalidator/v14"
    21  	"github.com/hechain20/hechain/core/common/ccprovider"
    22  	"github.com/hechain20/hechain/core/common/privdata"
    23  	validation "github.com/hechain20/hechain/core/handlers/validation/api/capabilities"
    24  	vs "github.com/hechain20/hechain/core/handlers/validation/api/state"
    25  	"github.com/hechain20/hechain/core/handlers/validation/builtin/v13/mocks"
    26  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/rwsetutil"
    27  	"github.com/hechain20/hechain/core/scc/lscc"
    28  	"github.com/hechain20/hechain/msp"
    29  	mspmgmt "github.com/hechain20/hechain/msp/mgmt"
    30  	msptesttools "github.com/hechain20/hechain/msp/mgmt/testtools"
    31  	"github.com/hechain20/hechain/protoutil"
    32  	"github.com/hyperledger/fabric-protos-go/common"
    33  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    34  	"github.com/hyperledger/fabric-protos-go/peer"
    35  	"github.com/pkg/errors"
    36  	"github.com/stretchr/testify/mock"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  //go:generate counterfeiter -o mocks/state.go -fake-name State . vsState
    41  
    42  type vsState interface {
    43  	vs.State
    44  }
    45  
    46  func createTx(endorsedByDuplicatedIdentity bool) (*common.Envelope, error) {
    47  	ccid := &peer.ChaincodeID{Name: "foo", Version: "v1"}
    48  	cis := &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeId: ccid}}
    49  
    50  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, []byte("res"), nil, ccid, id)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	var env *common.Envelope
    61  	if endorsedByDuplicatedIdentity {
    62  		env, err = protoutil.CreateSignedTx(prop, id, presp, presp)
    63  	} else {
    64  		env, err = protoutil.CreateSignedTx(prop, id, presp)
    65  	}
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  	return env, err
    70  }
    71  
    72  func createCCDataRWsetWithCollection(nameK, nameV, version string, policy []byte, collectionConfigPackage []byte) ([]byte, error) {
    73  	cd := &ccprovider.ChaincodeData{
    74  		Name:                nameV,
    75  		Version:             version,
    76  		InstantiationPolicy: policy,
    77  	}
    78  
    79  	cdbytes := protoutil.MarshalOrPanic(cd)
    80  
    81  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
    82  	rwsetBuilder.AddToWriteSet("lscc", nameK, cdbytes)
    83  	rwsetBuilder.AddToWriteSet("lscc", privdata.BuildCollectionKVSKey(nameK), collectionConfigPackage)
    84  	sr, err := rwsetBuilder.GetTxSimulationResults()
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	return sr.GetPubSimulationBytes()
    89  }
    90  
    91  func createCCDataRWset(nameK, nameV, version string, policy []byte) ([]byte, error) {
    92  	cd := &ccprovider.ChaincodeData{
    93  		Name:                nameV,
    94  		Version:             version,
    95  		InstantiationPolicy: policy,
    96  	}
    97  
    98  	cdbytes := protoutil.MarshalOrPanic(cd)
    99  
   100  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   101  	rwsetBuilder.AddToWriteSet("lscc", nameK, cdbytes)
   102  	sr, err := rwsetBuilder.GetTxSimulationResults()
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  	return sr.GetPubSimulationBytes()
   107  }
   108  
   109  func createLSCCTxWithCollection(ccname, ccver, f string, res []byte, policy []byte, ccpBytes []byte) (*common.Envelope, error) {
   110  	return createLSCCTxPutCdsWithCollection(ccname, ccver, f, res, nil, true, policy, ccpBytes)
   111  }
   112  
   113  func createLSCCTx(ccname, ccver, f string, res []byte) (*common.Envelope, error) {
   114  	return createLSCCTxPutCds(ccname, ccver, f, res, nil, true)
   115  }
   116  
   117  func createLSCCTxPutCdsWithCollection(ccname, ccver, f string, res, cdsbytes []byte, putcds bool, policy []byte, ccpBytes []byte) (*common.Envelope, error) {
   118  	cds := &peer.ChaincodeDeploymentSpec{
   119  		ChaincodeSpec: &peer.ChaincodeSpec{
   120  			ChaincodeId: &peer.ChaincodeID{
   121  				Name:    ccname,
   122  				Version: ccver,
   123  			},
   124  			Type: peer.ChaincodeSpec_GOLANG,
   125  		},
   126  	}
   127  
   128  	cdsBytes, err := proto.Marshal(cds)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	var cis *peer.ChaincodeInvocationSpec
   134  	if putcds {
   135  		if cdsbytes != nil {
   136  			cdsBytes = cdsbytes
   137  		}
   138  		cis = &peer.ChaincodeInvocationSpec{
   139  			ChaincodeSpec: &peer.ChaincodeSpec{
   140  				ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
   141  				Input: &peer.ChaincodeInput{
   142  					Args: [][]byte{[]byte(f), []byte("barf"), cdsBytes, []byte("escc"), []byte("vscc"), policy, ccpBytes},
   143  				},
   144  				Type: peer.ChaincodeSpec_GOLANG,
   145  			},
   146  		}
   147  	} else {
   148  		cis = &peer.ChaincodeInvocationSpec{
   149  			ChaincodeSpec: &peer.ChaincodeSpec{
   150  				ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
   151  				Input: &peer.ChaincodeInput{
   152  					Args: [][]byte{[]byte(f), []byte("barf")},
   153  				},
   154  				Type: peer.ChaincodeSpec_GOLANG,
   155  			},
   156  		}
   157  	}
   158  
   159  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	ccid := &peer.ChaincodeID{Name: ccname, Version: ccver}
   165  
   166  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	return protoutil.CreateSignedTx(prop, id, presp)
   172  }
   173  
   174  func createLSCCTxPutCds(ccname, ccver, f string, res, cdsbytes []byte, putcds bool) (*common.Envelope, error) {
   175  	cds := &peer.ChaincodeDeploymentSpec{
   176  		ChaincodeSpec: &peer.ChaincodeSpec{
   177  			ChaincodeId: &peer.ChaincodeID{
   178  				Name:    ccname,
   179  				Version: ccver,
   180  			},
   181  			Type: peer.ChaincodeSpec_GOLANG,
   182  		},
   183  	}
   184  
   185  	cdsBytes, err := proto.Marshal(cds)
   186  	if err != nil {
   187  		return nil, err
   188  	}
   189  
   190  	var cis *peer.ChaincodeInvocationSpec
   191  	if putcds {
   192  		if cdsbytes != nil {
   193  			cdsBytes = cdsbytes
   194  		}
   195  		cis = &peer.ChaincodeInvocationSpec{
   196  			ChaincodeSpec: &peer.ChaincodeSpec{
   197  				ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
   198  				Input: &peer.ChaincodeInput{
   199  					Args: [][]byte{[]byte(f), []byte("barf"), cdsBytes},
   200  				},
   201  				Type: peer.ChaincodeSpec_GOLANG,
   202  			},
   203  		}
   204  	} else {
   205  		cis = &peer.ChaincodeInvocationSpec{
   206  			ChaincodeSpec: &peer.ChaincodeSpec{
   207  				ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
   208  				Input: &peer.ChaincodeInput{
   209  					Args: [][]byte{[]byte(f), []byte(ccname)},
   210  				},
   211  				Type: peer.ChaincodeSpec_GOLANG,
   212  			},
   213  		}
   214  	}
   215  
   216  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid)
   217  	if err != nil {
   218  		return nil, err
   219  	}
   220  
   221  	ccid := &peer.ChaincodeID{Name: ccname, Version: ccver}
   222  
   223  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id)
   224  	if err != nil {
   225  		return nil, err
   226  	}
   227  
   228  	return protoutil.CreateSignedTx(prop, id, presp)
   229  }
   230  
   231  func getSignedByMSPMemberPolicy(mspID string) ([]byte, error) {
   232  	p := policydsl.SignedByMspMember(mspID)
   233  
   234  	b, err := protoutil.Marshal(p)
   235  	if err != nil {
   236  		return nil, fmt.Errorf("Could not marshal policy, err %s", err)
   237  	}
   238  
   239  	return b, err
   240  }
   241  
   242  func getSignedByMSPAdminPolicy(mspID string) ([]byte, error) {
   243  	p := policydsl.SignedByMspAdmin(mspID)
   244  
   245  	b, err := protoutil.Marshal(p)
   246  	if err != nil {
   247  		return nil, fmt.Errorf("Could not marshal policy, err %s", err)
   248  	}
   249  
   250  	return b, err
   251  }
   252  
   253  func newValidationInstance(state map[string]map[string][]byte) *Validator {
   254  	c := &mocks.Capabilities{}
   255  	c.On("PrivateChannelData").Return(false)
   256  	c.On("V1_1Validation").Return(false)
   257  	c.On("V1_2Validation").Return(false)
   258  	vs := &mocks.State{}
   259  	vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) {
   260  		if ns, ok := state[namespace]; ok {
   261  			return [][]byte{ns[keys[0]]}, nil
   262  		} else {
   263  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
   264  		}
   265  	}
   266  	sf := &mocks.StateFetcher{}
   267  	sf.On("FetchState").Return(vs, nil)
   268  	return newCustomValidationInstance(sf, c)
   269  }
   270  
   271  func newCustomValidationInstance(sf StateFetcher, c validation.Capabilities) *Validator {
   272  	sbvm := &mocks.StateBasedValidator{}
   273  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   274  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   275  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   276  
   277  	is := &mocks.IdentityDeserializer{}
   278  	pe := &txvalidator.PolicyEvaluator{
   279  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   280  	}
   281  	v := New(c, sf, is, pe)
   282  
   283  	v.stateBasedValidator = sbvm
   284  	return v
   285  }
   286  
   287  func TestStateBasedValidationFailure(t *testing.T) {
   288  	sbvm := &mocks.StateBasedValidator{}
   289  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   290  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   291  
   292  	c := &mocks.Capabilities{}
   293  	c.On("V1_3Validation").Return(true)
   294  	vs := &mocks.State{}
   295  	sf := &mocks.StateFetcher{}
   296  	sf.On("FetchState").Return(vs, nil)
   297  	is := &mocks.IdentityDeserializer{}
   298  	pe := &txvalidator.PolicyEvaluator{
   299  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   300  	}
   301  	v := New(c, sf, is, pe)
   302  	v.stateBasedValidator = sbvm
   303  
   304  	tx, err := createTx(false)
   305  	if err != nil {
   306  		t.Fatalf("createTx returned err %s", err)
   307  	}
   308  
   309  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   310  	if err != nil {
   311  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   312  	}
   313  
   314  	policy, err := getSignedByMSPMemberPolicy(mspid)
   315  	if err != nil {
   316  		t.Fatalf("failed getting policy, err %s", err)
   317  	}
   318  
   319  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   320  
   321  	// bad path: policy validation error
   322  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCEndorsementPolicyError{Err: fmt.Errorf("some sbe validation err")}).Once()
   323  	err = v.Validate(b, "foo", 0, 0, policy)
   324  	require.Error(t, err)
   325  	require.IsType(t, &commonerrors.VSCCEndorsementPolicyError{}, err)
   326  
   327  	// bad path: execution error
   328  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCExecutionFailureError{Err: fmt.Errorf("some sbe validation err")}).Once()
   329  	err = v.Validate(b, "foo", 0, 0, policy)
   330  	require.Error(t, err)
   331  	require.IsType(t, &commonerrors.VSCCExecutionFailureError{}, err)
   332  
   333  	// good path: signed by the right MSP
   334  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
   335  	err = v.Validate(b, "foo", 0, 0, policy)
   336  	require.NoError(t, err)
   337  }
   338  
   339  func TestInvoke(t *testing.T) {
   340  	v := newValidationInstance(make(map[string]map[string][]byte))
   341  
   342  	// broken Envelope
   343  	var err error
   344  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{[]byte("a")}}, Header: &common.BlockHeader{}}
   345  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   346  	require.Error(t, err)
   347  
   348  	// (still) broken Envelope
   349  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{Payload: []byte("barf")})}}, Header: &common.BlockHeader{}}
   350  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   351  	require.Error(t, err)
   352  
   353  	// (still) broken Envelope
   354  	e := protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: []byte("barf")}})})
   355  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   356  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   357  	require.Error(t, err)
   358  
   359  	tx, err := createTx(false)
   360  	if err != nil {
   361  		t.Fatalf("createTx returned err %s", err)
   362  	}
   363  
   364  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   365  	if err != nil {
   366  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   367  	}
   368  
   369  	policy, err := getSignedByMSPMemberPolicy(mspid)
   370  	if err != nil {
   371  		t.Fatalf("failed getting policy, err %s", err)
   372  	}
   373  
   374  	// broken type
   375  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   376  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   377  	err = v.Validate(b, "foo", 0, 0, policy)
   378  	require.Error(t, err)
   379  
   380  	// broken tx payload
   381  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   382  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   383  	err = v.Validate(b, "foo", 0, 0, policy)
   384  	require.Error(t, err)
   385  
   386  	// good path: signed by the right MSP
   387  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   388  	err = v.Validate(b, "foo", 0, 0, policy)
   389  	require.NoError(t, err)
   390  }
   391  
   392  func TestRWSetTooBig(t *testing.T) {
   393  	state := make(map[string]map[string][]byte)
   394  	state["lscc"] = make(map[string][]byte)
   395  	v := newValidationInstance(state)
   396  
   397  	ccname := "mycc"
   398  	ccver := "1"
   399  
   400  	cd := &ccprovider.ChaincodeData{
   401  		Name:                ccname,
   402  		Version:             ccver,
   403  		InstantiationPolicy: nil,
   404  	}
   405  
   406  	cdbytes := protoutil.MarshalOrPanic(cd)
   407  
   408  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   409  	rwsetBuilder.AddToWriteSet("lscc", ccname, cdbytes)
   410  	rwsetBuilder.AddToWriteSet("lscc", "spurious", []byte("spurious"))
   411  
   412  	sr, err := rwsetBuilder.GetTxSimulationResults()
   413  	require.NoError(t, err)
   414  	srBytes, err := sr.GetPubSimulationBytes()
   415  	require.NoError(t, err)
   416  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, srBytes)
   417  	if err != nil {
   418  		t.Fatalf("createTx returned err %s", err)
   419  	}
   420  
   421  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   422  	if err != nil {
   423  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   424  	}
   425  
   426  	// good path: signed by the right MSP
   427  	policy, err := getSignedByMSPMemberPolicy(mspid)
   428  	if err != nil {
   429  		t.Fatalf("failed getting policy, err %s", err)
   430  	}
   431  
   432  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   433  	err = v.Validate(b, "lscc", 0, 0, policy)
   434  	require.EqualError(t, err, "LSCC can only issue a single putState upon deploy")
   435  }
   436  
   437  func TestValidateDeployFail(t *testing.T) {
   438  	state := make(map[string]map[string][]byte)
   439  	state["lscc"] = make(map[string][]byte)
   440  	v := newValidationInstance(state)
   441  
   442  	ccname := "mycc"
   443  	ccver := "1"
   444  
   445  	/*********************/
   446  	/* test no write set */
   447  	/*********************/
   448  
   449  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, nil)
   450  	if err != nil {
   451  		t.Fatalf("createTx returned err %s", err)
   452  	}
   453  
   454  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   455  	if err != nil {
   456  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   457  	}
   458  
   459  	// good path: signed by the right MSP
   460  	policy, err := getSignedByMSPMemberPolicy(mspid)
   461  	if err != nil {
   462  		t.Fatalf("failed getting policy, err %s", err)
   463  	}
   464  
   465  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   466  	err = v.Validate(b, "lscc", 0, 0, policy)
   467  	require.EqualError(t, err, "No read write set for lscc was found")
   468  
   469  	/************************/
   470  	/* test bogus write set */
   471  	/************************/
   472  
   473  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   474  	rwsetBuilder.AddToWriteSet("lscc", ccname, []byte("barf"))
   475  	sr, err := rwsetBuilder.GetTxSimulationResults()
   476  	require.NoError(t, err)
   477  	resBogusBytes, err := sr.GetPubSimulationBytes()
   478  	require.NoError(t, err)
   479  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, resBogusBytes)
   480  	if err != nil {
   481  		t.Fatalf("createTx returned err %s", err)
   482  	}
   483  
   484  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   485  	if err != nil {
   486  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   487  	}
   488  
   489  	// good path: signed by the right MSP
   490  	policy, err = getSignedByMSPMemberPolicy(mspid)
   491  	if err != nil {
   492  		t.Fatalf("failed getting policy, err %s", err)
   493  	}
   494  
   495  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   496  	err = v.Validate(b, "lscc", 0, 0, policy)
   497  	require.EqualError(t, err, "unmarhsalling of ChaincodeData failed, error unexpected EOF")
   498  
   499  	/**********************/
   500  	/* test bad LSCC args */
   501  	/**********************/
   502  
   503  	res, err := createCCDataRWset(ccname, ccname, ccver, nil)
   504  	require.NoError(t, err)
   505  
   506  	tx, err = createLSCCTxPutCds(ccname, ccver, lscc.DEPLOY, res, nil, false)
   507  	if err != nil {
   508  		t.Fatalf("createTx returned err %s", err)
   509  	}
   510  
   511  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   512  	if err != nil {
   513  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   514  	}
   515  
   516  	// good path: signed by the right MSP
   517  	policy, err = getSignedByMSPMemberPolicy(mspid)
   518  	if err != nil {
   519  		t.Fatalf("failed getting policy, err %s", err)
   520  	}
   521  
   522  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   523  	err = v.Validate(b, "lscc", 0, 0, policy)
   524  	require.EqualError(t, err, "Wrong number of arguments for invocation lscc(deploy): expected at least 2, received 1")
   525  
   526  	/**********************/
   527  	/* test bad LSCC args */
   528  	/**********************/
   529  
   530  	res, err = createCCDataRWset(ccname, ccname, ccver, nil)
   531  	require.NoError(t, err)
   532  
   533  	tx, err = createLSCCTxPutCds(ccname, ccver, lscc.DEPLOY, res, []byte("barf"), true)
   534  	if err != nil {
   535  		t.Fatalf("createTx returned err %s", err)
   536  	}
   537  
   538  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   539  	if err != nil {
   540  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   541  	}
   542  
   543  	// good path: signed by the right MSP
   544  	policy, err = getSignedByMSPMemberPolicy(mspid)
   545  	if err != nil {
   546  		t.Fatalf("failed getting policy, err %s", err)
   547  	}
   548  
   549  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   550  	err = v.Validate(b, "lscc", 0, 0, policy)
   551  	require.EqualError(t, err, "GetChaincodeDeploymentSpec error error unmarshalling ChaincodeDeploymentSpec: unexpected EOF")
   552  
   553  	/***********************/
   554  	/* test bad cc version */
   555  	/***********************/
   556  
   557  	res, err = createCCDataRWset(ccname, ccname, ccver+".1", nil)
   558  	require.NoError(t, err)
   559  
   560  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
   561  	if err != nil {
   562  		t.Fatalf("createTx returned err %s", err)
   563  	}
   564  
   565  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   566  	if err != nil {
   567  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   568  	}
   569  
   570  	// good path: signed by the right MSP
   571  	policy, err = getSignedByMSPMemberPolicy(mspid)
   572  	if err != nil {
   573  		t.Fatalf("failed getting policy, err %s", err)
   574  	}
   575  
   576  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   577  	err = v.Validate(b, "lscc", 0, 0, policy)
   578  	require.EqualError(t, err, fmt.Sprintf("expected cc version %s, found %s", ccver, ccver+".1"))
   579  
   580  	/*************/
   581  	/* bad rwset */
   582  	/*************/
   583  
   584  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, []byte("barf"))
   585  	if err != nil {
   586  		t.Fatalf("createTx returned err %s", err)
   587  	}
   588  
   589  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   590  	if err != nil {
   591  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   592  	}
   593  
   594  	// good path: signed by the right MSP
   595  	policy, err = getSignedByMSPMemberPolicy(mspid)
   596  	if err != nil {
   597  		t.Fatalf("failed getting policy, err %s", err)
   598  	}
   599  
   600  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   601  	err = v.Validate(b, "lscc", 0, 0, policy)
   602  	require.EqualError(t, err, "txRWSet.FromProtoBytes error unexpected EOF")
   603  
   604  	/********************/
   605  	/* test bad cc name */
   606  	/********************/
   607  
   608  	res, err = createCCDataRWset(ccname+".badbad", ccname, ccver, nil)
   609  	require.NoError(t, err)
   610  
   611  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
   612  	if err != nil {
   613  		t.Fatalf("createTx returned err %s", err)
   614  	}
   615  
   616  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   617  	if err != nil {
   618  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   619  	}
   620  
   621  	policy, err = getSignedByMSPMemberPolicy(mspid)
   622  	if err != nil {
   623  		t.Fatalf("failed getting policy, err %s", err)
   624  	}
   625  
   626  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   627  	err = v.Validate(b, "lscc", 0, 0, policy)
   628  	require.EqualError(t, err, fmt.Sprintf("expected key %s, found %s", ccname, ccname+".badbad"))
   629  
   630  	/**********************/
   631  	/* test bad cc name 2 */
   632  	/**********************/
   633  
   634  	res, err = createCCDataRWset(ccname, ccname+".badbad", ccver, nil)
   635  	require.NoError(t, err)
   636  
   637  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
   638  	if err != nil {
   639  		t.Fatalf("createTx returned err %s", err)
   640  	}
   641  
   642  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   643  	if err != nil {
   644  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   645  	}
   646  
   647  	policy, err = getSignedByMSPMemberPolicy(mspid)
   648  	if err != nil {
   649  		t.Fatalf("failed getting policy, err %s", err)
   650  	}
   651  
   652  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   653  	err = v.Validate(b, "lscc", 0, 0, policy)
   654  	require.EqualError(t, err, fmt.Sprintf("expected cc name %s, found %s", ccname, ccname+".badbad"))
   655  
   656  	/************************/
   657  	/* test suprious writes */
   658  	/************************/
   659  
   660  	cd := &ccprovider.ChaincodeData{
   661  		Name:                ccname,
   662  		Version:             ccver,
   663  		InstantiationPolicy: nil,
   664  	}
   665  
   666  	cdbytes := protoutil.MarshalOrPanic(cd)
   667  	rwsetBuilder = rwsetutil.NewRWSetBuilder()
   668  	rwsetBuilder.AddToWriteSet("lscc", ccname, cdbytes)
   669  	rwsetBuilder.AddToWriteSet("bogusbogus", "key", []byte("val"))
   670  	sr, err = rwsetBuilder.GetTxSimulationResults()
   671  	require.NoError(t, err)
   672  	srBytes, err := sr.GetPubSimulationBytes()
   673  	require.NoError(t, err)
   674  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, srBytes)
   675  	if err != nil {
   676  		t.Fatalf("createTx returned err %s", err)
   677  	}
   678  
   679  	envBytes, err = protoutil.GetBytesEnvelope(tx)
   680  	if err != nil {
   681  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   682  	}
   683  
   684  	policy, err = getSignedByMSPMemberPolicy(mspid)
   685  	if err != nil {
   686  		t.Fatalf("failed getting policy, err %s", err)
   687  	}
   688  
   689  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   690  	err = v.Validate(b, "lscc", 0, 0, policy)
   691  	require.EqualError(t, err, "LSCC invocation is attempting to write to namespace bogusbogus")
   692  }
   693  
   694  func TestAlreadyDeployed(t *testing.T) {
   695  	state := make(map[string]map[string][]byte)
   696  	state["lscc"] = make(map[string][]byte)
   697  
   698  	v := newValidationInstance(state)
   699  
   700  	ccname := "mycc"
   701  	ccver := "alreadydeployed"
   702  
   703  	// create state for ccname to simulate deployment
   704  	state["lscc"][ccname] = []byte{}
   705  
   706  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
   707  	require.NoError(t, err)
   708  
   709  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, simresres)
   710  	if err != nil {
   711  		t.Fatalf("createTx returned err %s", err)
   712  	}
   713  
   714  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   715  	if err != nil {
   716  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   717  	}
   718  
   719  	// good path: signed by the right MSP
   720  	policy, err := getSignedByMSPMemberPolicy(mspid)
   721  	if err != nil {
   722  		t.Fatalf("failed getting policy, err %s", err)
   723  	}
   724  
   725  	bl := &common.Block{
   726  		Data: &common.BlockData{
   727  			Data: [][]byte{envBytes},
   728  		},
   729  		Header: &common.BlockHeader{},
   730  	}
   731  	err = v.Validate(bl, "lscc", 0, 0, policy)
   732  	require.EqualError(t, err, "Chaincode mycc is already instantiated")
   733  }
   734  
   735  func TestValidateDeployNoLedger(t *testing.T) {
   736  	sf := &mocks.StateFetcher{}
   737  	sf.On("FetchState").Return(nil, errors.New("failed obtaining query executor"))
   738  	capabilities := &mocks.Capabilities{}
   739  	capabilities.On("PrivateChannelData").Return(false)
   740  	capabilities.On("V1_1Validation").Return(false)
   741  	capabilities.On("V1_2Validation").Return(false)
   742  	v := newCustomValidationInstance(sf, capabilities)
   743  
   744  	ccname := "mycc"
   745  	ccver := "1"
   746  
   747  	defaultPolicy, err := getSignedByMSPAdminPolicy(mspid)
   748  	require.NoError(t, err)
   749  	res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy)
   750  	require.NoError(t, err)
   751  
   752  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
   753  	if err != nil {
   754  		t.Fatalf("createTx returned err %s", err)
   755  	}
   756  
   757  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   758  	if err != nil {
   759  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   760  	}
   761  
   762  	// good path: signed by the right MSP
   763  	policy, err := getSignedByMSPMemberPolicy(mspid)
   764  	if err != nil {
   765  		t.Fatalf("failed getting policy, err %s", err)
   766  	}
   767  
   768  	b := &common.Block{
   769  		Data: &common.BlockData{
   770  			Data: [][]byte{envBytes},
   771  		},
   772  		Header: &common.BlockHeader{},
   773  	}
   774  	err = v.Validate(b, "lscc", 0, 0, policy)
   775  	require.EqualError(t, err, "could not retrieve QueryExecutor for channel testchannelid, error failed obtaining query executor")
   776  }
   777  
   778  func TestValidateDeployNOKNilChaincodeSpec(t *testing.T) {
   779  	state := make(map[string]map[string][]byte)
   780  	state["lscc"] = make(map[string][]byte)
   781  
   782  	v := newValidationInstance(state)
   783  
   784  	ccname := "mycc"
   785  	ccver := "1"
   786  
   787  	defaultPolicy, err := getSignedByMSPAdminPolicy(mspid)
   788  	require.NoError(t, err)
   789  	res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy)
   790  	require.NoError(t, err)
   791  
   792  	// Create a ChaincodeDeploymentSpec with nil ChaincodeSpec for negative test
   793  	cdsBytes, err := proto.Marshal(&peer.ChaincodeDeploymentSpec{})
   794  	require.NoError(t, err)
   795  
   796  	// ChaincodeDeploymentSpec/ChaincodeSpec are derived from cdsBytes (i.e., cis.ChaincodeSpec.Input.Args[2])
   797  	cis := &peer.ChaincodeInvocationSpec{
   798  		ChaincodeSpec: &peer.ChaincodeSpec{
   799  			ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
   800  			Input: &peer.ChaincodeInput{
   801  				Args: [][]byte{[]byte(lscc.DEPLOY), []byte("barf"), cdsBytes},
   802  			},
   803  			Type: peer.ChaincodeSpec_GOLANG,
   804  		},
   805  	}
   806  
   807  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid)
   808  	require.NoError(t, err)
   809  
   810  	ccid := &peer.ChaincodeID{Name: ccname, Version: ccver}
   811  
   812  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id)
   813  	require.NoError(t, err)
   814  
   815  	env, err := protoutil.CreateSignedTx(prop, id, presp)
   816  	require.NoError(t, err)
   817  
   818  	// good path: signed by the right MSP
   819  	policy, err := getSignedByMSPMemberPolicy(mspid)
   820  	if err != nil {
   821  		t.Fatalf("failed getting policy, err %s", err)
   822  	}
   823  
   824  	b := &common.Block{
   825  		Data: &common.BlockData{
   826  			Data: [][]byte{protoutil.MarshalOrPanic(env)},
   827  		},
   828  		Header: &common.BlockHeader{},
   829  	}
   830  	err = v.Validate(b, "lscc", 0, 0, policy)
   831  	require.EqualError(t, err, "VSCC error: invocation of lscc(deploy) does not have appropriate arguments")
   832  }
   833  
   834  func TestValidateDeployOK(t *testing.T) {
   835  	state := make(map[string]map[string][]byte)
   836  	state["lscc"] = make(map[string][]byte)
   837  
   838  	v := newValidationInstance(state)
   839  
   840  	ccname := "mycc"
   841  	ccver := "1"
   842  
   843  	defaultPolicy, err := getSignedByMSPAdminPolicy(mspid)
   844  	require.NoError(t, err)
   845  	res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy)
   846  	require.NoError(t, err)
   847  
   848  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
   849  	if err != nil {
   850  		t.Fatalf("createTx returned err %s", err)
   851  	}
   852  
   853  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   854  	if err != nil {
   855  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   856  	}
   857  
   858  	// good path: signed by the right MSP
   859  	policy, err := getSignedByMSPMemberPolicy(mspid)
   860  	if err != nil {
   861  		t.Fatalf("failed getting policy, err %s", err)
   862  	}
   863  
   864  	b := &common.Block{
   865  		Data: &common.BlockData{
   866  			Data: [][]byte{envBytes},
   867  		},
   868  		Header: &common.BlockHeader{},
   869  	}
   870  	err = v.Validate(b, "lscc", 0, 0, policy)
   871  	require.NoError(t, err)
   872  }
   873  
   874  func TestValidateDeployNOK(t *testing.T) {
   875  	testCases := []struct {
   876  		description string
   877  		ccName      string
   878  		ccVersion   string
   879  		errMsg      string
   880  	}{
   881  		{description: "empty cc name", ccName: "", ccVersion: "1", errMsg: "invalid chaincode name ''"},
   882  		{description: "bad first character in cc name", ccName: "_badname", ccVersion: "1.2", errMsg: "invalid chaincode name '_badname'"},
   883  		{description: "bad character in cc name", ccName: "bad.name", ccVersion: "1-5", errMsg: "invalid chaincode name 'bad.name'"},
   884  		{description: "empty cc version", ccName: "1good_name", ccVersion: "", errMsg: "invalid chaincode version ''"},
   885  		{description: "bad cc version", ccName: "good-name", ccVersion: "$badversion", errMsg: "invalid chaincode version '$badversion'"},
   886  		{description: "use system cc name", ccName: "qscc", ccVersion: "2.1", errMsg: "chaincode name 'qscc' is reserved for system chaincodes"},
   887  	}
   888  
   889  	// create validator and policy
   890  	state := make(map[string]map[string][]byte)
   891  	state["lscc"] = make(map[string][]byte)
   892  
   893  	v := newValidationInstance(state)
   894  
   895  	policy, err := getSignedByMSPAdminPolicy(mspid)
   896  	require.NoError(t, err)
   897  
   898  	for _, tc := range testCases {
   899  		t.Run(tc.description, func(t *testing.T) {
   900  			testChaincodeDeployNOK(t, tc.ccName, tc.ccVersion, tc.errMsg, v, policy)
   901  		})
   902  	}
   903  }
   904  
   905  func testChaincodeDeployNOK(t *testing.T, ccName, ccVersion, errMsg string, v *Validator, policy []byte) {
   906  	res, err := createCCDataRWset(ccName, ccName, ccVersion, policy)
   907  	require.NoError(t, err)
   908  
   909  	tx, err := createLSCCTx(ccName, ccVersion, lscc.DEPLOY, res)
   910  	if err != nil {
   911  		t.Fatalf("createTx returned err %s", err)
   912  	}
   913  
   914  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   915  	if err != nil {
   916  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   917  	}
   918  
   919  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   920  	err = v.Validate(b, "lscc", 0, 0, policy)
   921  	require.EqualError(t, err, errMsg)
   922  }
   923  
   924  func TestValidateDeployWithCollection(t *testing.T) {
   925  	state := make(map[string]map[string][]byte)
   926  	state["lscc"] = make(map[string][]byte)
   927  
   928  	vs := &mocks.State{}
   929  	vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) {
   930  		if ns, ok := state[namespace]; ok {
   931  			return [][]byte{ns[keys[0]]}, nil
   932  		} else {
   933  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
   934  		}
   935  	}
   936  	sf := &mocks.StateFetcher{}
   937  	sf.On("FetchState").Return(vs, nil)
   938  	capabilities := &mocks.Capabilities{}
   939  	capabilities.On("PrivateChannelData").Return(true)
   940  	capabilities.On("V1_1Validation").Return(true)
   941  	capabilities.On("V1_2Validation").Return(false)
   942  	v := newCustomValidationInstance(sf, capabilities)
   943  
   944  	ccname := "mycc"
   945  	ccver := "1"
   946  
   947  	collName1 := "mycollection1"
   948  	collName2 := "mycollection2"
   949  	signers := [][]byte{[]byte("signer0"), []byte("signer1")}
   950  	policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
   951  	var requiredPeerCount, maximumPeerCount int32
   952  	var blockToLive uint64
   953  	requiredPeerCount = 1
   954  	maximumPeerCount = 2
   955  	blockToLive = 1000
   956  	coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
   957  	coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
   958  
   959  	// Test 1: Deploy chaincode with a valid collection configs --> success
   960  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}}
   961  	ccpBytes, err := proto.Marshal(ccp)
   962  	require.NoError(t, err)
   963  	require.NotNil(t, ccpBytes)
   964  
   965  	defaultPolicy, err := getSignedByMSPAdminPolicy(mspid)
   966  	require.NoError(t, err)
   967  	res, err := createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
   968  	require.NoError(t, err)
   969  
   970  	tx, err := createLSCCTxWithCollection(ccname, ccver, lscc.DEPLOY, res, defaultPolicy, ccpBytes)
   971  	if err != nil {
   972  		t.Fatalf("createTx returned err %s", err)
   973  	}
   974  
   975  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   976  	if err != nil {
   977  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   978  	}
   979  
   980  	// good path: signed by the right MSP
   981  	policy, err := getSignedByMSPMemberPolicy(mspid)
   982  	if err != nil {
   983  		t.Fatalf("failed getting policy, err %s", err)
   984  	}
   985  
   986  	b := &common.Block{
   987  		Data: &common.BlockData{
   988  			Data: [][]byte{envBytes},
   989  		},
   990  		Header: &common.BlockHeader{},
   991  	}
   992  	err = v.Validate(b, "lscc", 0, 0, policy)
   993  	require.NoError(t, err)
   994  
   995  	// Test 2: Deploy the chaincode with duplicate collection configs --> no error as the
   996  	// peer is not in V1_2Validation mode
   997  	ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2, coll1}}
   998  	ccpBytes, err = proto.Marshal(ccp)
   999  	require.NoError(t, err)
  1000  	require.NotNil(t, ccpBytes)
  1001  
  1002  	res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
  1003  	require.NoError(t, err)
  1004  
  1005  	tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.DEPLOY, res, defaultPolicy, ccpBytes)
  1006  	if err != nil {
  1007  		t.Fatalf("createTx returned err %s", err)
  1008  	}
  1009  
  1010  	envBytes, err = protoutil.GetBytesEnvelope(tx)
  1011  	if err != nil {
  1012  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1013  	}
  1014  
  1015  	b = &common.Block{
  1016  		Data: &common.BlockData{
  1017  			Data: [][]byte{envBytes},
  1018  		},
  1019  		Header: &common.BlockHeader{},
  1020  	}
  1021  	err = v.Validate(b, "lscc", 0, 0, policy)
  1022  	require.NoError(t, err)
  1023  
  1024  	// Test 3: Once the V1_2Validation is enabled, validation should fail due to duplicate collection configs
  1025  	capabilities = &mocks.Capabilities{}
  1026  	capabilities.On("PrivateChannelData").Return(true)
  1027  	capabilities.On("V1_2Validation").Return(true)
  1028  	v = newCustomValidationInstance(sf, capabilities)
  1029  
  1030  	b = &common.Block{
  1031  		Data: &common.BlockData{
  1032  			Data: [][]byte{envBytes},
  1033  		},
  1034  		Header: &common.BlockHeader{},
  1035  	}
  1036  	err = v.Validate(b, "lscc", 0, 0, policy)
  1037  	require.EqualError(t, err, "collection-name: mycollection1 -- found duplicate collection configuration")
  1038  }
  1039  
  1040  func TestValidateDeployWithPolicies(t *testing.T) {
  1041  	state := make(map[string]map[string][]byte)
  1042  	state["lscc"] = make(map[string][]byte)
  1043  
  1044  	v := newValidationInstance(state)
  1045  
  1046  	ccname := "mycc"
  1047  	ccver := "1"
  1048  
  1049  	/*********************************************/
  1050  	/* test 1: success with an accept-all policy */
  1051  	/*********************************************/
  1052  
  1053  	res, err := createCCDataRWset(ccname, ccname, ccver, policydsl.MarshaledAcceptAllPolicy)
  1054  	require.NoError(t, err)
  1055  
  1056  	tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
  1057  	if err != nil {
  1058  		t.Fatalf("createTx returned err %s", err)
  1059  	}
  1060  
  1061  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1062  	if err != nil {
  1063  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1064  	}
  1065  
  1066  	// good path: signed by the right MSP
  1067  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1068  	if err != nil {
  1069  		t.Fatalf("failed getting policy, err %s", err)
  1070  	}
  1071  
  1072  	b := &common.Block{
  1073  		Data: &common.BlockData{
  1074  			Data: [][]byte{envBytes},
  1075  		},
  1076  		Header: &common.BlockHeader{},
  1077  	}
  1078  	err = v.Validate(b, "lscc", 0, 0, policy)
  1079  	require.NoError(t, err)
  1080  
  1081  	/********************************************/
  1082  	/* test 2: failure with a reject-all policy */
  1083  	/********************************************/
  1084  
  1085  	res, err = createCCDataRWset(ccname, ccname, ccver, policydsl.MarshaledRejectAllPolicy)
  1086  	require.NoError(t, err)
  1087  
  1088  	tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res)
  1089  	if err != nil {
  1090  		t.Fatalf("createTx returned err %s", err)
  1091  	}
  1092  
  1093  	envBytes, err = protoutil.GetBytesEnvelope(tx)
  1094  	if err != nil {
  1095  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1096  	}
  1097  
  1098  	// good path: signed by the right MSP
  1099  	policy, err = getSignedByMSPMemberPolicy(mspid)
  1100  	if err != nil {
  1101  		t.Fatalf("failed getting policy, err %s", err)
  1102  	}
  1103  
  1104  	b = &common.Block{
  1105  		Data: &common.BlockData{
  1106  			Data: [][]byte{envBytes},
  1107  		},
  1108  		Header: &common.BlockHeader{},
  1109  	}
  1110  	err = v.Validate(b, "lscc", 0, 0, policy)
  1111  	require.EqualError(t, err, "chaincode instantiation policy violated, error signature set did not satisfy policy")
  1112  }
  1113  
  1114  func TestInvalidUpgrade(t *testing.T) {
  1115  	state := make(map[string]map[string][]byte)
  1116  	state["lscc"] = make(map[string][]byte)
  1117  
  1118  	v := newValidationInstance(state)
  1119  
  1120  	ccname := "mycc"
  1121  	ccver := "2"
  1122  
  1123  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
  1124  	require.NoError(t, err)
  1125  
  1126  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1127  	if err != nil {
  1128  		t.Fatalf("createTx returned err %s", err)
  1129  	}
  1130  
  1131  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1132  	if err != nil {
  1133  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1134  	}
  1135  
  1136  	// good path: signed by the right MSP
  1137  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1138  	if err != nil {
  1139  		t.Fatalf("failed getting policy, err %s", err)
  1140  	}
  1141  
  1142  	b := &common.Block{
  1143  		Data: &common.BlockData{
  1144  			Data: [][]byte{envBytes},
  1145  		},
  1146  		Header: &common.BlockHeader{},
  1147  	}
  1148  	err = v.Validate(b, "lscc", 0, 0, policy)
  1149  	require.EqualError(t, err, "Upgrading non-existent chaincode mycc")
  1150  }
  1151  
  1152  func TestValidateUpgradeOK(t *testing.T) {
  1153  	state := make(map[string]map[string][]byte)
  1154  	state["lscc"] = make(map[string][]byte)
  1155  
  1156  	v := newValidationInstance(state)
  1157  
  1158  	ccname := "mycc"
  1159  	ccver := "upgradeok"
  1160  	ccver = "2"
  1161  
  1162  	// policy signed by the right MSP
  1163  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1164  	if err != nil {
  1165  		t.Fatalf("failed getting policy, err %s", err)
  1166  	}
  1167  
  1168  	// create lscc record
  1169  	cd := &ccprovider.ChaincodeData{
  1170  		InstantiationPolicy: policy,
  1171  	}
  1172  	cdbytes, err := proto.Marshal(cd)
  1173  	if err != nil {
  1174  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1175  	}
  1176  	state["lscc"][ccname] = cdbytes
  1177  
  1178  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
  1179  	require.NoError(t, err)
  1180  
  1181  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1182  	if err != nil {
  1183  		t.Fatalf("createTx returned err %s", err)
  1184  	}
  1185  
  1186  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1187  	if err != nil {
  1188  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1189  	}
  1190  
  1191  	bl := &common.Block{
  1192  		Data: &common.BlockData{
  1193  			Data: [][]byte{envBytes},
  1194  		},
  1195  		Header: &common.BlockHeader{},
  1196  	}
  1197  	err = v.Validate(bl, "lscc", 0, 0, policy)
  1198  	require.NoError(t, err)
  1199  }
  1200  
  1201  func TestInvalidateUpgradeBadVersion(t *testing.T) {
  1202  	state := make(map[string]map[string][]byte)
  1203  	state["lscc"] = make(map[string][]byte)
  1204  
  1205  	v := newValidationInstance(state)
  1206  
  1207  	ccname := "mycc"
  1208  	ccver := "upgradebadversion"
  1209  
  1210  	// policy signed by the right MSP
  1211  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1212  	if err != nil {
  1213  		t.Fatalf("failed getting policy, err %s", err)
  1214  	}
  1215  
  1216  	// create lscc record
  1217  	cd := &ccprovider.ChaincodeData{
  1218  		InstantiationPolicy: policy,
  1219  		Version:             ccver,
  1220  	}
  1221  	cdbytes, err := proto.Marshal(cd)
  1222  	if err != nil {
  1223  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1224  	}
  1225  	state["lscc"][ccname] = cdbytes
  1226  
  1227  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
  1228  	require.NoError(t, err)
  1229  
  1230  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1231  	if err != nil {
  1232  		t.Fatalf("createTx returned err %s", err)
  1233  	}
  1234  
  1235  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1236  	if err != nil {
  1237  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1238  	}
  1239  
  1240  	bl := &common.Block{
  1241  		Data: &common.BlockData{
  1242  			Data: [][]byte{envBytes},
  1243  		},
  1244  		Header: &common.BlockHeader{},
  1245  	}
  1246  	err = v.Validate(bl, "lscc", 0, 0, policy)
  1247  	require.EqualError(t, err, fmt.Sprintf("Existing version of the cc on the ledger (%s) should be different from the upgraded one", ccver))
  1248  }
  1249  
  1250  func validateUpgradeWithCollection(t *testing.T, V1_2Validation bool) {
  1251  	state := make(map[string]map[string][]byte)
  1252  	state["lscc"] = make(map[string][]byte)
  1253  
  1254  	vs := &mocks.State{}
  1255  	vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) {
  1256  		if ns, ok := state[namespace]; ok {
  1257  			return [][]byte{ns[keys[0]]}, nil
  1258  		} else {
  1259  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
  1260  		}
  1261  	}
  1262  	sf := &mocks.StateFetcher{}
  1263  	sf.On("FetchState").Return(vs, nil)
  1264  	capabilities := &mocks.Capabilities{}
  1265  	capabilities.On("PrivateChannelData").Return(true)
  1266  	capabilities.On("V1_1Validation").Return(true)
  1267  	capabilities.On("V1_2Validation").Return(V1_2Validation)
  1268  	v := newCustomValidationInstance(sf, capabilities)
  1269  
  1270  	ccname := "mycc"
  1271  	ccver := "2"
  1272  
  1273  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1274  	if err != nil {
  1275  		t.Fatalf("failed getting policy, err %s", err)
  1276  	}
  1277  
  1278  	// create lscc record
  1279  	cd := &ccprovider.ChaincodeData{
  1280  		InstantiationPolicy: policy,
  1281  	}
  1282  	cdbytes, err := proto.Marshal(cd)
  1283  	if err != nil {
  1284  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1285  	}
  1286  	state["lscc"][ccname] = cdbytes
  1287  
  1288  	collName1 := "mycollection1"
  1289  	collName2 := "mycollection2"
  1290  	signers := [][]byte{[]byte("signer0"), []byte("signer1")}
  1291  	policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
  1292  	var requiredPeerCount, maximumPeerCount int32
  1293  	var blockToLive uint64
  1294  	requiredPeerCount = 1
  1295  	maximumPeerCount = 2
  1296  	blockToLive = 1000
  1297  	coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1298  	coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1299  
  1300  	// Test 1: Valid Collection Config in the upgrade.
  1301  	// V1_2Validation enabled: success
  1302  	// V1_2Validation disable: fail (as no collection updates are allowed)
  1303  	// Note: We might change V1_2Validation with CollectionUpdate capability
  1304  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}}
  1305  	ccpBytes, err := proto.Marshal(ccp)
  1306  	require.NoError(t, err)
  1307  	require.NotNil(t, ccpBytes)
  1308  
  1309  	defaultPolicy, err := getSignedByMSPAdminPolicy(mspid)
  1310  	require.NoError(t, err)
  1311  	res, err := createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
  1312  	require.NoError(t, err)
  1313  
  1314  	tx, err := createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes)
  1315  	if err != nil {
  1316  		t.Fatalf("createTx returned err %s", err)
  1317  	}
  1318  
  1319  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1320  	if err != nil {
  1321  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1322  	}
  1323  
  1324  	bl := &common.Block{
  1325  		Data: &common.BlockData{
  1326  			Data: [][]byte{envBytes},
  1327  		},
  1328  		Header: &common.BlockHeader{},
  1329  	}
  1330  	err = v.Validate(bl, "lscc", 0, 0, policy)
  1331  	if V1_2Validation {
  1332  		require.NoError(t, err)
  1333  	} else {
  1334  		require.Error(t, err, "LSCC can only issue a single putState upon deploy/upgrade")
  1335  	}
  1336  
  1337  	state["lscc"][privdata.BuildCollectionKVSKey(ccname)] = ccpBytes
  1338  
  1339  	if V1_2Validation {
  1340  		ccver = "3"
  1341  
  1342  		collName3 := "mycollection3"
  1343  		coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1344  
  1345  		// Test 2: some existing collections are missing in the updated config and peer in
  1346  		// V1_2Validation mode --> error
  1347  		ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll3}}
  1348  		ccpBytes, err = proto.Marshal(ccp)
  1349  		require.NoError(t, err)
  1350  		require.NotNil(t, ccpBytes)
  1351  
  1352  		res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
  1353  		require.NoError(t, err)
  1354  
  1355  		tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes)
  1356  		if err != nil {
  1357  			t.Fatalf("createTx returned err %s", err)
  1358  		}
  1359  
  1360  		envBytes, err = protoutil.GetBytesEnvelope(tx)
  1361  		if err != nil {
  1362  			t.Fatalf("GetBytesEnvelope returned err %s", err)
  1363  		}
  1364  
  1365  		bl = &common.Block{
  1366  			Data: &common.BlockData{
  1367  				Data: [][]byte{envBytes},
  1368  			},
  1369  			Header: &common.BlockHeader{},
  1370  		}
  1371  		err = v.Validate(bl, "lscc", 0, 0, policy)
  1372  		require.Error(t, err, "Some existing collection configurations are missing in the new collection configuration package")
  1373  
  1374  		ccver = "3"
  1375  
  1376  		// Test 3: some existing collections are missing in the updated config and peer in
  1377  		// V1_2Validation mode --> error
  1378  		ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll3}}
  1379  		ccpBytes, err = proto.Marshal(ccp)
  1380  		require.NoError(t, err)
  1381  		require.NotNil(t, ccpBytes)
  1382  
  1383  		res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
  1384  		require.NoError(t, err)
  1385  
  1386  		tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes)
  1387  		if err != nil {
  1388  			t.Fatalf("createTx returned err %s", err)
  1389  		}
  1390  
  1391  		envBytes, err = protoutil.GetBytesEnvelope(tx)
  1392  		if err != nil {
  1393  			t.Fatalf("GetBytesEnvelope returned err %s", err)
  1394  		}
  1395  
  1396  		bl = &common.Block{
  1397  			Data: &common.BlockData{
  1398  				Data: [][]byte{envBytes},
  1399  			},
  1400  			Header: &common.BlockHeader{},
  1401  		}
  1402  		err = v.Validate(bl, "lscc", 0, 0, policy)
  1403  		require.Error(t, err, "existing collection named mycollection2 is missing in the new collection configuration package")
  1404  
  1405  		ccver = "3"
  1406  
  1407  		// Test 4: valid collection config config and peer in V1_2Validation mode --> success
  1408  		ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2, coll3}}
  1409  		ccpBytes, err = proto.Marshal(ccp)
  1410  		require.NoError(t, err)
  1411  		require.NotNil(t, ccpBytes)
  1412  
  1413  		res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes)
  1414  		require.NoError(t, err)
  1415  
  1416  		tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes)
  1417  		if err != nil {
  1418  			t.Fatalf("createTx returned err %s", err)
  1419  		}
  1420  
  1421  		envBytes, err = protoutil.GetBytesEnvelope(tx)
  1422  		if err != nil {
  1423  			t.Fatalf("GetBytesEnvelope returned err %s", err)
  1424  		}
  1425  
  1426  		bl = &common.Block{
  1427  			Data: &common.BlockData{
  1428  				Data: [][]byte{envBytes},
  1429  			},
  1430  			Header: &common.BlockHeader{},
  1431  		}
  1432  		err = v.Validate(bl, "lscc", 0, 0, policy)
  1433  		require.NoError(t, err)
  1434  	}
  1435  }
  1436  
  1437  func TestValidateUpgradeWithCollection(t *testing.T) {
  1438  	// with V1_2Validation enabled
  1439  	validateUpgradeWithCollection(t, true)
  1440  	// with V1_2Validation disabled
  1441  	validateUpgradeWithCollection(t, false)
  1442  }
  1443  
  1444  func TestValidateUpgradeWithPoliciesOK(t *testing.T) {
  1445  	state := make(map[string]map[string][]byte)
  1446  	state["lscc"] = make(map[string][]byte)
  1447  
  1448  	v := newValidationInstance(state)
  1449  
  1450  	ccname := "mycc"
  1451  	ccver := "upgradewithpoliciesok"
  1452  
  1453  	// policy signed by the right MSP
  1454  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1455  	if err != nil {
  1456  		t.Fatalf("failed getting policy, err %s", err)
  1457  	}
  1458  
  1459  	// create lscc record
  1460  	cd := &ccprovider.ChaincodeData{
  1461  		InstantiationPolicy: policy,
  1462  	}
  1463  	cdbytes, err := proto.Marshal(cd)
  1464  	if err != nil {
  1465  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1466  	}
  1467  	state["lscc"][ccname] = cdbytes
  1468  
  1469  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
  1470  	require.NoError(t, err)
  1471  
  1472  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1473  	if err != nil {
  1474  		t.Fatalf("createTx returned err %s", err)
  1475  	}
  1476  
  1477  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1478  	if err != nil {
  1479  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1480  	}
  1481  
  1482  	bl := &common.Block{
  1483  		Data: &common.BlockData{
  1484  			Data: [][]byte{envBytes},
  1485  		},
  1486  		Header: &common.BlockHeader{},
  1487  	}
  1488  	err = v.Validate(bl, "lscc", 0, 0, policy)
  1489  	require.NoError(t, err)
  1490  }
  1491  
  1492  func TestValidateUpgradeWithNewFailAllIP(t *testing.T) {
  1493  	// we're testing upgrade.
  1494  	// In particular, we want to test the scenario where the upgrade
  1495  	// complies with the instantiation policy of the current version
  1496  	// BUT NOT the instantiation policy of the new version. For this
  1497  	// reason we first deploy a cc with IP which is equal to the AcceptAllPolicy
  1498  	// and then try to upgrade with a cc with the RejectAllPolicy.
  1499  	// We run this test twice, once with the V11 capability (and expect
  1500  	// a failure) and once without (and we expect success).
  1501  
  1502  	validateUpgradeWithNewFailAllIP(t, true, true)
  1503  	validateUpgradeWithNewFailAllIP(t, false, false)
  1504  }
  1505  
  1506  func validateUpgradeWithNewFailAllIP(t *testing.T, v11capability, expecterr bool) {
  1507  	state := make(map[string]map[string][]byte)
  1508  	state["lscc"] = make(map[string][]byte)
  1509  
  1510  	vs := &mocks.State{}
  1511  	vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) {
  1512  		if ns, ok := state[namespace]; ok {
  1513  			return [][]byte{ns[keys[0]]}, nil
  1514  		} else {
  1515  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
  1516  		}
  1517  	}
  1518  	sf := &mocks.StateFetcher{}
  1519  	sf.On("FetchState").Return(vs, nil)
  1520  	capabilities := &mocks.Capabilities{}
  1521  	capabilities.On("PrivateChannelData").Return(true)
  1522  	capabilities.On("V1_1Validation").Return(v11capability)
  1523  	capabilities.On("V1_2Validation").Return(false)
  1524  	v := newCustomValidationInstance(sf, capabilities)
  1525  
  1526  	ccname := "mycc"
  1527  	ccver := "2"
  1528  
  1529  	// create lscc record with accept all instantiation policy
  1530  	ipbytes, err := proto.Marshal(policydsl.AcceptAllPolicy)
  1531  	if err != nil {
  1532  		t.Fatalf("Failed to marshal AcceptAllPolicy: %s", err)
  1533  	}
  1534  	cd := &ccprovider.ChaincodeData{
  1535  		InstantiationPolicy: ipbytes,
  1536  	}
  1537  	cdbytes, err := proto.Marshal(cd)
  1538  	if err != nil {
  1539  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1540  	}
  1541  	state["lscc"][ccname] = cdbytes
  1542  
  1543  	// now we upgrade, with v 2 of the same cc, with the crucial difference that it has a reject all IP
  1544  	ccver = ccver + ".2"
  1545  
  1546  	simresres, err := createCCDataRWset(ccname, ccname, ccver,
  1547  		policydsl.MarshaledRejectAllPolicy, // here's where we specify the IP of the upgraded cc
  1548  	)
  1549  	require.NoError(t, err)
  1550  
  1551  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1552  	if err != nil {
  1553  		t.Fatalf("createTx returned err %s", err)
  1554  	}
  1555  
  1556  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1557  	if err != nil {
  1558  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1559  	}
  1560  
  1561  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1562  	if err != nil {
  1563  		t.Fatalf("failed getting policy, err %s", err)
  1564  	}
  1565  
  1566  	// execute the upgrade tx
  1567  	bl := &common.Block{
  1568  		Data: &common.BlockData{
  1569  			Data: [][]byte{envBytes},
  1570  		},
  1571  		Header: &common.BlockHeader{},
  1572  	}
  1573  	if expecterr {
  1574  		err = v.Validate(bl, "lscc", 0, 0, policy)
  1575  		require.Error(t, err)
  1576  	} else {
  1577  		err = v.Validate(bl, "lscc", 0, 0, policy)
  1578  		require.NoError(t, err)
  1579  	}
  1580  }
  1581  
  1582  func TestValidateUpgradeWithPoliciesFail(t *testing.T) {
  1583  	ccname := "mycc"
  1584  	ccver := "upgradewithpoliciesfail"
  1585  
  1586  	state := make(map[string]map[string][]byte)
  1587  	state["lscc"] = make(map[string][]byte)
  1588  
  1589  	v := newValidationInstance(state)
  1590  
  1591  	// create lscc record with reject all instantiation policy
  1592  	ipbytes, err := proto.Marshal(policydsl.RejectAllPolicy)
  1593  	if err != nil {
  1594  		t.Fatalf("Failed to marshal RejectAllPolicy: %s", err)
  1595  	}
  1596  	cd := &ccprovider.ChaincodeData{
  1597  		InstantiationPolicy: ipbytes,
  1598  		Version:             ccver,
  1599  	}
  1600  	cdbytes, err := proto.Marshal(cd)
  1601  	if err != nil {
  1602  		t.Fatalf("Failed to marshal ChaincodeData: %s", err)
  1603  	}
  1604  	state["lscc"][ccname] = cdbytes
  1605  
  1606  	ccver = "2"
  1607  	simresres, err := createCCDataRWset(ccname, ccname, ccver, nil)
  1608  	require.NoError(t, err)
  1609  
  1610  	tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres)
  1611  	if err != nil {
  1612  		t.Fatalf("createTx returned err %s", err)
  1613  	}
  1614  
  1615  	envBytes, err := protoutil.GetBytesEnvelope(tx)
  1616  	if err != nil {
  1617  		t.Fatalf("GetBytesEnvelope returned err %s", err)
  1618  	}
  1619  
  1620  	// good path: signed by the right MSP
  1621  	policy, err := getSignedByMSPMemberPolicy(mspid)
  1622  	if err != nil {
  1623  		t.Fatalf("failed getting policy, err %s", err)
  1624  	}
  1625  
  1626  	bl := &common.Block{
  1627  		Data: &common.BlockData{
  1628  			Data: [][]byte{envBytes},
  1629  		},
  1630  		Header: &common.BlockHeader{},
  1631  	}
  1632  	err = v.Validate(bl, "lscc", 0, 0, policy)
  1633  	require.EqualError(t, err, "chaincode instantiation policy violated, error signature set did not satisfy policy")
  1634  }
  1635  
  1636  var (
  1637  	id        msp.SigningIdentity
  1638  	sid       []byte
  1639  	mspid     string
  1640  	channelID string = "testchannelid"
  1641  )
  1642  
  1643  func createCollectionConfig(collectionName string, signaturePolicyEnvelope *common.SignaturePolicyEnvelope,
  1644  	requiredPeerCount int32, maximumPeerCount int32, blockToLive uint64,
  1645  ) *peer.CollectionConfig {
  1646  	signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{
  1647  		SignaturePolicy: signaturePolicyEnvelope,
  1648  	}
  1649  	accessPolicy := &peer.CollectionPolicyConfig{
  1650  		Payload: signaturePolicy,
  1651  	}
  1652  
  1653  	return &peer.CollectionConfig{
  1654  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1655  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1656  				Name:              collectionName,
  1657  				MemberOrgsPolicy:  accessPolicy,
  1658  				RequiredPeerCount: requiredPeerCount,
  1659  				MaximumPeerCount:  maximumPeerCount,
  1660  				BlockToLive:       blockToLive,
  1661  			},
  1662  		},
  1663  	}
  1664  }
  1665  
  1666  func testValidateCollection(t *testing.T, v *Validator, collectionConfigs []*peer.CollectionConfig, cdRWSet *ccprovider.ChaincodeData,
  1667  	lsccFunc string, ac channelconfig.ApplicationCapabilities, chid string,
  1668  ) error {
  1669  	ccp := &peer.CollectionConfigPackage{Config: collectionConfigs}
  1670  	ccpBytes, err := proto.Marshal(ccp)
  1671  	require.NoError(t, err)
  1672  	require.NotNil(t, ccpBytes)
  1673  
  1674  	lsccargs := [][]byte{nil, nil, nil, nil, nil, ccpBytes}
  1675  	rwset := &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: cdRWSet.Name}, {Key: privdata.BuildCollectionKVSKey(cdRWSet.Name), Value: ccpBytes}}}
  1676  
  1677  	err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid)
  1678  	return err
  1679  }
  1680  
  1681  func TestValidateRWSetAndCollectionForDeploy(t *testing.T) {
  1682  	var err error
  1683  	chid := "ch"
  1684  	ccid := "mycc"
  1685  	ccver := "1.0"
  1686  	cdRWSet := &ccprovider.ChaincodeData{Name: ccid, Version: ccver}
  1687  
  1688  	state := make(map[string]map[string][]byte)
  1689  	state["lscc"] = make(map[string][]byte)
  1690  
  1691  	v := newValidationInstance(state)
  1692  
  1693  	ac := capabilities.NewApplicationProvider(map[string]*common.Capability{
  1694  		capabilities.ApplicationV1_1: {},
  1695  	})
  1696  
  1697  	lsccFunc := lscc.DEPLOY
  1698  	// Test 1: More than two entries in the rwset -> error
  1699  	rwset := &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: "b"}, {Key: "c"}}}
  1700  	err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid)
  1701  	require.EqualError(t, err, "LSCC can only issue one or two putState upon deploy")
  1702  
  1703  	// Test 2: Invalid key for the collection config package -> error
  1704  	rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: "b"}}}
  1705  	err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid)
  1706  	require.EqualError(t, err, "invalid key for the collection of chaincode mycc:1.0; expected 'mycc~collection', received 'b'")
  1707  
  1708  	// Test 3: No collection config package -> success
  1709  	rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}}}
  1710  	err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid)
  1711  	require.NoError(t, err)
  1712  
  1713  	lsccargs := [][]byte{nil, nil, nil, nil, nil, nil}
  1714  	err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid)
  1715  	require.NoError(t, err)
  1716  
  1717  	// Test 4: Valid key for the collection config package -> success
  1718  	rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: privdata.BuildCollectionKVSKey(ccid)}}}
  1719  	err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid)
  1720  	require.NoError(t, err)
  1721  
  1722  	// Test 5: Collection configuration of the lscc args doesn't match the rwset
  1723  	lsccargs = [][]byte{nil, nil, nil, nil, nil, []byte("barf")}
  1724  	err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid)
  1725  	require.EqualError(t, err, "collection configuration arguments supplied for chaincode mycc:1.0 do not match the configuration in the lscc writeset")
  1726  
  1727  	// Test 6: Invalid collection config package -> error
  1728  	rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: privdata.BuildCollectionKVSKey("mycc"), Value: []byte("barf")}}}
  1729  	err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid)
  1730  	require.EqualError(t, err, "invalid collection configuration supplied for chaincode mycc:1.0")
  1731  
  1732  	// Test 7: Valid collection config package -> success
  1733  	collName1 := "mycollection1"
  1734  	collName2 := "mycollection2"
  1735  	signers := [][]byte{[]byte("signer0"), []byte("signer1")}
  1736  	policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
  1737  	var requiredPeerCount, maximumPeerCount int32
  1738  	var blockToLive uint64
  1739  	requiredPeerCount = 1
  1740  	maximumPeerCount = 2
  1741  	blockToLive = 10000
  1742  	coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1743  	coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1744  
  1745  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2}, cdRWSet, lsccFunc, ac, chid)
  1746  	require.NoError(t, err)
  1747  
  1748  	// Test 8: Duplicate collections in the collection config package -> success as the peer is in v1.1 validation mode
  1749  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll1}, cdRWSet, lsccFunc, ac, chid)
  1750  	require.NoError(t, err)
  1751  
  1752  	// Test 9: requiredPeerCount > maximumPeerCount -> success as the peer is in v1.1 validation mode
  1753  	collName3 := "mycollection3"
  1754  	requiredPeerCount = 2
  1755  	maximumPeerCount = 1
  1756  	blockToLive = 10000
  1757  	coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1758  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid)
  1759  	require.NoError(t, err)
  1760  
  1761  	// Enable v1.2 validation mode
  1762  	ac = capabilities.NewApplicationProvider(map[string]*common.Capability{
  1763  		capabilities.ApplicationV1_2: {},
  1764  	})
  1765  
  1766  	// Test 10: Duplicate collections in the collection config package -> error
  1767  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll1}, cdRWSet, lsccFunc, ac, chid)
  1768  	require.EqualError(t, err, "collection-name: mycollection1 -- found duplicate collection configuration")
  1769  
  1770  	// Test 11: requiredPeerCount < 0 -> error
  1771  	requiredPeerCount = -2
  1772  	maximumPeerCount = 1
  1773  	blockToLive = 10000
  1774  	coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1775  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid)
  1776  	require.EqualError(t, err, "collection-name: mycollection3 -- requiredPeerCount (1) cannot be less than zero (-2)",
  1777  		collName3, maximumPeerCount, requiredPeerCount)
  1778  
  1779  	// Test 11: requiredPeerCount > maximumPeerCount -> error
  1780  	requiredPeerCount = 2
  1781  	maximumPeerCount = 1
  1782  	blockToLive = 10000
  1783  	coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1784  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid)
  1785  	require.EqualError(t, err, "collection-name: mycollection3 -- maximum peer count (1) cannot be less than the required peer count (2)")
  1786  
  1787  	// Test 12: AND concatenation of orgs in access policy -> error
  1788  	requiredPeerCount = 1
  1789  	maximumPeerCount = 2
  1790  	policyEnvelope = policydsl.Envelope(policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
  1791  	coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1792  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll3}, cdRWSet, lsccFunc, ac, chid)
  1793  	require.EqualError(t, err, "collection-name: mycollection3 -- error in member org policy: signature policy is not an OR concatenation, NOutOf 2")
  1794  
  1795  	// Test 13: deploy with existing collection config on the ledger -> error
  1796  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}}
  1797  	ccpBytes, err := proto.Marshal(ccp)
  1798  	require.NoError(t, err)
  1799  	state["lscc"][privdata.BuildCollectionKVSKey(ccid)] = ccpBytes
  1800  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid)
  1801  	require.EqualError(t, err, "collection data should not exist for chaincode mycc:1.0")
  1802  }
  1803  
  1804  func TestValidateRWSetAndCollectionForUpgrade(t *testing.T) {
  1805  	chid := "ch"
  1806  	ccid := "mycc"
  1807  	ccver := "1.0"
  1808  	cdRWSet := &ccprovider.ChaincodeData{Name: ccid, Version: ccver}
  1809  
  1810  	state := make(map[string]map[string][]byte)
  1811  	state["lscc"] = make(map[string][]byte)
  1812  
  1813  	v := newValidationInstance(state)
  1814  
  1815  	ac := capabilities.NewApplicationProvider(map[string]*common.Capability{
  1816  		capabilities.ApplicationV1_2: {},
  1817  	})
  1818  
  1819  	lsccFunc := lscc.UPGRADE
  1820  
  1821  	collName1 := "mycollection1"
  1822  	collName2 := "mycollection2"
  1823  	collName3 := "mycollection3"
  1824  	signers := [][]byte{[]byte("signer0"), []byte("signer1")}
  1825  	policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
  1826  	var requiredPeerCount, maximumPeerCount int32
  1827  	var blockToLive uint64
  1828  	requiredPeerCount = 1
  1829  	maximumPeerCount = 2
  1830  	blockToLive = 3
  1831  	coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1832  	coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1833  	coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive)
  1834  
  1835  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}}
  1836  	ccpBytes, err := proto.Marshal(ccp)
  1837  	require.NoError(t, err)
  1838  
  1839  	// Test 1: no existing collection config package -> success
  1840  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid)
  1841  	require.NoError(t, err)
  1842  
  1843  	state["lscc"][privdata.BuildCollectionKVSKey(ccid)] = ccpBytes
  1844  
  1845  	// Test 2: exactly same as the existing collection config package -> success
  1846  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2}, cdRWSet, lsccFunc, ac, chid)
  1847  	require.NoError(t, err)
  1848  
  1849  	// Test 3: missing one existing collection (check based on the length) -> error
  1850  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid)
  1851  	require.EqualError(t, err, "the following existing collections are missing in the new collection configuration package: [mycollection2]")
  1852  
  1853  	// Test 4: missing one existing collection (check based on the collection names) -> error
  1854  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll3}, cdRWSet, lsccFunc, ac, chid)
  1855  	require.EqualError(t, err, "the following existing collections are missing in the new collection configuration package: [mycollection2]")
  1856  
  1857  	// Test 5: adding a new collection along with the existing collections -> success
  1858  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid)
  1859  	require.NoError(t, err)
  1860  
  1861  	newBlockToLive := blockToLive + 1
  1862  	coll2 = createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, newBlockToLive)
  1863  
  1864  	// Test 6: modify the BlockToLive in an existing collection -> error
  1865  	err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid)
  1866  	require.EqualError(t, err, "the BlockToLive in the following existing collections must not be modified: [mycollection2]")
  1867  }
  1868  
  1869  func TestMain(m *testing.M) {
  1870  	code := -1
  1871  	defer func() {
  1872  		os.Exit(code)
  1873  	}()
  1874  
  1875  	testDir, err := ioutil.TempDir("", "v1.3-validation")
  1876  	if err != nil {
  1877  		fmt.Printf("Could not create temp dir: %s", err)
  1878  		return
  1879  	}
  1880  	defer os.RemoveAll(testDir)
  1881  	ccprovider.SetChaincodesPath(testDir)
  1882  
  1883  	// setup the MSP manager so that we can sign/verify
  1884  	msptesttools.LoadMSPSetupForTesting()
  1885  
  1886  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1887  	if err != nil {
  1888  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
  1889  		return
  1890  	}
  1891  
  1892  	id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
  1893  	if err != nil {
  1894  		fmt.Printf("GetDefaultSigningIdentity failed with err %s", err)
  1895  		return
  1896  	}
  1897  
  1898  	sid, err = id.Serialize()
  1899  	if err != nil {
  1900  		fmt.Printf("Serialize failed with err %s", err)
  1901  		return
  1902  	}
  1903  
  1904  	// determine the MSP identifier for the first MSP in the default chain
  1905  	var msp msp.MSP
  1906  	mspMgr := mspmgmt.GetManagerForChain(channelID)
  1907  	msps, err := mspMgr.GetMSPs()
  1908  	if err != nil {
  1909  		fmt.Printf("Could not retrieve the MSPs for the chain manager, err %s", err)
  1910  		return
  1911  	}
  1912  	if len(msps) == 0 {
  1913  		fmt.Printf("At least one MSP was expected")
  1914  		return
  1915  	}
  1916  	for _, m := range msps {
  1917  		msp = m
  1918  		break
  1919  	}
  1920  	mspid, err = msp.GetIdentifier()
  1921  	if err != nil {
  1922  		fmt.Printf("Failure getting the msp identifier, err %s", err)
  1923  		return
  1924  	}
  1925  
  1926  	// also set the MSP for the "test" chain
  1927  	mspmgmt.XXXSetMSPManager("mycc", mspmgmt.GetManagerForChain("testchannelid"))
  1928  	code = m.Run()
  1929  }
  1930  
  1931  func TestInValidCollectionName(t *testing.T) {
  1932  	validNames := []string{"collection1", "collection_2"}
  1933  	inValidNames := []string{"collection.1", "collection%2", ""}
  1934  
  1935  	for _, name := range validNames {
  1936  		require.NoError(t, validateCollectionName(name), "Testing for name = "+name)
  1937  	}
  1938  	for _, name := range inValidNames {
  1939  		require.Error(t, validateCollectionName(name), "Testing for name = "+name)
  1940  	}
  1941  }
  1942  
  1943  func TestNoopTranslator_Translate(t *testing.T) {
  1944  	tr := &noopTranslator{}
  1945  	res, err := tr.Translate([]byte("Nel mezzo del cammin di nostra vita"))
  1946  	require.NoError(t, err)
  1947  	require.Equal(t, res, []byte("Nel mezzo del cammin di nostra vita"))
  1948  }