github.com/anjalikarhana/fabric@v2.1.1+incompatible/core/handlers/validation/builtin/v12/validation_logic_test.go (about)

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