github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/scc/lscc/lscc_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lscc
     8  
     9  import (
    10  	"archive/tar"
    11  	"bytes"
    12  	"compress/gzip"
    13  	"fmt"
    14  	"io/ioutil"
    15  	"os"
    16  	"strings"
    17  	"testing"
    18  
    19  	"github.com/golang/protobuf/proto"
    20  	"github.com/hyperledger/fabric-chaincode-go/shim"
    21  	"github.com/hyperledger/fabric-chaincode-go/shimtest"
    22  	"github.com/hyperledger/fabric-protos-go/common"
    23  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    24  	mb "github.com/hyperledger/fabric-protos-go/msp"
    25  	"github.com/hyperledger/fabric-protos-go/peer"
    26  	pb "github.com/hyperledger/fabric-protos-go/peer"
    27  	"github.com/osdi23p228/fabric/bccsp/sw"
    28  	"github.com/osdi23p228/fabric/common/channelconfig"
    29  	"github.com/osdi23p228/fabric/common/policies"
    30  	"github.com/osdi23p228/fabric/common/policydsl"
    31  	"github.com/osdi23p228/fabric/common/util"
    32  	"github.com/osdi23p228/fabric/core/aclmgmt/mocks"
    33  	"github.com/osdi23p228/fabric/core/aclmgmt/resources"
    34  	"github.com/osdi23p228/fabric/core/chaincode/lifecycle"
    35  	"github.com/osdi23p228/fabric/core/common/ccprovider"
    36  	"github.com/osdi23p228/fabric/core/common/sysccprovider"
    37  	"github.com/osdi23p228/fabric/core/container"
    38  	"github.com/osdi23p228/fabric/core/container/externalbuilder"
    39  	"github.com/osdi23p228/fabric/core/ledger/ledgermgmt"
    40  	"github.com/osdi23p228/fabric/core/ledger/ledgermgmt/ledgermgmttest"
    41  	"github.com/osdi23p228/fabric/core/policy"
    42  	policymocks "github.com/osdi23p228/fabric/core/policy/mocks"
    43  	"github.com/osdi23p228/fabric/core/scc/lscc/mock"
    44  	"github.com/osdi23p228/fabric/msp"
    45  	mspmgmt "github.com/osdi23p228/fabric/msp/mgmt"
    46  	msptesttools "github.com/osdi23p228/fabric/msp/mgmt/testtools"
    47  	mspmocks "github.com/osdi23p228/fabric/msp/mocks"
    48  	"github.com/osdi23p228/fabric/protoutil"
    49  	"github.com/pkg/errors"
    50  	"github.com/stretchr/testify/assert"
    51  	"github.com/stretchr/testify/require"
    52  )
    53  
    54  //go:generate counterfeiter -o mock/application.go -fake-name Application . application
    55  
    56  type application interface {
    57  	channelconfig.Application
    58  }
    59  
    60  //go:generate counterfeiter -o mock/application_capabilities.go -fake-name ApplicationCapabilities . applicationCapabilities
    61  
    62  type applicationCapabilities interface {
    63  	channelconfig.ApplicationCapabilities
    64  }
    65  
    66  // create a valid SignaturePolicyEnvelope to be used in tests
    67  var testPolicyEnvelope = &common.SignaturePolicyEnvelope{
    68  	Version: 0,
    69  	Rule:    policydsl.NOutOf(1, []*common.SignaturePolicy{policydsl.SignedBy(0)}),
    70  	Identities: []*mb.MSPPrincipal{
    71  		{
    72  			PrincipalClassification: mb.MSPPrincipal_ORGANIZATION_UNIT,
    73  			Principal:               protoutil.MarshalOrPanic(&mb.OrganizationUnit{MspIdentifier: "Org1"}),
    74  		},
    75  	},
    76  }
    77  
    78  func constructDeploymentSpec(name, path, version string, initArgs [][]byte, createInvalidIndex bool, createFS bool, scc *SCC) (*pb.ChaincodeDeploymentSpec, error) {
    79  	spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: name, Path: path, Version: version}, Input: &pb.ChaincodeInput{Args: initArgs}}
    80  
    81  	codePackageBytes := bytes.NewBuffer(nil)
    82  	gz := gzip.NewWriter(codePackageBytes)
    83  	tw := tar.NewWriter(gz)
    84  
    85  	payload := []byte(name + path + version)
    86  	err := tw.WriteHeader(&tar.Header{
    87  		Name: "src/garbage.go",
    88  		Size: int64(len(payload)),
    89  		Mode: 0100644,
    90  	})
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	_, err = tw.Write(payload)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	// create an invalid couchdb index definition for negative testing
   101  	if createInvalidIndex {
   102  		payload := []byte("invalid index definition")
   103  		err := tw.WriteHeader(&tar.Header{
   104  			Name: "META-INF/statedb/couchdb/indexes/badIndex.json",
   105  			Size: int64(len(payload)),
   106  			Mode: 0100644,
   107  		})
   108  		if err != nil {
   109  			return nil, err
   110  		}
   111  
   112  		_, err = tw.Write(payload)
   113  		if err != nil {
   114  			return nil, err
   115  		}
   116  	}
   117  
   118  	tw.Close()
   119  	gz.Close()
   120  
   121  	depSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes.Bytes()}
   122  
   123  	if createFS {
   124  		buf, err := proto.Marshal(depSpec)
   125  		if err != nil {
   126  			return nil, err
   127  		}
   128  
   129  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   130  		if err != nil {
   131  			return nil, err
   132  		}
   133  		cccdspack := &ccprovider.CDSPackage{GetHasher: cryptoProvider}
   134  		if _, err := cccdspack.InitFromBuffer(buf); err != nil {
   135  			return nil, err
   136  		}
   137  
   138  		scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = cccdspack
   139  		scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = nil
   140  		scc.Support.(*MockSupport).GetChaincodesFromLocalStorageRv = &pb.ChaincodeQueryResponse{Chaincodes: []*pb.ChaincodeInfo{{}}}
   141  		scc.Support.(*MockSupport).GetChaincodesFromLocalStorageErr = nil
   142  	} else {
   143  		scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = nil
   144  		scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = errors.New("barf")
   145  		scc.Support.(*MockSupport).GetChaincodesFromLocalStorageRv = nil
   146  		scc.Support.(*MockSupport).GetChaincodesFromLocalStorageErr = errors.New("barf")
   147  	}
   148  
   149  	return depSpec, nil
   150  }
   151  
   152  func getMSPIDs(cid string) []string {
   153  	return nil
   154  }
   155  
   156  // TestInstall tests the install function with various inputs
   157  func TestInstall(t *testing.T) {
   158  	// Initialize ledgermgmt that inturn initializes internal components (such as cceventmgmt on which this test depends)
   159  	tempdir, err := ioutil.TempDir("", "lscc-test")
   160  	require.NoError(t, err, "failed to create temporary directory")
   161  	defer os.RemoveAll(tempdir)
   162  
   163  	initializer := ledgermgmttest.NewInitializer(tempdir)
   164  
   165  	ledgerMgr := ledgermgmt.NewLedgerMgr(initializer)
   166  	defer ledgerMgr.Close()
   167  
   168  	chaincodeBuilder := &mock.ChaincodeBuilder{}
   169  
   170  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   171  	assert.NoError(t, err)
   172  	scc := &SCC{
   173  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   174  		Support:          &MockSupport{},
   175  		ACLProvider:      mockAclProvider,
   176  		GetMSPIDs:        getMSPIDs,
   177  		BCCSP:            cryptoProvider,
   178  		BuildRegistry:    &container.BuildRegistry{},
   179  		ChaincodeBuilder: chaincodeBuilder,
   180  		EbMetadataProvider: &externalbuilder.MetadataProvider{
   181  			DurablePath: "testdata",
   182  		},
   183  	}
   184  	stub := shimtest.NewMockStub("lscc", scc)
   185  	res := stub.MockInit("1", nil)
   186  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   187  
   188  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{}, nil)
   189  	assert.NotEqual(t, int32(shim.OK), res.Status)
   190  	assert.Equal(t, "invalid number of arguments to lscc: 0", res.Message)
   191  
   192  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("install")}, nil)
   193  	assert.NotEqual(t, int32(shim.OK), res.Status)
   194  	assert.Equal(t, "invalid number of arguments to lscc: 1", res.Message)
   195  
   196  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("install")}, nil)
   197  	assert.NotEqual(t, int32(shim.OK), res.Status)
   198  	assert.Equal(t, "invalid number of arguments to lscc: 1", res.Message)
   199  
   200  	path := "mychaincode"
   201  
   202  	testInstall(t, "example02", "0", path, false, "", "Alice", scc, stub, nil)
   203  
   204  	assert.Equal(t, 1, chaincodeBuilder.BuildCallCount())
   205  	assert.Equal(t, "example02:0", chaincodeBuilder.BuildArgsForCall(0))
   206  
   207  	// Re-install, should not build a second time
   208  	testInstall(t, "example02", "0", path, false, "", "Alice", scc, stub, nil)
   209  	assert.Equal(t, 1, chaincodeBuilder.BuildCallCount())
   210  
   211  	chaincodeBuilder.BuildReturns(fmt.Errorf("fake-build-error"))
   212  	testInstall(t, "example02-different", "0", path, false, "chaincode installed to peer but could not build chaincode: fake-build-error", "Alice", scc, stub, nil)
   213  	chaincodeBuilder.BuildReturns(nil)
   214  
   215  	// This is a bad test, but it does at least exercise the external builder md path
   216  	// The integration tests will ultimately ensure that it actually works.
   217  	testInstall(t, "external-built", "cc", path, false, "", "Alice", scc, stub, nil)
   218  
   219  	testInstall(t, "example02-2", "1.0", path, false, "", "Alice", scc, stub, nil)
   220  	testInstall(t, "example02.go", "0", path, false, InvalidChaincodeNameErr("example02.go").Error(), "Alice", scc, stub, nil)
   221  	testInstall(t, "", "0", path, false, InvalidChaincodeNameErr("").Error(), "Alice", scc, stub, nil)
   222  	testInstall(t, "example02", "1{}0", path, false, InvalidVersionErr("1{}0").Error(), "Alice", scc, stub, nil)
   223  	testInstall(t, "example02", "0", path, true, InvalidStatedbArtifactsErr("").Error(), "Alice", scc, stub, nil)
   224  	testInstall(t, "example02", "0", path, false, "access denied for [install]", "Bob", scc, stub, errors.New("authorization error"))
   225  	testInstall(t, "example02-2", "1.0-alpha+001", path, false, "", "Alice", scc, stub, nil)
   226  	testInstall(t, "example02-2", "1.0+sha.c0ffee", path, false, "", "Alice", scc, stub, nil)
   227  
   228  	scc.Support.(*MockSupport).PutChaincodeToLocalStorageErr = errors.New("barf")
   229  
   230  	testInstall(t, "example02", "0", path, false, "barf", "Alice", scc, stub, nil)
   231  	testInstall(t, "lscc", "0", path, false, "cannot install: lscc is the name of a system chaincode", "Alice", scc, stub, nil)
   232  }
   233  
   234  func testInstall(t *testing.T, ccname string, version string, path string, createInvalidIndex bool, expectedErrorMsg string, caller string, scc *SCC, stub *shimtest.MockStub, aclErr error) {
   235  	t.Run(ccname+":"+version, func(t *testing.T) {
   236  		identityDeserializer := &policymocks.MockIdentityDeserializer{
   237  			Identity: []byte("Alice"),
   238  			Msg:      []byte("msg1"),
   239  		}
   240  		policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{
   241  			Managers: map[string]policies.Manager{
   242  				"test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}},
   243  			},
   244  		}
   245  		scc.PolicyChecker = policy.NewPolicyChecker(
   246  			policyManagerGetter,
   247  			identityDeserializer,
   248  			&policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   249  		)
   250  
   251  		cds, err := constructDeploymentSpec(ccname, path, version, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, createInvalidIndex, false, scc)
   252  		assert.NoError(t, err)
   253  		cdsBytes := protoutil.MarshalOrPanic(cds)
   254  
   255  		// constructDeploymentSpec puts the depspec on the FS. This should succeed
   256  		args := [][]byte{[]byte("install"), cdsBytes}
   257  
   258  		sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte(caller), []byte("msg1"))
   259  		identityDeserializer.Msg = sProp.ProposalBytes
   260  		sProp.Signature = sProp.ProposalBytes
   261  
   262  		mockAclProvider.Reset()
   263  		mockAclProvider.On("CheckACL", resources.Lscc_Install, "", sProp).Return(aclErr)
   264  
   265  		if expectedErrorMsg == "" {
   266  			res := stub.MockInvokeWithSignedProposal("1", args, sProp)
   267  			assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   268  		} else {
   269  			res := stub.MockInvokeWithSignedProposal("1", args, sProp)
   270  			assert.True(t, strings.HasPrefix(string(res.Message), expectedErrorMsg), res.Message)
   271  		}
   272  	})
   273  }
   274  
   275  func TestNewLifecycleEnabled(t *testing.T) {
   276  	// Enable PrivateChannelData
   277  	capabilities := &mock.ApplicationCapabilities{}
   278  	capabilities.LifecycleV20Returns(true)
   279  	application := &mock.Application{}
   280  	application.CapabilitiesReturns(capabilities)
   281  	sccProvider := &mock.SystemChaincodeProvider{}
   282  	sccProvider.GetApplicationConfigReturns(application, true)
   283  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   284  	assert.NoError(t, err)
   285  
   286  	scc := &SCC{
   287  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   288  		Support:          &SupportImpl{GetMSPIDs: getMSPIDs},
   289  		SCCProvider:      sccProvider,
   290  		ACLProvider:      mockAclProvider,
   291  		GetMSPIDs:        getMSPIDs,
   292  		BCCSP:            cryptoProvider,
   293  		BuildRegistry:    &container.BuildRegistry{},
   294  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   295  	}
   296  	stub := shimtest.NewMockStub("lscc", scc)
   297  	res := stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("deploy"), []byte("test"), nil}, nil)
   298  	assert.NotEqual(t, int32(shim.OK), res.Status)
   299  	assert.Equal(t, "Channel 'test' has been migrated to the new lifecycle, LSCC is now read-only", res.Message)
   300  
   301  }
   302  
   303  func TestDeploy(t *testing.T) {
   304  	path := "mychaincode"
   305  
   306  	testDeploy(t, "example02", "0", path, false, false, true, "", nil, nil, nil)
   307  	testDeploy(t, "example02", "1.0", path, false, false, true, "", nil, nil, nil)
   308  	testDeploy(t, "example02", "1.0", path, false, false, false, "cannot get package for chaincode (example02:1.0)", nil, nil, nil)
   309  	testDeploy(t, "example02", "0", path, true, false, true, InvalidChaincodeNameErr("").Error(), nil, nil, nil)
   310  	testDeploy(t, "example02", "0", path, false, true, true, InvalidVersionErr("").Error(), nil, nil, nil)
   311  	testDeploy(t, "example02.go", "0", path, false, false, true, InvalidChaincodeNameErr("example02.go").Error(), nil, nil, nil)
   312  	testDeploy(t, "example02", "1{}0", path, false, false, true, InvalidVersionErr("1{}0").Error(), nil, nil, nil)
   313  	testDeploy(t, "example02", "0", path, true, true, true, InvalidChaincodeNameErr("").Error(), nil, nil, nil)
   314  
   315  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   316  	assert.NoError(t, err)
   317  	scc := &SCC{
   318  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   319  		Support:          &MockSupport{},
   320  		SCCProvider:      NewMockProvider(),
   321  		ACLProvider:      mockAclProvider,
   322  		GetMSPIDs:        getMSPIDs,
   323  		BCCSP:            cryptoProvider,
   324  		BuildRegistry:    &container.BuildRegistry{},
   325  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   326  	}
   327  	stub := shimtest.NewMockStub("lscc", scc)
   328  	res := stub.MockInit("1", nil)
   329  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   330  
   331  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("deploy")}, nil)
   332  	assert.NotEqual(t, int32(shim.OK), res.Status)
   333  	assert.Equal(t, "invalid number of arguments to lscc: 1", res.Message)
   334  
   335  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("deploy"), []byte(""), []byte("")}, nil)
   336  	assert.NotEqual(t, int32(shim.OK), res.Status)
   337  	assert.Equal(t, "invalid channel name: ", res.Message)
   338  
   339  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("deploy"), []byte("chain"), []byte("barf")}, nil)
   340  	assert.NotEqual(t, int32(shim.OK), res.Status)
   341  	assert.Equal(t, "error unmarshaling ChaincodeDeploymentSpec: unexpected EOF", res.Message)
   342  
   343  	testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, nil)
   344  	testDeploy(t, "example02", "1.0", path, false, false, true, "chaincode with name 'example02' already exists", scc, stub, nil)
   345  
   346  	scc = &SCC{
   347  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   348  		Support:          &MockSupport{},
   349  		SCCProvider:      NewMockProvider(),
   350  		ACLProvider:      mockAclProvider,
   351  		GetMSPIDs:        getMSPIDs,
   352  		BCCSP:            cryptoProvider,
   353  		BuildRegistry:    &container.BuildRegistry{},
   354  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   355  	}
   356  	stub = shimtest.NewMockStub("lscc", scc)
   357  	res = stub.MockInit("1", nil)
   358  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   359  	scc.Support.(*MockSupport).GetInstantiationPolicyErr = errors.New("barf")
   360  
   361  	testDeploy(t, "example02", "1.0", path, false, false, true, "barf", scc, stub, nil)
   362  
   363  	scc = &SCC{
   364  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   365  		Support:          &MockSupport{},
   366  		SCCProvider:      NewMockProvider(),
   367  		ACLProvider:      mockAclProvider,
   368  		GetMSPIDs:        getMSPIDs,
   369  		BCCSP:            cryptoProvider,
   370  		BuildRegistry:    &container.BuildRegistry{},
   371  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   372  	}
   373  	stub = shimtest.NewMockStub("lscc", scc)
   374  	res = stub.MockInit("1", nil)
   375  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   376  	scc.Support.(*MockSupport).CheckInstantiationPolicyErr = errors.New("barf")
   377  
   378  	testDeploy(t, "example02", "1.0", path, false, false, true, "barf", scc, stub, nil)
   379  
   380  	scc = &SCC{
   381  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   382  		Support:          &MockSupport{},
   383  		SCCProvider:      NewMockProvider(),
   384  		ACLProvider:      mockAclProvider,
   385  		GetMSPIDs:        getMSPIDs,
   386  		BCCSP:            cryptoProvider,
   387  		BuildRegistry:    &container.BuildRegistry{},
   388  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   389  	}
   390  	stub = shimtest.NewMockStub("lscc", scc)
   391  	res = stub.MockInit("1", nil)
   392  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   393  
   394  	// As the PrivateChannelData is disabled, the following error message is expected due to the presence of
   395  	// collectionConfigBytes in the stub.args
   396  	testDeploy(t, "example02", "1.0", path, false, false, true, PrivateChannelDataNotAvailable("").Error(), scc, stub, []byte("collections"))
   397  
   398  	// Enable PrivateChannelData
   399  	capabilities := &mock.ApplicationCapabilities{}
   400  	capabilities.PrivateChannelDataReturns(true)
   401  	application := &mock.Application{}
   402  	application.CapabilitiesReturns(capabilities)
   403  	sccProvider := &mock.SystemChaincodeProvider{}
   404  	sccProvider.GetApplicationConfigReturns(application, true)
   405  
   406  	scc = &SCC{
   407  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   408  		Support:          &MockSupport{},
   409  		SCCProvider:      sccProvider,
   410  		ACLProvider:      mockAclProvider,
   411  		GetMSPIDs:        getMSPIDs,
   412  		BCCSP:            cryptoProvider,
   413  		BuildRegistry:    &container.BuildRegistry{},
   414  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   415  	}
   416  	stub = shimtest.NewMockStub("lscc", scc)
   417  	res = stub.MockInit("1", nil)
   418  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   419  
   420  	// As the PrivateChannelData is enabled and collectionConfigBytes is invalid, the following error
   421  	// message is expected.
   422  	errMessage := "invalid collection configuration supplied for chaincode example02:1.0"
   423  	testDeploy(t, "example02", "1.0", path, false, false, true, errMessage, scc, stub, []byte("invalid collection"))
   424  	// Should contain an entry for the chaincodeData only
   425  	assert.Equal(t, 1, len(stub.State))
   426  	_, ok := stub.State["example02"]
   427  	assert.Equal(t, true, ok)
   428  
   429  	collName1 := "mycollection1"
   430  	policyEnvelope := policydsl.SignedByAnyMember([]string{"SampleOrg"})
   431  	var requiredPeerCount, maximumPeerCount int32
   432  	requiredPeerCount = 1
   433  	maximumPeerCount = 2
   434  	coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount)
   435  
   436  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}}
   437  	ccpBytes, err := proto.Marshal(ccp)
   438  	assert.NoError(t, err)
   439  	assert.NotNil(t, ccpBytes)
   440  
   441  	scc = &SCC{
   442  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   443  		Support:          &MockSupport{},
   444  		SCCProvider:      sccProvider,
   445  		ACLProvider:      mockAclProvider,
   446  		GetMSPIDs:        getMSPIDs,
   447  		BCCSP:            cryptoProvider,
   448  		BuildRegistry:    &container.BuildRegistry{},
   449  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   450  	}
   451  	stub = shimtest.NewMockStub("lscc", scc)
   452  	res = stub.MockInit("1", nil)
   453  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   454  
   455  	// As the PrivateChannelData is enabled and collectionConfigBytes is valid, no error is expected
   456  	testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, ccpBytes)
   457  	// Should contain two entries: one for the chaincodeData and another for the collectionConfigBytes
   458  	assert.Equal(t, 2, len(stub.State))
   459  	_, ok = stub.State["example02"]
   460  	assert.Equal(t, true, ok)
   461  	actualccpBytes, ok := stub.State["example02~collection"]
   462  	assert.Equal(t, true, ok)
   463  	assert.Equal(t, ccpBytes, actualccpBytes)
   464  
   465  	scc = &SCC{
   466  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   467  		Support:          &MockSupport{},
   468  		SCCProvider:      sccProvider,
   469  		ACLProvider:      mockAclProvider,
   470  		GetMSPIDs:        getMSPIDs,
   471  		BCCSP:            cryptoProvider,
   472  		BuildRegistry:    &container.BuildRegistry{},
   473  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   474  	}
   475  	stub = shimtest.NewMockStub("lscc", scc)
   476  	res = stub.MockInit("1", nil)
   477  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   478  
   479  	// As the PrivateChannelData is enabled and collectionConfigBytes is nil, no error is expected
   480  	testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, []byte("nil"))
   481  	// Should contain an entry for the chaincodeData only. As the collectionConfigBytes is nil, it
   482  	// is ignored
   483  	assert.Equal(t, 1, len(stub.State))
   484  	_, ok = stub.State["example02"]
   485  	assert.Equal(t, true, ok)
   486  }
   487  
   488  func createCollectionConfig(collectionName string, signaturePolicyEnvelope *common.SignaturePolicyEnvelope,
   489  	requiredPeerCount int32, maximumPeerCount int32,
   490  ) *peer.CollectionConfig {
   491  	signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{
   492  		SignaturePolicy: signaturePolicyEnvelope,
   493  	}
   494  	accessPolicy := &peer.CollectionPolicyConfig{
   495  		Payload: signaturePolicy,
   496  	}
   497  
   498  	return &peer.CollectionConfig{
   499  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
   500  			StaticCollectionConfig: &peer.StaticCollectionConfig{
   501  				Name:              collectionName,
   502  				MemberOrgsPolicy:  accessPolicy,
   503  				RequiredPeerCount: requiredPeerCount,
   504  				MaximumPeerCount:  maximumPeerCount,
   505  			},
   506  		},
   507  	}
   508  }
   509  
   510  func testDeploy(t *testing.T, ccname string, version string, path string, forceBlankCCName bool, forceBlankVersion bool, install bool, expectedErrorMsg string, scc *SCC, stub *shimtest.MockStub, collectionConfigBytes []byte) {
   511  	if scc == nil {
   512  		cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   513  		scc = &SCC{
   514  			BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   515  			Support:          &MockSupport{},
   516  			SCCProvider:      NewMockProvider(),
   517  			ACLProvider:      mockAclProvider,
   518  			GetMSPIDs:        getMSPIDs,
   519  			BCCSP:            cryptoProvider,
   520  			BuildRegistry:    &container.BuildRegistry{},
   521  			ChaincodeBuilder: &mock.ChaincodeBuilder{},
   522  		}
   523  		stub = shimtest.NewMockStub("lscc", scc)
   524  		res := stub.MockInit("1", nil)
   525  		assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   526  	}
   527  	stub.ChannelID = channelID
   528  
   529  	identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")}
   530  	policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{
   531  		Managers: map[string]policies.Manager{
   532  			"test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}},
   533  		},
   534  	}
   535  	scc.PolicyChecker = policy.NewPolicyChecker(
   536  		policyManagerGetter,
   537  		identityDeserializer,
   538  		&policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   539  	)
   540  	sProp, _ := protoutil.MockSignedEndorserProposalOrPanic(channelID, &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
   541  	identityDeserializer.Msg = sProp.ProposalBytes
   542  	sProp.Signature = sProp.ProposalBytes
   543  
   544  	cds, err := constructDeploymentSpec(ccname, path, version, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, install, scc)
   545  	assert.NoError(t, err)
   546  
   547  	if forceBlankCCName {
   548  		cds.ChaincodeSpec.ChaincodeId.Name = ""
   549  	}
   550  	if forceBlankVersion {
   551  		cds.ChaincodeSpec.ChaincodeId.Version = ""
   552  	}
   553  	cdsBytes := protoutil.MarshalOrPanic(cds)
   554  
   555  	sProp2, _ := protoutil.MockSignedEndorserProposal2OrPanic(channelID, &pb.ChaincodeSpec{}, id)
   556  	var args [][]byte
   557  	if len(collectionConfigBytes) > 0 {
   558  		if bytes.Equal(collectionConfigBytes, []byte("nil")) {
   559  			args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes, nil, []byte("escc"), []byte("vscc"), nil}
   560  		} else {
   561  			args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes, nil, []byte("escc"), []byte("vscc"), collectionConfigBytes}
   562  		}
   563  	} else {
   564  		args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes}
   565  	}
   566  	res := stub.MockInvokeWithSignedProposal("1", args, sProp2)
   567  
   568  	if expectedErrorMsg == "" {
   569  		assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   570  
   571  		for _, function := range []string{"getchaincodes", "GetChaincodes"} {
   572  			t.Run(function, func(t *testing.T) {
   573  				mockAclProvider.Reset()
   574  				mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, channelID, sProp).Return(nil)
   575  				args = [][]byte{[]byte(function)}
   576  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   577  				assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   578  			})
   579  		}
   580  		for _, function := range []string{"getid", "ChaincodeExists"} {
   581  			t.Run(function, func(t *testing.T) {
   582  				mockAclProvider.Reset()
   583  				mockAclProvider.On("CheckACL", resources.Lscc_ChaincodeExists, "test", sProp).Return(nil)
   584  				args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
   585  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   586  				assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   587  			})
   588  		}
   589  		for _, function := range []string{"getdepspec", "GetDeploymentSpec"} {
   590  			t.Run(function, func(t *testing.T) {
   591  				mockAclProvider.Reset()
   592  				mockAclProvider.On("CheckACL", resources.Lscc_GetDeploymentSpec, "test", sProp).Return(nil)
   593  				args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
   594  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   595  				assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   596  				scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = errors.New("barf")
   597  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   598  				assert.NotEqual(t, int32(shim.OK), res.Status)
   599  				assert.Equal(t, "invalid deployment spec: barf", res.Message)
   600  				scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = nil
   601  				bkpCCFromLSRv := scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv
   602  				cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   603  				scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = &ccprovider.CDSPackage{GetHasher: cryptoProvider}
   604  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   605  				assert.NotEqual(t, int32(shim.OK), res.Status)
   606  				assert.Contains(t, res.Message, "chaincode fingerprint mismatch")
   607  				scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = bkpCCFromLSRv
   608  			})
   609  		}
   610  
   611  		for _, function := range []string{"getccdata", "GetChaincodeData"} {
   612  			t.Run(function, func(t *testing.T) {
   613  				mockAclProvider.Reset()
   614  				mockAclProvider.On("CheckACL", resources.Lscc_GetChaincodeData, "test", sProp).Return(nil)
   615  				args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
   616  				res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   617  				assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   618  			})
   619  		}
   620  	} else {
   621  		assert.Equal(t, expectedErrorMsg, string(res.Message))
   622  	}
   623  }
   624  
   625  // TestUpgrade tests the upgrade function with various inputs for basic use cases
   626  func TestUpgrade(t *testing.T) {
   627  	path := "mychaincode"
   628  
   629  	testUpgrade(t, "example02", "0", "example02", "1", path, "", nil, nil, nil)
   630  	testUpgrade(t, "example02", "0", "example02", "", path, InvalidVersionErr("").Error(), nil, nil, nil)
   631  	testUpgrade(t, "example02", "0", "example02", "0", path, IdenticalVersionErr("example02").Error(), nil, nil, nil)
   632  	testUpgrade(t, "example02", "0", "example03", "1", path, NotFoundErr("example03").Error(), nil, nil, nil)
   633  	testUpgrade(t, "example02", "0", "example02", "1{}0", path, InvalidVersionErr("1{}0").Error(), nil, nil, nil)
   634  	testUpgrade(t, "example02", "0", "example*02", "1{}0", path, InvalidChaincodeNameErr("example*02").Error(), nil, nil, nil)
   635  	testUpgrade(t, "example02", "0", "", "1", path, InvalidChaincodeNameErr("").Error(), nil, nil, nil)
   636  
   637  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   638  	assert.NoError(t, err)
   639  	scc := &SCC{
   640  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   641  		Support:          &MockSupport{},
   642  		SCCProvider:      NewMockProvider(),
   643  		ACLProvider:      mockAclProvider,
   644  		GetMSPIDs:        getMSPIDs,
   645  		BCCSP:            cryptoProvider,
   646  		BuildRegistry:    &container.BuildRegistry{},
   647  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   648  	}
   649  	stub := shimtest.NewMockStub("lscc", scc)
   650  	res := stub.MockInit("1", nil)
   651  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   652  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   653  	scc.Support.(*MockSupport).GetInstantiationPolicyErr = errors.New("barf")
   654  
   655  	testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil)
   656  
   657  	scc = &SCC{
   658  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   659  		Support:          &MockSupport{},
   660  		SCCProvider:      NewMockProvider(),
   661  		ACLProvider:      mockAclProvider,
   662  		GetMSPIDs:        getMSPIDs,
   663  		BCCSP:            cryptoProvider,
   664  		BuildRegistry:    &container.BuildRegistry{},
   665  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   666  	}
   667  	stub = shimtest.NewMockStub("lscc", scc)
   668  	res = stub.MockInit("1", nil)
   669  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   670  
   671  	testUpgrade(t, "example02", "0", "example02", "1", path, "instantiation policy missing", scc, stub, nil)
   672  
   673  	scc = &SCC{
   674  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   675  		Support:          &MockSupport{},
   676  		SCCProvider:      NewMockProvider(),
   677  		ACLProvider:      mockAclProvider,
   678  		GetMSPIDs:        getMSPIDs,
   679  		BCCSP:            cryptoProvider,
   680  		BuildRegistry:    &container.BuildRegistry{},
   681  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   682  	}
   683  	stub = shimtest.NewMockStub("lscc", scc)
   684  	res = stub.MockInit("1", nil)
   685  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   686  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   687  	scc.Support.(*MockSupport).GetInstantiationPolicyMap = map[string][]byte{}
   688  	scc.Support.(*MockSupport).CheckInstantiationPolicyMap = map[string]error{"example020": errors.New("barf")}
   689  
   690  	testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil)
   691  
   692  	scc = &SCC{
   693  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   694  		Support:          &MockSupport{},
   695  		SCCProvider:      NewMockProvider(),
   696  		ACLProvider:      mockAclProvider,
   697  		GetMSPIDs:        getMSPIDs,
   698  		BCCSP:            cryptoProvider,
   699  		BuildRegistry:    &container.BuildRegistry{},
   700  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   701  	}
   702  	stub = shimtest.NewMockStub("lscc", scc)
   703  	res = stub.MockInit("1", nil)
   704  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   705  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   706  	scc.Support.(*MockSupport).GetInstantiationPolicyMap = map[string][]byte{}
   707  	scc.Support.(*MockSupport).CheckInstantiationPolicyMap = map[string]error{"example021": errors.New("barf")}
   708  
   709  	testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil)
   710  
   711  	// Enable PrivateChannelData
   712  	capabilities := &mock.ApplicationCapabilities{}
   713  	capabilities.PrivateChannelDataReturns(true)
   714  	application := &mock.Application{}
   715  	application.CapabilitiesReturns(capabilities)
   716  	sccProvider := &mock.SystemChaincodeProvider{}
   717  	sccProvider.GetApplicationConfigReturns(application, true)
   718  
   719  	scc = &SCC{
   720  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   721  		Support:          &MockSupport{},
   722  		SCCProvider:      sccProvider,
   723  		ACLProvider:      mockAclProvider,
   724  		GetMSPIDs:        getMSPIDs,
   725  		BCCSP:            cryptoProvider,
   726  		BuildRegistry:    &container.BuildRegistry{},
   727  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   728  	}
   729  	stub = shimtest.NewMockStub("lscc", scc)
   730  	res = stub.MockInit("1", nil)
   731  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   732  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   733  
   734  	collName1 := "mycollection1"
   735  	var requiredPeerCount, maximumPeerCount int32
   736  	requiredPeerCount = 1
   737  	maximumPeerCount = 2
   738  	coll1 := createCollectionConfig(collName1, testPolicyEnvelope, requiredPeerCount, maximumPeerCount)
   739  
   740  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}}
   741  	ccpBytes, err := proto.Marshal(ccp)
   742  	assert.NoError(t, err)
   743  	assert.NotNil(t, ccpBytes)
   744  
   745  	// As v12 capability is not enabled (which is required for the collection upgrade), an error is expected
   746  	expectedErrorMsg := "as V1_2 capability is not enabled, collection upgrades are not allowed"
   747  	testUpgrade(t, "example02", "0", "example02", "1", path, expectedErrorMsg, scc, stub, ccpBytes)
   748  
   749  	// Enable PrivateChannelData and V1_2Validation
   750  	capabilities = &mock.ApplicationCapabilities{}
   751  	capabilities.CollectionUpgradeReturns(true)
   752  	capabilities.PrivateChannelDataReturns(true)
   753  	application = &mock.Application{}
   754  	application.CapabilitiesReturns(capabilities)
   755  	sccProvider = &mock.SystemChaincodeProvider{}
   756  	sccProvider.GetApplicationConfigReturns(application, true)
   757  
   758  	scc = &SCC{
   759  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   760  		Support:          &MockSupport{},
   761  		SCCProvider:      sccProvider,
   762  		ACLProvider:      mockAclProvider,
   763  		GetMSPIDs:        getMSPIDs,
   764  		BCCSP:            cryptoProvider,
   765  		BuildRegistry:    &container.BuildRegistry{},
   766  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   767  	}
   768  	stub = shimtest.NewMockStub("lscc", scc)
   769  	res = stub.MockInit("1", nil)
   770  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   771  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   772  
   773  	// As the PrivateChannelData is enabled and collectionConfigBytes is valid, no error is expected
   774  	testUpgrade(t, "example02", "0", "example02", "1", path, "", scc, stub, []byte("nil"))
   775  	// Should contain an entry for the chaincodeData only as the collectionConfigBytes is nil
   776  	assert.Equal(t, 1, len(stub.State))
   777  	_, ok := stub.State["example02"]
   778  	assert.Equal(t, true, ok)
   779  
   780  	scc = &SCC{
   781  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   782  		Support:          &MockSupport{},
   783  		SCCProvider:      sccProvider,
   784  		ACLProvider:      mockAclProvider,
   785  		GetMSPIDs:        getMSPIDs,
   786  		BCCSP:            cryptoProvider,
   787  		BuildRegistry:    &container.BuildRegistry{},
   788  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   789  	}
   790  	stub = shimtest.NewMockStub("lscc", scc)
   791  	res = stub.MockInit("1", nil)
   792  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   793  	scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   794  
   795  	// As the PrivateChannelData is enabled and collectionConfigBytes is valid, no error is expected
   796  	testUpgrade(t, "example02", "0", "example02", "1", path, "", scc, stub, ccpBytes)
   797  	// Should contain two entries: one for the chaincodeData and another for the collectionConfigBytes
   798  	// as the V1_2Validation is enabled. Only in V1_2Validation, collection upgrades are allowed.
   799  	// Note that V1_2Validation would be replaced with CollectionUpgrade capability.
   800  	assert.Equal(t, 2, len(stub.State))
   801  	_, ok = stub.State["example02"]
   802  	assert.Equal(t, true, ok)
   803  	actualccpBytes, ok := stub.State["example02~collection"]
   804  	assert.Equal(t, true, ok)
   805  	assert.Equal(t, ccpBytes, actualccpBytes)
   806  }
   807  
   808  func testUpgrade(t *testing.T, ccname string, version string, newccname string, newversion string, path string, expectedErrorMsg string, scc *SCC, stub *shimtest.MockStub, collectionConfigBytes []byte) {
   809  	t.Run(ccname+":"+version+"->"+newccname+":"+newversion, func(t *testing.T) {
   810  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   811  		assert.NoError(t, err)
   812  		if scc == nil {
   813  			scc = &SCC{
   814  				BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   815  				Support:          &MockSupport{},
   816  				SCCProvider:      NewMockProvider(),
   817  				ACLProvider:      mockAclProvider,
   818  				GetMSPIDs:        getMSPIDs,
   819  				BCCSP:            cryptoProvider,
   820  				BuildRegistry:    &container.BuildRegistry{},
   821  				ChaincodeBuilder: &mock.ChaincodeBuilder{},
   822  			}
   823  			stub = shimtest.NewMockStub("lscc", scc)
   824  			res := stub.MockInit("1", nil)
   825  			assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   826  			scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy")
   827  		}
   828  
   829  		cds, err := constructDeploymentSpec(ccname, path, version, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc)
   830  		assert.NoError(t, err)
   831  		cdsBytes := protoutil.MarshalOrPanic(cds)
   832  
   833  		sProp, _ := protoutil.MockSignedEndorserProposal2OrPanic(channelID, &pb.ChaincodeSpec{}, id)
   834  		args := [][]byte{[]byte("deploy"), []byte("test"), cdsBytes}
   835  		saved1 := scc.Support.(*MockSupport).GetInstantiationPolicyErr
   836  		saved2 := scc.Support.(*MockSupport).CheckInstantiationPolicyMap
   837  		scc.Support.(*MockSupport).GetInstantiationPolicyErr = nil
   838  		scc.Support.(*MockSupport).CheckInstantiationPolicyMap = nil
   839  		res := stub.MockInvokeWithSignedProposal("1", args, sProp)
   840  		assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   841  		scc.Support.(*MockSupport).GetInstantiationPolicyErr = saved1
   842  		scc.Support.(*MockSupport).CheckInstantiationPolicyMap = saved2
   843  
   844  		newCds, err := constructDeploymentSpec(newccname, path, newversion, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc)
   845  		assert.NoError(t, err)
   846  		newCdsBytes := protoutil.MarshalOrPanic(newCds)
   847  
   848  		if len(collectionConfigBytes) > 0 {
   849  			if bytes.Equal(collectionConfigBytes, []byte("nil")) {
   850  				args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes, nil, []byte("escc"), []byte("vscc"), nil}
   851  			} else {
   852  				args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes, nil, []byte("escc"), []byte("vscc"), collectionConfigBytes}
   853  			}
   854  		} else {
   855  			args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes}
   856  		}
   857  
   858  		res = stub.MockInvokeWithSignedProposal("1", args, sProp)
   859  		if expectedErrorMsg == "" {
   860  			assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   861  
   862  			cd := &ccprovider.ChaincodeData{}
   863  			err = proto.Unmarshal(res.Payload, cd)
   864  			assert.NoError(t, err)
   865  
   866  			newVer := cd.Version
   867  
   868  			expectVer := "1"
   869  			assert.Equal(t, newVer, expectVer, fmt.Sprintf("Upgrade chaincode version error, expected %s, got %s", expectVer, newVer))
   870  
   871  			chaincodeEvent := <-stub.ChaincodeEventsChannel
   872  			assert.Equal(t, "upgrade", chaincodeEvent.EventName)
   873  			lifecycleEvent := &pb.LifecycleEvent{}
   874  			err = proto.Unmarshal(chaincodeEvent.Payload, lifecycleEvent)
   875  			assert.NoError(t, err)
   876  			assert.Equal(t, newccname, lifecycleEvent.ChaincodeName)
   877  		} else {
   878  			assert.Equal(t, expectedErrorMsg, string(res.Message))
   879  		}
   880  	})
   881  }
   882  
   883  func TestFunctionsWithAliases(t *testing.T) {
   884  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   885  	assert.NoError(t, err)
   886  	scc := &SCC{
   887  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   888  		Support:          &MockSupport{},
   889  		ACLProvider:      mockAclProvider,
   890  		GetMSPIDs:        getMSPIDs,
   891  		BCCSP:            cryptoProvider,
   892  		BuildRegistry:    &container.BuildRegistry{},
   893  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   894  	}
   895  	stub := shimtest.NewMockStub("lscc", scc)
   896  	res := stub.MockInit("1", nil)
   897  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   898  
   899  	identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")}
   900  	policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{
   901  		Managers: map[string]policies.Manager{
   902  			"test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}},
   903  		},
   904  	}
   905  	scc.PolicyChecker = policy.NewPolicyChecker(
   906  		policyManagerGetter,
   907  		identityDeserializer,
   908  		&policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   909  	)
   910  	sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
   911  	identityDeserializer.Msg = sProp.ProposalBytes
   912  	sProp.Signature = sProp.ProposalBytes
   913  
   914  	testInvoke := func(function, resource string) {
   915  		t.Run(function, func(t *testing.T) {
   916  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1")}, nil)
   917  			assert.NotEqual(t, int32(shim.OK), res.Status)
   918  			assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message)
   919  
   920  			mockAclProvider.Reset()
   921  			mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(errors.New("bonanza"))
   922  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("chaincode")}, sProp)
   923  			assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
   924  			assert.Equal(t, fmt.Sprintf("access denied for [%s][testchannel1]: bonanza", function), res.Message)
   925  
   926  			mockAclProvider.Reset()
   927  			mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(nil)
   928  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("nonexistentchaincode")}, sProp)
   929  			assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
   930  			assert.Equal(t, res.Message, "could not find chaincode with name 'nonexistentchaincode'")
   931  		})
   932  	}
   933  
   934  	testInvoke("getid", "lscc/ChaincodeExists")
   935  	testInvoke("ChaincodeExists", "lscc/ChaincodeExists")
   936  	testInvoke("getdepspec", "lscc/GetDeploymentSpec")
   937  	testInvoke("GetDeploymentSpec", "lscc/GetDeploymentSpec")
   938  	testInvoke("getccdata", "lscc/GetChaincodeData")
   939  	testInvoke("GetChaincodeData", "lscc/GetChaincodeData")
   940  }
   941  
   942  func TestGetChaincodes(t *testing.T) {
   943  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   944  	assert.NoError(t, err)
   945  	scc := &SCC{
   946  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   947  		Support:          &MockSupport{},
   948  		ACLProvider:      mockAclProvider,
   949  		GetMSPIDs:        getMSPIDs,
   950  		BCCSP:            cryptoProvider,
   951  		BuildRegistry:    &container.BuildRegistry{},
   952  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   953  	}
   954  	stub := shimtest.NewMockStub("lscc", scc)
   955  	stub.ChannelID = "test"
   956  	res := stub.MockInit("1", nil)
   957  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   958  
   959  	for _, function := range []string{"getchaincodes", "GetChaincodes"} {
   960  		t.Run(function, func(t *testing.T) {
   961  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("barf")}, nil)
   962  			assert.NotEqual(t, int32(shim.OK), res.Status)
   963  			assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message)
   964  
   965  			sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("test", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
   966  			sProp.Signature = sProp.ProposalBytes
   967  
   968  			mockAclProvider.Reset()
   969  			mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(errors.New("coyote"))
   970  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
   971  			assert.NotEqual(t, int32(shim.OK), res.Status)
   972  			assert.Regexp(t, `access denied for \[`+function+`\]\[test\](.*)coyote`, res.Message)
   973  
   974  			mockAclProvider.Reset()
   975  			mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(nil)
   976  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
   977  			assert.Equal(t, int32(shim.OK), res.Status, res.Message)
   978  		})
   979  	}
   980  }
   981  
   982  func TestGetChaincodesFilter(t *testing.T) {
   983  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   984  	assert.NoError(t, err)
   985  	scc := &SCC{
   986  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
   987  		Support:          &MockSupport{GetChaincodeFromLocalStorageErr: errors.New("banana")},
   988  		ACLProvider:      mockAclProvider,
   989  		GetMSPIDs:        getMSPIDs,
   990  		BCCSP:            cryptoProvider,
   991  		BuildRegistry:    &container.BuildRegistry{},
   992  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
   993  	}
   994  
   995  	sqi := &mock.StateQueryIterator{}
   996  	results := []*queryresult.KV{
   997  		{Key: "one", Value: protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "name-one", Version: "1.0", Escc: "escc", Vscc: "vscc"})},
   998  		{Key: "something~collections", Value: []byte("completely-ignored")},
   999  		{Key: "two", Value: protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "name-two", Version: "2.0", Escc: "escc-2", Vscc: "vscc-2"})},
  1000  	}
  1001  	for i, r := range results {
  1002  		sqi.NextReturnsOnCall(i, r, nil)
  1003  		sqi.HasNextReturnsOnCall(i, true)
  1004  	}
  1005  
  1006  	stub := &mock.ChaincodeStub{}
  1007  	stub.GetStateByRangeReturns(sqi, nil)
  1008  
  1009  	resp := scc.getChaincodes(stub)
  1010  	assert.Equal(t, resp.Status, int32(shim.OK))
  1011  
  1012  	cqr := &pb.ChaincodeQueryResponse{}
  1013  	err = proto.Unmarshal(resp.GetPayload(), cqr)
  1014  	assert.NoError(t, err)
  1015  
  1016  	assert.Equal(t, cqr.Chaincodes, []*pb.ChaincodeInfo{
  1017  		{Name: "name-one", Version: "1.0", Escc: "escc", Vscc: "vscc"},
  1018  		{Name: "name-two", Version: "2.0", Escc: "escc-2", Vscc: "vscc-2"},
  1019  	})
  1020  }
  1021  
  1022  func TestGetInstalledChaincodes(t *testing.T) {
  1023  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1024  	assert.NoError(t, err)
  1025  	scc := &SCC{
  1026  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
  1027  		Support:          &MockSupport{},
  1028  		ACLProvider:      mockAclProvider,
  1029  		GetMSPIDs:        getMSPIDs,
  1030  		BCCSP:            cryptoProvider,
  1031  		BuildRegistry:    &container.BuildRegistry{},
  1032  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
  1033  	}
  1034  	stub := shimtest.NewMockStub("lscc", scc)
  1035  	res := stub.MockInit("1", nil)
  1036  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1037  
  1038  	for _, function := range []string{"getinstalledchaincodes", "GetInstalledChaincodes"} {
  1039  		t.Run(function, func(t *testing.T) {
  1040  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("barf")}, nil)
  1041  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1042  			assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message)
  1043  
  1044  			identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")}
  1045  			policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{
  1046  				Managers: map[string]policies.Manager{
  1047  					"test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}},
  1048  				},
  1049  			}
  1050  			scc.PolicyChecker = policy.NewPolicyChecker(
  1051  				policyManagerGetter,
  1052  				identityDeserializer,
  1053  				&policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
  1054  			)
  1055  			sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
  1056  			identityDeserializer.Msg = sProp.ProposalBytes
  1057  			sProp.Signature = sProp.ProposalBytes
  1058  
  1059  			mockAclProvider.Reset()
  1060  			mockAclProvider.On("CheckACL", resources.Lscc_GetInstalledChaincodes, "", sProp).Return(errors.New("authorization failure"))
  1061  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
  1062  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1063  			assert.Contains(t, res.Message, "access denied for ["+function+"]")
  1064  
  1065  			sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
  1066  			identityDeserializer.Msg = sProp.ProposalBytes
  1067  			sProp.Signature = sProp.ProposalBytes
  1068  
  1069  			mockAclProvider.Reset()
  1070  			mockAclProvider.On("CheckACL", resources.Lscc_GetInstalledChaincodes, "", sProp).Return(nil)
  1071  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
  1072  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1073  			assert.Equal(t, "proto: Marshal called with nil", res.Message)
  1074  
  1075  			_, err := constructDeploymentSpec("ccname-"+function, "path", "version", [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, false, scc)
  1076  			assert.NoError(t, err)
  1077  
  1078  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
  1079  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1080  			assert.Equal(t, "barf", res.Message)
  1081  
  1082  			_, err = constructDeploymentSpec("ccname-"+function, "path", "version", [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc)
  1083  			assert.NoError(t, err)
  1084  
  1085  			res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
  1086  			assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1087  
  1088  			scc.Support = &MockSupport{}
  1089  		})
  1090  	}
  1091  }
  1092  
  1093  func TestNewLifeCycleSysCC(t *testing.T) {
  1094  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1095  	assert.NoError(t, err)
  1096  	scc := &SCC{
  1097  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
  1098  		Support:          &SupportImpl{GetMSPIDs: getMSPIDs},
  1099  		ACLProvider:      mockAclProvider,
  1100  		GetMSPIDs:        getMSPIDs,
  1101  		BCCSP:            cryptoProvider,
  1102  		BuildRegistry:    &container.BuildRegistry{},
  1103  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
  1104  	}
  1105  	assert.NotNil(t, scc)
  1106  	stub := shimtest.NewMockStub("lscc", scc)
  1107  	res := stub.MockInit("1", nil)
  1108  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1109  
  1110  	res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("barf")}, nil)
  1111  	assert.NotEqual(t, int32(shim.OK), res.Status)
  1112  	assert.Equal(t, "invalid function to lscc: barf", res.Message)
  1113  }
  1114  
  1115  func TestGetChaincodeData(t *testing.T) {
  1116  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1117  	assert.NoError(t, err)
  1118  	scc := &SCC{
  1119  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
  1120  		Support:          &SupportImpl{GetMSPIDs: getMSPIDs},
  1121  		ACLProvider:      mockAclProvider,
  1122  		GetMSPIDs:        getMSPIDs,
  1123  		BCCSP:            cryptoProvider,
  1124  		BuildRegistry:    &container.BuildRegistry{},
  1125  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
  1126  	}
  1127  	assert.NotNil(t, scc)
  1128  	stub := shimtest.NewMockStub("lscc", scc)
  1129  	res := stub.MockInit("1", nil)
  1130  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1131  
  1132  	_, err = scc.getChaincodeData("barf", []byte("barf"))
  1133  	assert.Error(t, err)
  1134  
  1135  	_, err = scc.getChaincodeData("barf", protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "barf s'more"}))
  1136  	assert.Error(t, err)
  1137  	assert.True(t, len(err.Error()) > 0)
  1138  }
  1139  
  1140  func TestExecuteInstall(t *testing.T) {
  1141  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1142  	assert.NoError(t, err)
  1143  	scc := &SCC{
  1144  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
  1145  		Support:          &SupportImpl{GetMSPIDs: getMSPIDs},
  1146  		ACLProvider:      mockAclProvider,
  1147  		GetMSPIDs:        getMSPIDs,
  1148  		BCCSP:            cryptoProvider,
  1149  		BuildRegistry:    &container.BuildRegistry{},
  1150  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
  1151  	}
  1152  	assert.NotNil(t, scc)
  1153  	stub := shimtest.NewMockStub("lscc", scc)
  1154  	res := stub.MockInit("1", nil)
  1155  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1156  
  1157  	err = scc.executeInstall(stub, []byte("barf"))
  1158  	assert.Error(t, err)
  1159  }
  1160  
  1161  func TestErrors(t *testing.T) {
  1162  	// these errors are really hard (if
  1163  	// outright impossible without writing
  1164  	// tons of lines of mocking code) to
  1165  	// get in testing
  1166  	err1 := TXNotFoundErr("")
  1167  	assert.True(t, len(err1.Error()) > 0)
  1168  
  1169  	err3 := MarshallErr("")
  1170  	assert.True(t, len(err3.Error()) > 0)
  1171  }
  1172  
  1173  func TestPutChaincodeCollectionData(t *testing.T) {
  1174  	scc := &SCC{
  1175  		Support: &MockSupport{},
  1176  	}
  1177  	stub := shimtest.NewMockStub("lscc", scc)
  1178  
  1179  	if res := stub.MockInit("1", nil); res.Status != shim.OK {
  1180  		fmt.Println("Init failed", string(res.Message))
  1181  		t.FailNow()
  1182  	}
  1183  
  1184  	err := scc.putChaincodeCollectionData(stub, nil, nil)
  1185  	assert.Error(t, err)
  1186  
  1187  	cd := &ccprovider.ChaincodeData{Name: "foo"}
  1188  
  1189  	err = scc.putChaincodeCollectionData(stub, cd, nil)
  1190  	assert.NoError(t, err)
  1191  
  1192  	collName1 := "mycollection1"
  1193  	coll1 := createCollectionConfig(collName1, testPolicyEnvelope, 1, 2)
  1194  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}}
  1195  	ccpBytes, err := proto.Marshal(ccp)
  1196  	assert.NoError(t, err)
  1197  	assert.NotNil(t, ccpBytes)
  1198  
  1199  	stub.MockTransactionStart("foo")
  1200  	err = scc.putChaincodeCollectionData(stub, cd, []byte("barf"))
  1201  	assert.Error(t, err)
  1202  	stub.MockTransactionEnd("foo")
  1203  
  1204  	stub.MockTransactionStart("foo")
  1205  	err = scc.putChaincodeCollectionData(stub, cd, ccpBytes)
  1206  	assert.NoError(t, err)
  1207  	stub.MockTransactionEnd("foo")
  1208  }
  1209  
  1210  func TestGetChaincodeCollectionData(t *testing.T) {
  1211  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1212  	assert.NoError(t, err)
  1213  	scc := &SCC{
  1214  		BuiltinSCCs:      map[string]struct{}{"lscc": {}},
  1215  		Support:          &SupportImpl{GetMSPIDs: getMSPIDs},
  1216  		ACLProvider:      mockAclProvider,
  1217  		GetMSPIDs:        getMSPIDs,
  1218  		BCCSP:            cryptoProvider,
  1219  		BuildRegistry:    &container.BuildRegistry{},
  1220  		ChaincodeBuilder: &mock.ChaincodeBuilder{},
  1221  	}
  1222  	stub := shimtest.NewMockStub("lscc", scc)
  1223  	stub.ChannelID = "test"
  1224  	scc.Support = &MockSupport{}
  1225  
  1226  	cd := &ccprovider.ChaincodeData{Name: "foo"}
  1227  
  1228  	collName1 := "mycollection1"
  1229  	coll1 := createCollectionConfig(collName1, testPolicyEnvelope, 1, 2)
  1230  	ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}}
  1231  	ccpBytes, err := proto.Marshal(ccp)
  1232  	assert.NoError(t, err)
  1233  	assert.NotNil(t, ccpBytes)
  1234  
  1235  	stub.MockTransactionStart("foo")
  1236  	err = scc.putChaincodeCollectionData(stub, cd, ccpBytes)
  1237  	assert.NoError(t, err)
  1238  	stub.MockTransactionEnd("foo")
  1239  
  1240  	res := stub.MockInit("1", nil)
  1241  	assert.Equal(t, int32(shim.OK), res.Status, res.Message)
  1242  
  1243  	for _, function := range []string{"GetCollectionsConfig", "getcollectionsconfig"} {
  1244  		sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("test", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
  1245  		sProp.Signature = sProp.ProposalBytes
  1246  
  1247  		t.Run("invalid number of arguments", func(t *testing.T) {
  1248  			res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo", "bar"), nil)
  1249  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1250  			assert.Equal(t, "invalid number of arguments to lscc: 3", res.Message)
  1251  		})
  1252  		t.Run("invalid identity", func(t *testing.T) {
  1253  			mockAclProvider.Reset()
  1254  			mockAclProvider.On("CheckACL", resources.Lscc_GetCollectionsConfig, "test", sProp).Return(errors.New("acl check failed"))
  1255  			res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo"), sProp)
  1256  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1257  			assert.Contains(t, res.Message, "access denied for ["+function+"]")
  1258  		})
  1259  		t.Run("non-exists collections config", func(t *testing.T) {
  1260  			mockAclProvider.Reset()
  1261  			mockAclProvider.On("CheckACL", resources.Lscc_GetCollectionsConfig, "test", sProp).Return(nil)
  1262  			res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "bar"), sProp)
  1263  			assert.NotEqual(t, int32(shim.OK), res.Status)
  1264  			assert.Equal(t, res.Message, "collections config not defined for chaincode bar")
  1265  		})
  1266  		t.Run("Success", func(t *testing.T) {
  1267  			res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo"), sProp)
  1268  			assert.Equal(t, int32(shim.OK), res.Status)
  1269  			assert.NotNil(t, res.Payload)
  1270  		})
  1271  	}
  1272  }
  1273  
  1274  func TestCheckCollectionMemberPolicy(t *testing.T) {
  1275  	// error case: no msp manager set, no collection config set
  1276  	err := checkCollectionMemberPolicy(nil, nil)
  1277  	assert.Error(t, err)
  1278  
  1279  	mockmsp := new(mspmocks.MockMSP)
  1280  	mockmsp.On("DeserializeIdentity", []byte("signer0")).Return(&mspmocks.MockIdentity{}, nil)
  1281  	mockmsp.On("DeserializeIdentity", []byte("signer1")).Return(&mspmocks.MockIdentity{}, nil)
  1282  	mockmsp.On("GetIdentifier").Return("Org1", nil)
  1283  	mockmsp.On("GetType").Return(msp.FABRIC)
  1284  	mspmgmt.GetManagerForChain("foochannel")
  1285  	mgr := mspmgmt.GetManagerForChain("foochannel")
  1286  
  1287  	// error case: msp manager not set up, no collection config set
  1288  	err = checkCollectionMemberPolicy(nil, nil)
  1289  	assert.EqualError(t, err, "msp manager not set")
  1290  
  1291  	// set up msp manager
  1292  	mgr.Setup([]msp.MSP{mockmsp})
  1293  
  1294  	// error case: no collection config set
  1295  	err = checkCollectionMemberPolicy(nil, mgr)
  1296  	assert.EqualError(t, err, "collection configuration is not set")
  1297  
  1298  	// error case: empty collection config
  1299  	cc := &peer.CollectionConfig{}
  1300  	err = checkCollectionMemberPolicy(cc, mgr)
  1301  	assert.EqualError(t, err, "collection configuration is empty")
  1302  
  1303  	// error case: no static collection config
  1304  	cc = &peer.CollectionConfig{Payload: &peer.CollectionConfig_StaticCollectionConfig{}}
  1305  	err = checkCollectionMemberPolicy(cc, mgr)
  1306  	assert.EqualError(t, err, "collection configuration is empty")
  1307  
  1308  	// error case: member org policy not set
  1309  	cc = &peer.CollectionConfig{
  1310  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1311  			StaticCollectionConfig: &peer.StaticCollectionConfig{},
  1312  		},
  1313  	}
  1314  	err = checkCollectionMemberPolicy(cc, mgr)
  1315  	assert.EqualError(t, err, "collection member policy is not set")
  1316  
  1317  	// error case: member org policy config empty
  1318  	cc = &peer.CollectionConfig{
  1319  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1320  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1321  				Name: "mycollection",
  1322  				MemberOrgsPolicy: &peer.CollectionPolicyConfig{
  1323  					Payload: &peer.CollectionPolicyConfig_SignaturePolicy{},
  1324  				},
  1325  			},
  1326  		},
  1327  	}
  1328  	err = checkCollectionMemberPolicy(cc, mgr)
  1329  	assert.EqualError(t, err, "collection member org policy is empty")
  1330  
  1331  	// error case: signd-by index is out of range of signers
  1332  	cc = &peer.CollectionConfig{
  1333  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1334  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1335  				Name:             "mycollection",
  1336  				MemberOrgsPolicy: getBadAccessPolicy([]string{"signer0"}, 1),
  1337  			},
  1338  		},
  1339  	}
  1340  	err = checkCollectionMemberPolicy(cc, mgr)
  1341  	assert.EqualError(t, err, "invalid member org policy for collection 'mycollection': identity index out of range, requested 1, but identities length is 1")
  1342  
  1343  	// valid case: well-formed collection policy config
  1344  	cc = &peer.CollectionConfig{
  1345  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1346  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1347  				Name: "mycollection",
  1348  				MemberOrgsPolicy: &peer.CollectionPolicyConfig{
  1349  					Payload: &peer.CollectionPolicyConfig_SignaturePolicy{
  1350  						SignaturePolicy: testPolicyEnvelope,
  1351  					},
  1352  				},
  1353  			},
  1354  		},
  1355  	}
  1356  	err = checkCollectionMemberPolicy(cc, mgr)
  1357  	assert.NoError(t, err)
  1358  
  1359  	// check MSPPrincipal_IDENTITY type
  1360  	var signers = [][]byte{[]byte("signer0"), []byte("signer1")}
  1361  	signaturePolicyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers)
  1362  	signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{
  1363  		SignaturePolicy: signaturePolicyEnvelope,
  1364  	}
  1365  	accessPolicy := &peer.CollectionPolicyConfig{
  1366  		Payload: signaturePolicy,
  1367  	}
  1368  	cc = &peer.CollectionConfig{
  1369  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1370  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1371  				Name:             "mycollection",
  1372  				MemberOrgsPolicy: accessPolicy,
  1373  			},
  1374  		},
  1375  	}
  1376  	err = checkCollectionMemberPolicy(cc, mgr)
  1377  	assert.NoError(t, err)
  1378  	mockmsp.AssertNumberOfCalls(t, "DeserializeIdentity", 3)
  1379  
  1380  	// check MSPPrincipal_ROLE type
  1381  	signaturePolicyEnvelope = policydsl.SignedByAnyMember([]string{"Org1"})
  1382  	signaturePolicy.SignaturePolicy = signaturePolicyEnvelope
  1383  	accessPolicy.Payload = signaturePolicy
  1384  	cc = &peer.CollectionConfig{
  1385  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1386  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1387  				Name:             "mycollection",
  1388  				MemberOrgsPolicy: accessPolicy,
  1389  			},
  1390  		},
  1391  	}
  1392  	err = checkCollectionMemberPolicy(cc, mgr)
  1393  	assert.NoError(t, err)
  1394  
  1395  	// check MSPPrincipal_ROLE type for unknown org
  1396  	signaturePolicyEnvelope = policydsl.SignedByAnyMember([]string{"Org2"})
  1397  	signaturePolicy.SignaturePolicy = signaturePolicyEnvelope
  1398  	accessPolicy.Payload = signaturePolicy
  1399  	cc = &peer.CollectionConfig{
  1400  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1401  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1402  				Name:             "mycollection",
  1403  				MemberOrgsPolicy: accessPolicy,
  1404  			},
  1405  		},
  1406  	}
  1407  	err = checkCollectionMemberPolicy(cc, mgr)
  1408  	// this does not raise an error but prints a warning logging message instead
  1409  	assert.NoError(t, err)
  1410  
  1411  	// check MSPPrincipal_ORGANIZATION_UNIT type
  1412  	principal := &mb.MSPPrincipal{
  1413  		PrincipalClassification: mb.MSPPrincipal_ORGANIZATION_UNIT,
  1414  		Principal:               protoutil.MarshalOrPanic(&mb.OrganizationUnit{MspIdentifier: "Org1"}),
  1415  	}
  1416  	// create the policy: it requires exactly 1 signature from the first (and only) principal
  1417  	signaturePolicy.SignaturePolicy = &common.SignaturePolicyEnvelope{
  1418  		Version:    0,
  1419  		Rule:       policydsl.NOutOf(1, []*common.SignaturePolicy{policydsl.SignedBy(0)}),
  1420  		Identities: []*mb.MSPPrincipal{principal},
  1421  	}
  1422  	accessPolicy.Payload = signaturePolicy
  1423  	cc = &peer.CollectionConfig{
  1424  		Payload: &peer.CollectionConfig_StaticCollectionConfig{
  1425  			StaticCollectionConfig: &peer.StaticCollectionConfig{
  1426  				Name:             "mycollection",
  1427  				MemberOrgsPolicy: accessPolicy,
  1428  			},
  1429  		},
  1430  	}
  1431  	err = checkCollectionMemberPolicy(cc, mgr)
  1432  	assert.NoError(t, err)
  1433  }
  1434  
  1435  func TestCheckChaincodeName(t *testing.T) {
  1436  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1437  	assert.NoError(t, err)
  1438  
  1439  	lscc := &SCC{BCCSP: cryptoProvider}
  1440  
  1441  	/*allowed naming*/
  1442  	err = lscc.isValidChaincodeName("a-b")
  1443  	assert.NoError(t, err)
  1444  	err = lscc.isValidChaincodeName("a_b")
  1445  	assert.NoError(t, err)
  1446  	err = lscc.isValidChaincodeName("a_b-c")
  1447  	assert.NoError(t, err)
  1448  	err = lscc.isValidChaincodeName("a-b_c")
  1449  	assert.NoError(t, err)
  1450  
  1451  	/*invalid naming*/
  1452  	err = lscc.isValidChaincodeName("")
  1453  	assert.EqualError(t, err, "invalid chaincode name ''. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1454  	err = lscc.isValidChaincodeName("-ab")
  1455  	assert.EqualError(t, err, "invalid chaincode name '-ab'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1456  	err = lscc.isValidChaincodeName("_ab")
  1457  	assert.EqualError(t, err, "invalid chaincode name '_ab'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1458  	err = lscc.isValidChaincodeName("ab-")
  1459  	assert.EqualError(t, err, "invalid chaincode name 'ab-'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1460  	err = lscc.isValidChaincodeName("ab_")
  1461  	assert.EqualError(t, err, "invalid chaincode name 'ab_'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1462  	err = lscc.isValidChaincodeName("a__b")
  1463  	assert.EqualError(t, err, "invalid chaincode name 'a__b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1464  	err = lscc.isValidChaincodeName("a--b")
  1465  	assert.EqualError(t, err, "invalid chaincode name 'a--b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1466  	err = lscc.isValidChaincodeName("a-_b")
  1467  	assert.EqualError(t, err, "invalid chaincode name 'a-_b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'")
  1468  }
  1469  
  1470  func TestCheckChaincodeVersion(t *testing.T) {
  1471  	lscc := &SCC{}
  1472  
  1473  	validCCName := "ccname"
  1474  	/*allowed versions*/
  1475  	err := lscc.isValidChaincodeVersion(validCCName, "a_b")
  1476  	assert.NoError(t, err)
  1477  	err = lscc.isValidChaincodeVersion(validCCName, "a.b")
  1478  	assert.NoError(t, err)
  1479  	err = lscc.isValidChaincodeVersion(validCCName, "a+b")
  1480  	assert.NoError(t, err)
  1481  	err = lscc.isValidChaincodeVersion(validCCName, "a-b")
  1482  	assert.NoError(t, err)
  1483  	err = lscc.isValidChaincodeVersion(validCCName, "-ab")
  1484  	assert.NoError(t, err)
  1485  	err = lscc.isValidChaincodeVersion(validCCName, "a.0")
  1486  	assert.NoError(t, err)
  1487  	err = lscc.isValidChaincodeVersion(validCCName, "a_b.c+d-e")
  1488  	assert.NoError(t, err)
  1489  	err = lscc.isValidChaincodeVersion(validCCName, "0")
  1490  	assert.NoError(t, err)
  1491  
  1492  	/*invalid versions*/
  1493  	err = lscc.isValidChaincodeVersion(validCCName, "")
  1494  	assert.EqualError(t, err, "invalid chaincode version ''. Versions must not be empty and can only consist of alphanumerics, '_',  '-', '+', and '.'")
  1495  	err = lscc.isValidChaincodeVersion(validCCName, "$badversion")
  1496  	assert.EqualError(t, err, "invalid chaincode version '$badversion'. Versions must not be empty and can only consist of alphanumerics, '_',  '-', '+', and '.'")
  1497  }
  1498  
  1499  func TestLifecycleChaincodeRegularExpressionsMatch(t *testing.T) {
  1500  	assert.Equal(t, ChaincodeNameRegExp.String(), lifecycle.ChaincodeNameRegExp.String())
  1501  	assert.Equal(t, ChaincodeVersionRegExp.String(), lifecycle.ChaincodeVersionRegExp.String())
  1502  }
  1503  
  1504  var id msp.SigningIdentity
  1505  var channelID = "testchannelid"
  1506  var mockAclProvider *mocks.MockACLProvider
  1507  
  1508  func NewMockProvider() sysccprovider.SystemChaincodeProvider {
  1509  	capabilities := &mock.ApplicationCapabilities{}
  1510  	application := &mock.Application{}
  1511  	application.CapabilitiesReturns(capabilities)
  1512  	sccProvider := &mock.SystemChaincodeProvider{}
  1513  	sccProvider.GetApplicationConfigReturns(application, true)
  1514  	return sccProvider
  1515  }
  1516  
  1517  func TestMain(m *testing.M) {
  1518  	var err error
  1519  	msptesttools.LoadMSPSetupForTesting()
  1520  
  1521  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1522  	if err != nil {
  1523  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
  1524  		os.Exit(-1)
  1525  	}
  1526  
  1527  	id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
  1528  	if err != nil {
  1529  		fmt.Printf("GetSigningIdentity failed with err %s", err)
  1530  		os.Exit(-1)
  1531  	}
  1532  
  1533  	mockAclProvider = &mocks.MockACLProvider{}
  1534  	mockAclProvider.Reset()
  1535  
  1536  	os.Exit(m.Run())
  1537  }
  1538  
  1539  type MockSupport struct {
  1540  	PutChaincodeToLocalStorageErr    error
  1541  	GetChaincodeFromLocalStorageRv   ccprovider.CCPackage
  1542  	GetChaincodeFromLocalStorageErr  error
  1543  	GetChaincodesFromLocalStorageRv  *peer.ChaincodeQueryResponse
  1544  	GetChaincodesFromLocalStorageErr error
  1545  	GetInstantiationPolicyRv         []byte
  1546  	GetInstantiationPolicyErr        error
  1547  	CheckInstantiationPolicyErr      error
  1548  	GetInstantiationPolicyMap        map[string][]byte
  1549  	CheckInstantiationPolicyMap      map[string]error
  1550  	CheckCollectionConfigErr         error
  1551  }
  1552  
  1553  func (s *MockSupport) PutChaincodeToLocalStorage(ccpack ccprovider.CCPackage) error {
  1554  	return s.PutChaincodeToLocalStorageErr
  1555  }
  1556  
  1557  func (s *MockSupport) GetChaincodeFromLocalStorage(ccNameVersion string) (ccprovider.CCPackage, error) {
  1558  	return s.GetChaincodeFromLocalStorageRv, s.GetChaincodeFromLocalStorageErr
  1559  }
  1560  
  1561  func (s *MockSupport) GetChaincodesFromLocalStorage() (*peer.ChaincodeQueryResponse, error) {
  1562  	return s.GetChaincodesFromLocalStorageRv, s.GetChaincodesFromLocalStorageErr
  1563  }
  1564  
  1565  func (s *MockSupport) GetInstantiationPolicy(channel string, ccpack ccprovider.CCPackage) ([]byte, error) {
  1566  	if s.GetInstantiationPolicyMap != nil {
  1567  		str := ccpack.GetChaincodeData().Name + ccpack.GetChaincodeData().Version
  1568  		s.GetInstantiationPolicyMap[str] = []byte(str)
  1569  		return []byte(ccpack.GetChaincodeData().Name + ccpack.GetChaincodeData().Version), nil
  1570  	}
  1571  	return s.GetInstantiationPolicyRv, s.GetInstantiationPolicyErr
  1572  }
  1573  
  1574  func (s *MockSupport) CheckInstantiationPolicy(signedProp *peer.SignedProposal, chainName string, instantiationPolicy []byte) error {
  1575  	if s.CheckInstantiationPolicyMap != nil {
  1576  		return s.CheckInstantiationPolicyMap[string(instantiationPolicy)]
  1577  	}
  1578  	return s.CheckInstantiationPolicyErr
  1579  }
  1580  
  1581  func (s *MockSupport) CheckCollectionConfig(collectionConfig *peer.CollectionConfig, channelName string) error {
  1582  	return s.CheckCollectionConfigErr
  1583  }
  1584  
  1585  // getBadAccessPolicy creates a bad CollectionPolicyConfig with signedby index out of range of signers
  1586  func getBadAccessPolicy(signers []string, badIndex int32) *peer.CollectionPolicyConfig {
  1587  	var data [][]byte
  1588  	for _, signer := range signers {
  1589  		data = append(data, []byte(signer))
  1590  	}
  1591  	// use a out of range index to trigger error
  1592  	policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(badIndex)), data)
  1593  	return &peer.CollectionPolicyConfig{
  1594  		Payload: &peer.CollectionPolicyConfig_SignaturePolicy{
  1595  			SignaturePolicy: policyEnvelope,
  1596  		},
  1597  	}
  1598  }