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

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