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