github.com/true-sqn/fabric@v2.1.1+incompatible/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/hyperledger/fabric/bccsp/sw" 28 "github.com/hyperledger/fabric/common/channelconfig" 29 "github.com/hyperledger/fabric/common/policies" 30 "github.com/hyperledger/fabric/common/policydsl" 31 "github.com/hyperledger/fabric/common/util" 32 "github.com/hyperledger/fabric/core/aclmgmt/mocks" 33 "github.com/hyperledger/fabric/core/aclmgmt/resources" 34 "github.com/hyperledger/fabric/core/chaincode/lifecycle" 35 "github.com/hyperledger/fabric/core/common/ccprovider" 36 "github.com/hyperledger/fabric/core/common/sysccprovider" 37 "github.com/hyperledger/fabric/core/container" 38 "github.com/hyperledger/fabric/core/container/externalbuilder" 39 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 40 "github.com/hyperledger/fabric/core/ledger/ledgermgmt/ledgermgmttest" 41 "github.com/hyperledger/fabric/core/policy" 42 policymocks "github.com/hyperledger/fabric/core/policy/mocks" 43 "github.com/hyperledger/fabric/core/scc/lscc/mock" 44 "github.com/hyperledger/fabric/msp" 45 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 46 msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools" 47 mspmocks "github.com/hyperledger/fabric/msp/mocks" 48 "github.com/hyperledger/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 errMessage := InvalidArgsLenErr(7).Error() 397 testDeploy(t, "example02", "1.0", path, false, false, true, PrivateChannelDataNotAvailable("").Error(), scc, stub, []byte("collections")) 398 399 // Enable PrivateChannelData 400 capabilities := &mock.ApplicationCapabilities{} 401 capabilities.PrivateChannelDataReturns(true) 402 application := &mock.Application{} 403 application.CapabilitiesReturns(capabilities) 404 sccProvider := &mock.SystemChaincodeProvider{} 405 sccProvider.GetApplicationConfigReturns(application, true) 406 407 scc = &SCC{ 408 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 409 Support: &MockSupport{}, 410 SCCProvider: sccProvider, 411 ACLProvider: mockAclProvider, 412 GetMSPIDs: getMSPIDs, 413 BCCSP: cryptoProvider, 414 BuildRegistry: &container.BuildRegistry{}, 415 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 416 } 417 stub = shimtest.NewMockStub("lscc", scc) 418 res = stub.MockInit("1", nil) 419 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 420 421 // As the PrivateChannelData is enabled and collectionConfigBytes is invalid, the following error 422 // message is expected. 423 errMessage = "invalid collection configuration supplied for chaincode example02:1.0" 424 testDeploy(t, "example02", "1.0", path, false, false, true, errMessage, scc, stub, []byte("invalid collection")) 425 // Should contain an entry for the chaincodeData only 426 assert.Equal(t, 1, len(stub.State)) 427 _, ok := stub.State["example02"] 428 assert.Equal(t, true, ok) 429 430 collName1 := "mycollection1" 431 policyEnvelope := policydsl.SignedByAnyMember([]string{"SampleOrg"}) 432 var requiredPeerCount, maximumPeerCount int32 433 requiredPeerCount = 1 434 maximumPeerCount = 2 435 coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount) 436 437 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}} 438 ccpBytes, err := proto.Marshal(ccp) 439 assert.NoError(t, err) 440 assert.NotNil(t, ccpBytes) 441 442 scc = &SCC{ 443 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 444 Support: &MockSupport{}, 445 SCCProvider: sccProvider, 446 ACLProvider: mockAclProvider, 447 GetMSPIDs: getMSPIDs, 448 BCCSP: cryptoProvider, 449 BuildRegistry: &container.BuildRegistry{}, 450 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 451 } 452 stub = shimtest.NewMockStub("lscc", scc) 453 res = stub.MockInit("1", nil) 454 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 455 456 // As the PrivateChannelData is enabled and collectionConfigBytes is valid, no error is expected 457 testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, ccpBytes) 458 // Should contain two entries: one for the chaincodeData and another for the collectionConfigBytes 459 assert.Equal(t, 2, len(stub.State)) 460 _, ok = stub.State["example02"] 461 assert.Equal(t, true, ok) 462 actualccpBytes, ok := stub.State["example02~collection"] 463 assert.Equal(t, true, ok) 464 assert.Equal(t, ccpBytes, actualccpBytes) 465 466 scc = &SCC{ 467 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 468 Support: &MockSupport{}, 469 SCCProvider: sccProvider, 470 ACLProvider: mockAclProvider, 471 GetMSPIDs: getMSPIDs, 472 BCCSP: cryptoProvider, 473 BuildRegistry: &container.BuildRegistry{}, 474 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 475 } 476 stub = shimtest.NewMockStub("lscc", scc) 477 res = stub.MockInit("1", nil) 478 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 479 480 // As the PrivateChannelData is enabled and collectionConfigBytes is nil, no error is expected 481 testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, []byte("nil")) 482 // Should contain an entry for the chaincodeData only. As the collectionConfigBytes is nil, it 483 // is ignored 484 assert.Equal(t, 1, len(stub.State)) 485 _, ok = stub.State["example02"] 486 assert.Equal(t, true, ok) 487 } 488 489 func createCollectionConfig(collectionName string, signaturePolicyEnvelope *common.SignaturePolicyEnvelope, 490 requiredPeerCount int32, maximumPeerCount int32, 491 ) *peer.CollectionConfig { 492 signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{ 493 SignaturePolicy: signaturePolicyEnvelope, 494 } 495 accessPolicy := &peer.CollectionPolicyConfig{ 496 Payload: signaturePolicy, 497 } 498 499 return &peer.CollectionConfig{ 500 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 501 StaticCollectionConfig: &peer.StaticCollectionConfig{ 502 Name: collectionName, 503 MemberOrgsPolicy: accessPolicy, 504 RequiredPeerCount: requiredPeerCount, 505 MaximumPeerCount: maximumPeerCount, 506 }, 507 }, 508 } 509 } 510 511 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) { 512 if scc == nil { 513 cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 514 scc = &SCC{ 515 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 516 Support: &MockSupport{}, 517 SCCProvider: NewMockProvider(), 518 ACLProvider: mockAclProvider, 519 GetMSPIDs: getMSPIDs, 520 BCCSP: cryptoProvider, 521 BuildRegistry: &container.BuildRegistry{}, 522 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 523 } 524 stub = shimtest.NewMockStub("lscc", scc) 525 res := stub.MockInit("1", nil) 526 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 527 } 528 stub.ChannelID = channelID 529 530 identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")} 531 policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{ 532 Managers: map[string]policies.Manager{ 533 "test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}}, 534 }, 535 } 536 scc.PolicyChecker = policy.NewPolicyChecker( 537 policyManagerGetter, 538 identityDeserializer, 539 &policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")}, 540 ) 541 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic(channelID, &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1")) 542 identityDeserializer.Msg = sProp.ProposalBytes 543 sProp.Signature = sProp.ProposalBytes 544 545 cds, err := constructDeploymentSpec(ccname, path, version, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, install, scc) 546 assert.NoError(t, err) 547 548 if forceBlankCCName { 549 cds.ChaincodeSpec.ChaincodeId.Name = "" 550 } 551 if forceBlankVersion { 552 cds.ChaincodeSpec.ChaincodeId.Version = "" 553 } 554 cdsBytes := protoutil.MarshalOrPanic(cds) 555 556 sProp2, _ := protoutil.MockSignedEndorserProposal2OrPanic(channelID, &pb.ChaincodeSpec{}, id) 557 var args [][]byte 558 if len(collectionConfigBytes) > 0 { 559 if bytes.Equal(collectionConfigBytes, []byte("nil")) { 560 args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes, nil, []byte("escc"), []byte("vscc"), nil} 561 } else { 562 args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes, nil, []byte("escc"), []byte("vscc"), collectionConfigBytes} 563 } 564 } else { 565 args = [][]byte{[]byte("deploy"), []byte("test"), cdsBytes} 566 } 567 res := stub.MockInvokeWithSignedProposal("1", args, sProp2) 568 569 if expectedErrorMsg == "" { 570 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 571 572 for _, function := range []string{"getchaincodes", "GetChaincodes"} { 573 t.Run(function, func(t *testing.T) { 574 mockAclProvider.Reset() 575 mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, channelID, sProp).Return(nil) 576 args = [][]byte{[]byte(function)} 577 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 578 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 579 }) 580 } 581 for _, function := range []string{"getid", "ChaincodeExists"} { 582 t.Run(function, func(t *testing.T) { 583 mockAclProvider.Reset() 584 mockAclProvider.On("CheckACL", resources.Lscc_ChaincodeExists, "test", sProp).Return(nil) 585 args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)} 586 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 587 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 588 }) 589 } 590 for _, function := range []string{"getdepspec", "GetDeploymentSpec"} { 591 t.Run(function, func(t *testing.T) { 592 mockAclProvider.Reset() 593 mockAclProvider.On("CheckACL", resources.Lscc_GetDeploymentSpec, "test", sProp).Return(nil) 594 args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)} 595 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 596 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 597 scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = errors.New("barf") 598 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 599 assert.NotEqual(t, int32(shim.OK), res.Status) 600 assert.Equal(t, "invalid deployment spec: barf", res.Message) 601 scc.Support.(*MockSupport).GetChaincodeFromLocalStorageErr = nil 602 bkpCCFromLSRv := scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv 603 cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 604 scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = &ccprovider.CDSPackage{GetHasher: cryptoProvider} 605 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 606 assert.NotEqual(t, int32(shim.OK), res.Status) 607 assert.Contains(t, res.Message, "chaincode fingerprint mismatch") 608 scc.Support.(*MockSupport).GetChaincodeFromLocalStorageRv = bkpCCFromLSRv 609 }) 610 } 611 612 for _, function := range []string{"getccdata", "GetChaincodeData"} { 613 t.Run(function, func(t *testing.T) { 614 mockAclProvider.Reset() 615 mockAclProvider.On("CheckACL", resources.Lscc_GetChaincodeData, "test", sProp).Return(nil) 616 args = [][]byte{[]byte(function), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)} 617 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 618 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 619 }) 620 } 621 } else { 622 assert.Equal(t, expectedErrorMsg, string(res.Message)) 623 } 624 } 625 626 // TestUpgrade tests the upgrade function with various inputs for basic use cases 627 func TestUpgrade(t *testing.T) { 628 path := "mychaincode" 629 630 testUpgrade(t, "example02", "0", "example02", "1", path, "", nil, nil, nil) 631 testUpgrade(t, "example02", "0", "example02", "", path, InvalidVersionErr("").Error(), nil, nil, nil) 632 testUpgrade(t, "example02", "0", "example02", "0", path, IdenticalVersionErr("example02").Error(), nil, nil, nil) 633 testUpgrade(t, "example02", "0", "example03", "1", path, NotFoundErr("example03").Error(), nil, nil, nil) 634 testUpgrade(t, "example02", "0", "example02", "1{}0", path, InvalidVersionErr("1{}0").Error(), nil, nil, nil) 635 testUpgrade(t, "example02", "0", "example*02", "1{}0", path, InvalidChaincodeNameErr("example*02").Error(), nil, nil, nil) 636 testUpgrade(t, "example02", "0", "", "1", path, InvalidChaincodeNameErr("").Error(), nil, nil, nil) 637 638 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 639 assert.NoError(t, err) 640 scc := &SCC{ 641 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 642 Support: &MockSupport{}, 643 SCCProvider: NewMockProvider(), 644 ACLProvider: mockAclProvider, 645 GetMSPIDs: getMSPIDs, 646 BCCSP: cryptoProvider, 647 BuildRegistry: &container.BuildRegistry{}, 648 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 649 } 650 stub := shimtest.NewMockStub("lscc", scc) 651 res := stub.MockInit("1", nil) 652 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 653 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 654 scc.Support.(*MockSupport).GetInstantiationPolicyErr = errors.New("barf") 655 656 testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil) 657 658 scc = &SCC{ 659 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 660 Support: &MockSupport{}, 661 SCCProvider: NewMockProvider(), 662 ACLProvider: mockAclProvider, 663 GetMSPIDs: getMSPIDs, 664 BCCSP: cryptoProvider, 665 BuildRegistry: &container.BuildRegistry{}, 666 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 667 } 668 stub = shimtest.NewMockStub("lscc", scc) 669 res = stub.MockInit("1", nil) 670 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 671 672 testUpgrade(t, "example02", "0", "example02", "1", path, "instantiation policy missing", scc, stub, nil) 673 674 scc = &SCC{ 675 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 676 Support: &MockSupport{}, 677 SCCProvider: NewMockProvider(), 678 ACLProvider: mockAclProvider, 679 GetMSPIDs: getMSPIDs, 680 BCCSP: cryptoProvider, 681 BuildRegistry: &container.BuildRegistry{}, 682 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 683 } 684 stub = shimtest.NewMockStub("lscc", scc) 685 res = stub.MockInit("1", nil) 686 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 687 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 688 scc.Support.(*MockSupport).GetInstantiationPolicyMap = map[string][]byte{} 689 scc.Support.(*MockSupport).CheckInstantiationPolicyMap = map[string]error{"example020": errors.New("barf")} 690 691 testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil) 692 693 scc = &SCC{ 694 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 695 Support: &MockSupport{}, 696 SCCProvider: NewMockProvider(), 697 ACLProvider: mockAclProvider, 698 GetMSPIDs: getMSPIDs, 699 BCCSP: cryptoProvider, 700 BuildRegistry: &container.BuildRegistry{}, 701 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 702 } 703 stub = shimtest.NewMockStub("lscc", scc) 704 res = stub.MockInit("1", nil) 705 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 706 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 707 scc.Support.(*MockSupport).GetInstantiationPolicyMap = map[string][]byte{} 708 scc.Support.(*MockSupport).CheckInstantiationPolicyMap = map[string]error{"example021": errors.New("barf")} 709 710 testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil) 711 712 // Enable PrivateChannelData 713 capabilities := &mock.ApplicationCapabilities{} 714 capabilities.PrivateChannelDataReturns(true) 715 application := &mock.Application{} 716 application.CapabilitiesReturns(capabilities) 717 sccProvider := &mock.SystemChaincodeProvider{} 718 sccProvider.GetApplicationConfigReturns(application, true) 719 720 scc = &SCC{ 721 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 722 Support: &MockSupport{}, 723 SCCProvider: sccProvider, 724 ACLProvider: mockAclProvider, 725 GetMSPIDs: getMSPIDs, 726 BCCSP: cryptoProvider, 727 BuildRegistry: &container.BuildRegistry{}, 728 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 729 } 730 stub = shimtest.NewMockStub("lscc", scc) 731 res = stub.MockInit("1", nil) 732 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 733 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 734 735 collName1 := "mycollection1" 736 var requiredPeerCount, maximumPeerCount int32 737 requiredPeerCount = 1 738 maximumPeerCount = 2 739 coll1 := createCollectionConfig(collName1, testPolicyEnvelope, requiredPeerCount, maximumPeerCount) 740 741 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}} 742 ccpBytes, err := proto.Marshal(ccp) 743 assert.NoError(t, err) 744 assert.NotNil(t, ccpBytes) 745 746 // As v12 capability is not enabled (which is required for the collection upgrade), an error is expected 747 expectedErrorMsg := "as V1_2 capability is not enabled, collection upgrades are not allowed" 748 testUpgrade(t, "example02", "0", "example02", "1", path, expectedErrorMsg, scc, stub, ccpBytes) 749 750 // Enable PrivateChannelData and V1_2Validation 751 capabilities = &mock.ApplicationCapabilities{} 752 capabilities.CollectionUpgradeReturns(true) 753 capabilities.PrivateChannelDataReturns(true) 754 application = &mock.Application{} 755 application.CapabilitiesReturns(capabilities) 756 sccProvider = &mock.SystemChaincodeProvider{} 757 sccProvider.GetApplicationConfigReturns(application, true) 758 759 scc = &SCC{ 760 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 761 Support: &MockSupport{}, 762 SCCProvider: sccProvider, 763 ACLProvider: mockAclProvider, 764 GetMSPIDs: getMSPIDs, 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 assert.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, []byte("nil")) 776 // Should contain an entry for the chaincodeData only as the collectionConfigBytes is nil 777 assert.Equal(t, 1, len(stub.State)) 778 _, ok := stub.State["example02"] 779 assert.Equal(t, true, ok) 780 781 scc = &SCC{ 782 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 783 Support: &MockSupport{}, 784 SCCProvider: sccProvider, 785 ACLProvider: mockAclProvider, 786 GetMSPIDs: getMSPIDs, 787 BCCSP: cryptoProvider, 788 BuildRegistry: &container.BuildRegistry{}, 789 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 790 } 791 stub = shimtest.NewMockStub("lscc", scc) 792 res = stub.MockInit("1", nil) 793 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 794 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 795 796 // As the PrivateChannelData is enabled and collectionConfigBytes is valid, no error is expected 797 testUpgrade(t, "example02", "0", "example02", "1", path, "", scc, stub, ccpBytes) 798 // Should contain two entries: one for the chaincodeData and another for the collectionConfigBytes 799 // as the V1_2Validation is enabled. Only in V1_2Validation, collection upgrades are allowed. 800 // Note that V1_2Validation would be replaced with CollectionUpgrade capability. 801 assert.Equal(t, 2, len(stub.State)) 802 _, ok = stub.State["example02"] 803 assert.Equal(t, true, ok) 804 actualccpBytes, ok := stub.State["example02~collection"] 805 assert.Equal(t, true, ok) 806 assert.Equal(t, ccpBytes, actualccpBytes) 807 } 808 809 func testUpgrade(t *testing.T, ccname string, version string, newccname string, newversion string, path string, expectedErrorMsg string, scc *SCC, stub *shimtest.MockStub, collectionConfigBytes []byte) { 810 t.Run(ccname+":"+version+"->"+newccname+":"+newversion, func(t *testing.T) { 811 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 812 assert.NoError(t, err) 813 if scc == nil { 814 scc = &SCC{ 815 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 816 Support: &MockSupport{}, 817 SCCProvider: NewMockProvider(), 818 ACLProvider: mockAclProvider, 819 GetMSPIDs: getMSPIDs, 820 BCCSP: cryptoProvider, 821 BuildRegistry: &container.BuildRegistry{}, 822 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 823 } 824 stub = shimtest.NewMockStub("lscc", scc) 825 res := stub.MockInit("1", nil) 826 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 827 scc.Support.(*MockSupport).GetInstantiationPolicyRv = []byte("instantiation policy") 828 } 829 830 cds, err := constructDeploymentSpec(ccname, path, version, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc) 831 assert.NoError(t, err) 832 cdsBytes := protoutil.MarshalOrPanic(cds) 833 834 sProp, _ := protoutil.MockSignedEndorserProposal2OrPanic(channelID, &pb.ChaincodeSpec{}, id) 835 args := [][]byte{[]byte("deploy"), []byte("test"), cdsBytes} 836 saved1 := scc.Support.(*MockSupport).GetInstantiationPolicyErr 837 saved2 := scc.Support.(*MockSupport).CheckInstantiationPolicyMap 838 scc.Support.(*MockSupport).GetInstantiationPolicyErr = nil 839 scc.Support.(*MockSupport).CheckInstantiationPolicyMap = nil 840 res := stub.MockInvokeWithSignedProposal("1", args, sProp) 841 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 842 scc.Support.(*MockSupport).GetInstantiationPolicyErr = saved1 843 scc.Support.(*MockSupport).CheckInstantiationPolicyMap = saved2 844 845 newCds, err := constructDeploymentSpec(newccname, path, newversion, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc) 846 assert.NoError(t, err) 847 newCdsBytes := protoutil.MarshalOrPanic(newCds) 848 849 if len(collectionConfigBytes) > 0 { 850 if bytes.Equal(collectionConfigBytes, []byte("nil")) { 851 args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes, nil, []byte("escc"), []byte("vscc"), nil} 852 } else { 853 args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes, nil, []byte("escc"), []byte("vscc"), collectionConfigBytes} 854 } 855 } else { 856 args = [][]byte{[]byte("upgrade"), []byte("test"), newCdsBytes} 857 } 858 859 res = stub.MockInvokeWithSignedProposal("1", args, sProp) 860 if expectedErrorMsg == "" { 861 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 862 863 cd := &ccprovider.ChaincodeData{} 864 err = proto.Unmarshal(res.Payload, cd) 865 assert.NoError(t, err) 866 867 newVer := cd.Version 868 869 expectVer := "1" 870 assert.Equal(t, newVer, expectVer, fmt.Sprintf("Upgrade chaincode version error, expected %s, got %s", expectVer, newVer)) 871 872 chaincodeEvent := <-stub.ChaincodeEventsChannel 873 assert.Equal(t, "upgrade", chaincodeEvent.EventName) 874 lifecycleEvent := &pb.LifecycleEvent{} 875 err = proto.Unmarshal(chaincodeEvent.Payload, lifecycleEvent) 876 assert.NoError(t, err) 877 assert.Equal(t, newccname, lifecycleEvent.ChaincodeName) 878 } else { 879 assert.Equal(t, expectedErrorMsg, string(res.Message)) 880 } 881 }) 882 } 883 884 func TestFunctionsWithAliases(t *testing.T) { 885 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 886 assert.NoError(t, err) 887 scc := &SCC{ 888 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 889 Support: &MockSupport{}, 890 ACLProvider: mockAclProvider, 891 GetMSPIDs: getMSPIDs, 892 BCCSP: cryptoProvider, 893 BuildRegistry: &container.BuildRegistry{}, 894 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 895 } 896 stub := shimtest.NewMockStub("lscc", scc) 897 res := stub.MockInit("1", nil) 898 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 899 900 identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")} 901 policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{ 902 Managers: map[string]policies.Manager{ 903 "test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}}, 904 }, 905 } 906 scc.PolicyChecker = policy.NewPolicyChecker( 907 policyManagerGetter, 908 identityDeserializer, 909 &policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")}, 910 ) 911 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1")) 912 identityDeserializer.Msg = sProp.ProposalBytes 913 sProp.Signature = sProp.ProposalBytes 914 915 testInvoke := func(function, resource string) { 916 t.Run(function, func(t *testing.T) { 917 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1")}, nil) 918 assert.NotEqual(t, int32(shim.OK), res.Status) 919 assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message) 920 921 mockAclProvider.Reset() 922 mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(errors.New("bonanza")) 923 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("chaincode")}, sProp) 924 assert.NotEqual(t, int32(shim.OK), res.Status, res.Message) 925 assert.Equal(t, fmt.Sprintf("access denied for [%s][testchannel1]: bonanza", function), res.Message) 926 927 mockAclProvider.Reset() 928 mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(nil) 929 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("nonexistentchaincode")}, sProp) 930 assert.NotEqual(t, int32(shim.OK), res.Status, res.Message) 931 assert.Equal(t, res.Message, "could not find chaincode with name 'nonexistentchaincode'") 932 }) 933 } 934 935 testInvoke("getid", "lscc/ChaincodeExists") 936 testInvoke("ChaincodeExists", "lscc/ChaincodeExists") 937 testInvoke("getdepspec", "lscc/GetDeploymentSpec") 938 testInvoke("GetDeploymentSpec", "lscc/GetDeploymentSpec") 939 testInvoke("getccdata", "lscc/GetChaincodeData") 940 testInvoke("GetChaincodeData", "lscc/GetChaincodeData") 941 } 942 943 func TestGetChaincodes(t *testing.T) { 944 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 945 assert.NoError(t, err) 946 scc := &SCC{ 947 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 948 Support: &MockSupport{}, 949 ACLProvider: mockAclProvider, 950 GetMSPIDs: getMSPIDs, 951 BCCSP: cryptoProvider, 952 BuildRegistry: &container.BuildRegistry{}, 953 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 954 } 955 stub := shimtest.NewMockStub("lscc", scc) 956 stub.ChannelID = "test" 957 res := stub.MockInit("1", nil) 958 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 959 960 for _, function := range []string{"getchaincodes", "GetChaincodes"} { 961 t.Run(function, func(t *testing.T) { 962 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("barf")}, nil) 963 assert.NotEqual(t, int32(shim.OK), res.Status) 964 assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message) 965 966 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("test", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1")) 967 sProp.Signature = sProp.ProposalBytes 968 969 mockAclProvider.Reset() 970 mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(errors.New("coyote")) 971 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 972 assert.NotEqual(t, int32(shim.OK), res.Status) 973 assert.Regexp(t, `access denied for \[`+function+`\]\[test\](.*)coyote`, res.Message) 974 975 mockAclProvider.Reset() 976 mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(nil) 977 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 978 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 979 }) 980 } 981 } 982 983 func TestGetChaincodesFilter(t *testing.T) { 984 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 985 assert.NoError(t, err) 986 scc := &SCC{ 987 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 988 Support: &MockSupport{GetChaincodeFromLocalStorageErr: errors.New("banana")}, 989 ACLProvider: mockAclProvider, 990 GetMSPIDs: getMSPIDs, 991 BCCSP: cryptoProvider, 992 BuildRegistry: &container.BuildRegistry{}, 993 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 994 } 995 996 sqi := &mock.StateQueryIterator{} 997 results := []*queryresult.KV{ 998 {Key: "one", Value: protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "name-one", Version: "1.0", Escc: "escc", Vscc: "vscc"})}, 999 {Key: "something~collections", Value: []byte("completely-ignored")}, 1000 {Key: "two", Value: protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "name-two", Version: "2.0", Escc: "escc-2", Vscc: "vscc-2"})}, 1001 } 1002 for i, r := range results { 1003 sqi.NextReturnsOnCall(i, r, nil) 1004 sqi.HasNextReturnsOnCall(i, true) 1005 } 1006 1007 stub := &mock.ChaincodeStub{} 1008 stub.GetStateByRangeReturns(sqi, nil) 1009 1010 resp := scc.getChaincodes(stub) 1011 assert.Equal(t, resp.Status, int32(shim.OK)) 1012 1013 cqr := &pb.ChaincodeQueryResponse{} 1014 err = proto.Unmarshal(resp.GetPayload(), cqr) 1015 assert.NoError(t, err) 1016 1017 assert.Equal(t, cqr.Chaincodes, []*pb.ChaincodeInfo{ 1018 {Name: "name-one", Version: "1.0", Escc: "escc", Vscc: "vscc"}, 1019 {Name: "name-two", Version: "2.0", Escc: "escc-2", Vscc: "vscc-2"}, 1020 }) 1021 } 1022 1023 func TestGetInstalledChaincodes(t *testing.T) { 1024 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1025 assert.NoError(t, err) 1026 scc := &SCC{ 1027 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 1028 Support: &MockSupport{}, 1029 ACLProvider: mockAclProvider, 1030 GetMSPIDs: getMSPIDs, 1031 BCCSP: cryptoProvider, 1032 BuildRegistry: &container.BuildRegistry{}, 1033 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 1034 } 1035 stub := shimtest.NewMockStub("lscc", scc) 1036 res := stub.MockInit("1", nil) 1037 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1038 1039 for _, function := range []string{"getinstalledchaincodes", "GetInstalledChaincodes"} { 1040 t.Run(function, func(t *testing.T) { 1041 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("barf")}, nil) 1042 assert.NotEqual(t, int32(shim.OK), res.Status) 1043 assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message) 1044 1045 identityDeserializer := &policymocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")} 1046 policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{ 1047 Managers: map[string]policies.Manager{ 1048 "test": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: identityDeserializer}}, 1049 }, 1050 } 1051 scc.PolicyChecker = policy.NewPolicyChecker( 1052 policyManagerGetter, 1053 identityDeserializer, 1054 &policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")}, 1055 ) 1056 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1")) 1057 identityDeserializer.Msg = sProp.ProposalBytes 1058 sProp.Signature = sProp.ProposalBytes 1059 1060 mockAclProvider.Reset() 1061 mockAclProvider.On("CheckACL", resources.Lscc_GetInstalledChaincodes, "", sProp).Return(errors.New("authorization failure")) 1062 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 1063 assert.NotEqual(t, int32(shim.OK), res.Status) 1064 assert.Contains(t, res.Message, "access denied for ["+function+"]") 1065 1066 sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1")) 1067 identityDeserializer.Msg = sProp.ProposalBytes 1068 sProp.Signature = sProp.ProposalBytes 1069 1070 mockAclProvider.Reset() 1071 mockAclProvider.On("CheckACL", resources.Lscc_GetInstalledChaincodes, "", sProp).Return(nil) 1072 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 1073 assert.NotEqual(t, int32(shim.OK), res.Status) 1074 assert.Equal(t, "proto: Marshal called with nil", res.Message) 1075 1076 _, err := constructDeploymentSpec("ccname-"+function, "path", "version", [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, false, scc) 1077 assert.NoError(t, err) 1078 1079 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 1080 assert.NotEqual(t, int32(shim.OK), res.Status) 1081 assert.Equal(t, "barf", res.Message) 1082 1083 _, err = constructDeploymentSpec("ccname-"+function, "path", "version", [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}, false, true, scc) 1084 assert.NoError(t, err) 1085 1086 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp) 1087 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1088 1089 scc.Support = &MockSupport{} 1090 }) 1091 } 1092 } 1093 1094 func TestNewLifeCycleSysCC(t *testing.T) { 1095 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1096 assert.NoError(t, err) 1097 scc := &SCC{ 1098 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 1099 Support: &SupportImpl{GetMSPIDs: getMSPIDs}, 1100 ACLProvider: mockAclProvider, 1101 GetMSPIDs: getMSPIDs, 1102 BCCSP: cryptoProvider, 1103 BuildRegistry: &container.BuildRegistry{}, 1104 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 1105 } 1106 assert.NotNil(t, scc) 1107 stub := shimtest.NewMockStub("lscc", scc) 1108 res := stub.MockInit("1", nil) 1109 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1110 1111 res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte("barf")}, nil) 1112 assert.NotEqual(t, int32(shim.OK), res.Status) 1113 assert.Equal(t, "invalid function to lscc: barf", res.Message) 1114 } 1115 1116 func TestGetChaincodeData(t *testing.T) { 1117 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1118 assert.NoError(t, err) 1119 scc := &SCC{ 1120 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 1121 Support: &SupportImpl{GetMSPIDs: getMSPIDs}, 1122 ACLProvider: mockAclProvider, 1123 GetMSPIDs: getMSPIDs, 1124 BCCSP: cryptoProvider, 1125 BuildRegistry: &container.BuildRegistry{}, 1126 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 1127 } 1128 assert.NotNil(t, scc) 1129 stub := shimtest.NewMockStub("lscc", scc) 1130 res := stub.MockInit("1", nil) 1131 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1132 1133 _, err = scc.getChaincodeData("barf", []byte("barf")) 1134 assert.Error(t, err) 1135 1136 _, err = scc.getChaincodeData("barf", protoutil.MarshalOrPanic(&ccprovider.ChaincodeData{Name: "barf s'more"})) 1137 assert.Error(t, err) 1138 assert.True(t, len(err.Error()) > 0) 1139 } 1140 1141 func TestExecuteInstall(t *testing.T) { 1142 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1143 assert.NoError(t, err) 1144 scc := &SCC{ 1145 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 1146 Support: &SupportImpl{GetMSPIDs: getMSPIDs}, 1147 ACLProvider: mockAclProvider, 1148 GetMSPIDs: getMSPIDs, 1149 BCCSP: cryptoProvider, 1150 BuildRegistry: &container.BuildRegistry{}, 1151 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 1152 } 1153 assert.NotNil(t, scc) 1154 stub := shimtest.NewMockStub("lscc", scc) 1155 res := stub.MockInit("1", nil) 1156 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1157 1158 err = scc.executeInstall(stub, []byte("barf")) 1159 assert.Error(t, err) 1160 } 1161 1162 func TestErrors(t *testing.T) { 1163 // these errors are really hard (if 1164 // outright impossible without writing 1165 // tons of lines of mocking code) to 1166 // get in testing 1167 err1 := TXNotFoundErr("") 1168 assert.True(t, len(err1.Error()) > 0) 1169 1170 err3 := MarshallErr("") 1171 assert.True(t, len(err3.Error()) > 0) 1172 } 1173 1174 func TestPutChaincodeCollectionData(t *testing.T) { 1175 scc := &SCC{ 1176 Support: &MockSupport{}, 1177 } 1178 stub := shimtest.NewMockStub("lscc", scc) 1179 1180 if res := stub.MockInit("1", nil); res.Status != shim.OK { 1181 fmt.Println("Init failed", string(res.Message)) 1182 t.FailNow() 1183 } 1184 1185 err := scc.putChaincodeCollectionData(stub, nil, nil) 1186 assert.Error(t, err) 1187 1188 cd := &ccprovider.ChaincodeData{Name: "foo"} 1189 1190 err = scc.putChaincodeCollectionData(stub, cd, nil) 1191 assert.NoError(t, err) 1192 1193 collName1 := "mycollection1" 1194 coll1 := createCollectionConfig(collName1, testPolicyEnvelope, 1, 2) 1195 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}} 1196 ccpBytes, err := proto.Marshal(ccp) 1197 assert.NoError(t, err) 1198 assert.NotNil(t, ccpBytes) 1199 1200 stub.MockTransactionStart("foo") 1201 err = scc.putChaincodeCollectionData(stub, cd, []byte("barf")) 1202 assert.Error(t, err) 1203 stub.MockTransactionEnd("foo") 1204 1205 stub.MockTransactionStart("foo") 1206 err = scc.putChaincodeCollectionData(stub, cd, ccpBytes) 1207 assert.NoError(t, err) 1208 stub.MockTransactionEnd("foo") 1209 } 1210 1211 func TestGetChaincodeCollectionData(t *testing.T) { 1212 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1213 assert.NoError(t, err) 1214 scc := &SCC{ 1215 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 1216 Support: &SupportImpl{GetMSPIDs: getMSPIDs}, 1217 ACLProvider: mockAclProvider, 1218 GetMSPIDs: getMSPIDs, 1219 BCCSP: cryptoProvider, 1220 BuildRegistry: &container.BuildRegistry{}, 1221 ChaincodeBuilder: &mock.ChaincodeBuilder{}, 1222 } 1223 stub := shimtest.NewMockStub("lscc", scc) 1224 stub.ChannelID = "test" 1225 scc.Support = &MockSupport{} 1226 1227 cd := &ccprovider.ChaincodeData{Name: "foo"} 1228 1229 collName1 := "mycollection1" 1230 coll1 := createCollectionConfig(collName1, testPolicyEnvelope, 1, 2) 1231 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}} 1232 ccpBytes, err := proto.Marshal(ccp) 1233 assert.NoError(t, err) 1234 assert.NotNil(t, ccpBytes) 1235 1236 stub.MockTransactionStart("foo") 1237 err = scc.putChaincodeCollectionData(stub, cd, ccpBytes) 1238 assert.NoError(t, err) 1239 stub.MockTransactionEnd("foo") 1240 1241 res := stub.MockInit("1", nil) 1242 assert.Equal(t, int32(shim.OK), res.Status, res.Message) 1243 1244 for _, function := range []string{"GetCollectionsConfig", "getcollectionsconfig"} { 1245 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("test", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1")) 1246 sProp.Signature = sProp.ProposalBytes 1247 1248 t.Run("invalid number of arguments", func(t *testing.T) { 1249 res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo", "bar"), nil) 1250 assert.NotEqual(t, int32(shim.OK), res.Status) 1251 assert.Equal(t, "invalid number of arguments to lscc: 3", res.Message) 1252 }) 1253 t.Run("invalid identity", func(t *testing.T) { 1254 mockAclProvider.Reset() 1255 mockAclProvider.On("CheckACL", resources.Lscc_GetCollectionsConfig, "test", sProp).Return(errors.New("acl check failed")) 1256 res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo"), sProp) 1257 assert.NotEqual(t, int32(shim.OK), res.Status) 1258 assert.Contains(t, res.Message, "access denied for ["+function+"]") 1259 }) 1260 t.Run("non-exists collections config", func(t *testing.T) { 1261 mockAclProvider.Reset() 1262 mockAclProvider.On("CheckACL", resources.Lscc_GetCollectionsConfig, "test", sProp).Return(nil) 1263 res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "bar"), sProp) 1264 assert.NotEqual(t, int32(shim.OK), res.Status) 1265 assert.Equal(t, res.Message, "collections config not defined for chaincode bar") 1266 }) 1267 t.Run("Success", func(t *testing.T) { 1268 res = stub.MockInvokeWithSignedProposal("1", util.ToChaincodeArgs(function, "foo"), sProp) 1269 assert.Equal(t, int32(shim.OK), res.Status) 1270 assert.NotNil(t, res.Payload) 1271 }) 1272 } 1273 } 1274 1275 func TestCheckCollectionMemberPolicy(t *testing.T) { 1276 // error case: no msp manager set, no collection config set 1277 err := checkCollectionMemberPolicy(nil, nil) 1278 assert.Error(t, err) 1279 1280 mockmsp := new(mspmocks.MockMSP) 1281 mockmsp.On("DeserializeIdentity", []byte("signer0")).Return(&mspmocks.MockIdentity{}, nil) 1282 mockmsp.On("DeserializeIdentity", []byte("signer1")).Return(&mspmocks.MockIdentity{}, nil) 1283 mockmsp.On("GetIdentifier").Return("Org1", nil) 1284 mockmsp.On("GetType").Return(msp.FABRIC) 1285 mspmgmt.GetManagerForChain("foochannel") 1286 mgr := mspmgmt.GetManagerForChain("foochannel") 1287 1288 // error case: msp manager not set up, no collection config set 1289 err = checkCollectionMemberPolicy(nil, nil) 1290 assert.EqualError(t, err, "msp manager not set") 1291 1292 // set up msp manager 1293 mgr.Setup([]msp.MSP{mockmsp}) 1294 1295 // error case: no collection config set 1296 err = checkCollectionMemberPolicy(nil, mgr) 1297 assert.EqualError(t, err, "collection configuration is not set") 1298 1299 // error case: empty collection config 1300 cc := &peer.CollectionConfig{} 1301 err = checkCollectionMemberPolicy(cc, mgr) 1302 assert.EqualError(t, err, "collection configuration is empty") 1303 1304 // error case: no static collection config 1305 cc = &peer.CollectionConfig{Payload: &peer.CollectionConfig_StaticCollectionConfig{}} 1306 err = checkCollectionMemberPolicy(cc, mgr) 1307 assert.EqualError(t, err, "collection configuration is empty") 1308 1309 // error case: member org policy not set 1310 cc = &peer.CollectionConfig{ 1311 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1312 StaticCollectionConfig: &peer.StaticCollectionConfig{}, 1313 }, 1314 } 1315 err = checkCollectionMemberPolicy(cc, mgr) 1316 assert.EqualError(t, err, "collection member policy is not set") 1317 1318 // error case: member org policy config empty 1319 cc = &peer.CollectionConfig{ 1320 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1321 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1322 Name: "mycollection", 1323 MemberOrgsPolicy: &peer.CollectionPolicyConfig{ 1324 Payload: &peer.CollectionPolicyConfig_SignaturePolicy{}, 1325 }, 1326 }, 1327 }, 1328 } 1329 err = checkCollectionMemberPolicy(cc, mgr) 1330 assert.EqualError(t, err, "collection member org policy is empty") 1331 1332 // error case: signd-by index is out of range of signers 1333 cc = &peer.CollectionConfig{ 1334 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1335 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1336 Name: "mycollection", 1337 MemberOrgsPolicy: getBadAccessPolicy([]string{"signer0"}, 1), 1338 }, 1339 }, 1340 } 1341 err = checkCollectionMemberPolicy(cc, mgr) 1342 assert.EqualError(t, err, "invalid member org policy for collection 'mycollection': identity index out of range, requested 1, but identities length is 1") 1343 1344 // valid case: well-formed collection policy config 1345 cc = &peer.CollectionConfig{ 1346 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1347 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1348 Name: "mycollection", 1349 MemberOrgsPolicy: &peer.CollectionPolicyConfig{ 1350 Payload: &peer.CollectionPolicyConfig_SignaturePolicy{ 1351 SignaturePolicy: testPolicyEnvelope, 1352 }, 1353 }, 1354 }, 1355 }, 1356 } 1357 err = checkCollectionMemberPolicy(cc, mgr) 1358 assert.NoError(t, err) 1359 1360 // check MSPPrincipal_IDENTITY type 1361 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 1362 signaturePolicyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1363 signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{ 1364 SignaturePolicy: signaturePolicyEnvelope, 1365 } 1366 accessPolicy := &peer.CollectionPolicyConfig{ 1367 Payload: signaturePolicy, 1368 } 1369 cc = &peer.CollectionConfig{ 1370 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1371 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1372 Name: "mycollection", 1373 MemberOrgsPolicy: accessPolicy, 1374 }, 1375 }, 1376 } 1377 err = checkCollectionMemberPolicy(cc, mgr) 1378 assert.NoError(t, err) 1379 mockmsp.AssertNumberOfCalls(t, "DeserializeIdentity", 3) 1380 1381 // check MSPPrincipal_ROLE type 1382 signaturePolicyEnvelope = policydsl.SignedByAnyMember([]string{"Org1"}) 1383 signaturePolicy.SignaturePolicy = signaturePolicyEnvelope 1384 accessPolicy.Payload = signaturePolicy 1385 cc = &peer.CollectionConfig{ 1386 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1387 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1388 Name: "mycollection", 1389 MemberOrgsPolicy: accessPolicy, 1390 }, 1391 }, 1392 } 1393 err = checkCollectionMemberPolicy(cc, mgr) 1394 assert.NoError(t, err) 1395 1396 // check MSPPrincipal_ROLE type for unknown org 1397 signaturePolicyEnvelope = policydsl.SignedByAnyMember([]string{"Org2"}) 1398 signaturePolicy.SignaturePolicy = signaturePolicyEnvelope 1399 accessPolicy.Payload = signaturePolicy 1400 cc = &peer.CollectionConfig{ 1401 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1402 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1403 Name: "mycollection", 1404 MemberOrgsPolicy: accessPolicy, 1405 }, 1406 }, 1407 } 1408 err = checkCollectionMemberPolicy(cc, mgr) 1409 // this does not raise an error but prints a warning logging message instead 1410 assert.NoError(t, err) 1411 1412 // check MSPPrincipal_ORGANIZATION_UNIT type 1413 principal := &mb.MSPPrincipal{ 1414 PrincipalClassification: mb.MSPPrincipal_ORGANIZATION_UNIT, 1415 Principal: protoutil.MarshalOrPanic(&mb.OrganizationUnit{MspIdentifier: "Org1"}), 1416 } 1417 // create the policy: it requires exactly 1 signature from the first (and only) principal 1418 signaturePolicy.SignaturePolicy = &common.SignaturePolicyEnvelope{ 1419 Version: 0, 1420 Rule: policydsl.NOutOf(1, []*common.SignaturePolicy{policydsl.SignedBy(0)}), 1421 Identities: []*mb.MSPPrincipal{principal}, 1422 } 1423 accessPolicy.Payload = signaturePolicy 1424 cc = &peer.CollectionConfig{ 1425 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1426 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1427 Name: "mycollection", 1428 MemberOrgsPolicy: accessPolicy, 1429 }, 1430 }, 1431 } 1432 err = checkCollectionMemberPolicy(cc, mgr) 1433 assert.NoError(t, err) 1434 } 1435 1436 func TestCheckChaincodeName(t *testing.T) { 1437 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1438 assert.NoError(t, err) 1439 1440 lscc := &SCC{BCCSP: cryptoProvider} 1441 1442 /*allowed naming*/ 1443 err = lscc.isValidChaincodeName("a-b") 1444 assert.NoError(t, err) 1445 err = lscc.isValidChaincodeName("a_b") 1446 assert.NoError(t, err) 1447 err = lscc.isValidChaincodeName("a_b-c") 1448 assert.NoError(t, err) 1449 err = lscc.isValidChaincodeName("a-b_c") 1450 assert.NoError(t, err) 1451 1452 /*invalid naming*/ 1453 err = lscc.isValidChaincodeName("") 1454 assert.EqualError(t, err, "invalid chaincode name ''. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1455 err = lscc.isValidChaincodeName("-ab") 1456 assert.EqualError(t, err, "invalid chaincode name '-ab'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1457 err = lscc.isValidChaincodeName("_ab") 1458 assert.EqualError(t, err, "invalid chaincode name '_ab'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1459 err = lscc.isValidChaincodeName("ab-") 1460 assert.EqualError(t, err, "invalid chaincode name 'ab-'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1461 err = lscc.isValidChaincodeName("ab_") 1462 assert.EqualError(t, err, "invalid chaincode name 'ab_'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1463 err = lscc.isValidChaincodeName("a__b") 1464 assert.EqualError(t, err, "invalid chaincode name 'a__b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1465 err = lscc.isValidChaincodeName("a--b") 1466 assert.EqualError(t, err, "invalid chaincode name 'a--b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1467 err = lscc.isValidChaincodeName("a-_b") 1468 assert.EqualError(t, err, "invalid chaincode name 'a-_b'. Names must start with an alphanumeric character and can only consist of alphanumerics, '_', and '-'") 1469 } 1470 1471 func TestCheckChaincodeVersion(t *testing.T) { 1472 lscc := &SCC{} 1473 1474 validCCName := "ccname" 1475 /*allowed versions*/ 1476 err := lscc.isValidChaincodeVersion(validCCName, "a_b") 1477 assert.NoError(t, err) 1478 err = lscc.isValidChaincodeVersion(validCCName, "a.b") 1479 assert.NoError(t, err) 1480 err = lscc.isValidChaincodeVersion(validCCName, "a+b") 1481 assert.NoError(t, err) 1482 err = lscc.isValidChaincodeVersion(validCCName, "a-b") 1483 assert.NoError(t, err) 1484 err = lscc.isValidChaincodeVersion(validCCName, "-ab") 1485 assert.NoError(t, err) 1486 err = lscc.isValidChaincodeVersion(validCCName, "a.0") 1487 assert.NoError(t, err) 1488 err = lscc.isValidChaincodeVersion(validCCName, "a_b.c+d-e") 1489 assert.NoError(t, err) 1490 err = lscc.isValidChaincodeVersion(validCCName, "0") 1491 assert.NoError(t, err) 1492 1493 /*invalid versions*/ 1494 err = lscc.isValidChaincodeVersion(validCCName, "") 1495 assert.EqualError(t, err, fmt.Sprintf("invalid chaincode version ''. Versions must not be empty and can only consist of alphanumerics, '_', '-', '+', and '.'")) 1496 err = lscc.isValidChaincodeVersion(validCCName, "$badversion") 1497 assert.EqualError(t, err, "invalid chaincode version '$badversion'. Versions must not be empty and can only consist of alphanumerics, '_', '-', '+', and '.'") 1498 } 1499 1500 func TestLifecycleChaincodeRegularExpressionsMatch(t *testing.T) { 1501 assert.Equal(t, ChaincodeNameRegExp.String(), lifecycle.ChaincodeNameRegExp.String()) 1502 assert.Equal(t, ChaincodeVersionRegExp.String(), lifecycle.ChaincodeVersionRegExp.String()) 1503 } 1504 1505 var id msp.SigningIdentity 1506 var channelID = "testchannelid" 1507 var mockAclProvider *mocks.MockACLProvider 1508 1509 func NewMockProvider() sysccprovider.SystemChaincodeProvider { 1510 capabilities := &mock.ApplicationCapabilities{} 1511 application := &mock.Application{} 1512 application.CapabilitiesReturns(capabilities) 1513 sccProvider := &mock.SystemChaincodeProvider{} 1514 sccProvider.GetApplicationConfigReturns(application, true) 1515 return sccProvider 1516 } 1517 1518 func TestMain(m *testing.M) { 1519 var err error 1520 msptesttools.LoadMSPSetupForTesting() 1521 1522 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1523 if err != nil { 1524 fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err) 1525 os.Exit(-1) 1526 } 1527 1528 id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity() 1529 if err != nil { 1530 fmt.Printf("GetSigningIdentity failed with err %s", err) 1531 os.Exit(-1) 1532 } 1533 1534 mockAclProvider = &mocks.MockACLProvider{} 1535 mockAclProvider.Reset() 1536 1537 os.Exit(m.Run()) 1538 } 1539 1540 type MockSupport struct { 1541 PutChaincodeToLocalStorageErr error 1542 GetChaincodeFromLocalStorageRv ccprovider.CCPackage 1543 GetChaincodeFromLocalStorageErr error 1544 GetChaincodesFromLocalStorageRv *peer.ChaincodeQueryResponse 1545 GetChaincodesFromLocalStorageErr error 1546 GetInstantiationPolicyRv []byte 1547 GetInstantiationPolicyErr error 1548 CheckInstantiationPolicyErr error 1549 GetInstantiationPolicyMap map[string][]byte 1550 CheckInstantiationPolicyMap map[string]error 1551 CheckCollectionConfigErr error 1552 } 1553 1554 func (s *MockSupport) PutChaincodeToLocalStorage(ccpack ccprovider.CCPackage) error { 1555 return s.PutChaincodeToLocalStorageErr 1556 } 1557 1558 func (s *MockSupport) GetChaincodeFromLocalStorage(ccNameVersion string) (ccprovider.CCPackage, error) { 1559 return s.GetChaincodeFromLocalStorageRv, s.GetChaincodeFromLocalStorageErr 1560 } 1561 1562 func (s *MockSupport) GetChaincodesFromLocalStorage() (*peer.ChaincodeQueryResponse, error) { 1563 return s.GetChaincodesFromLocalStorageRv, s.GetChaincodesFromLocalStorageErr 1564 } 1565 1566 func (s *MockSupport) GetInstantiationPolicy(channel string, ccpack ccprovider.CCPackage) ([]byte, error) { 1567 if s.GetInstantiationPolicyMap != nil { 1568 str := ccpack.GetChaincodeData().Name + ccpack.GetChaincodeData().Version 1569 s.GetInstantiationPolicyMap[str] = []byte(str) 1570 return []byte(ccpack.GetChaincodeData().Name + ccpack.GetChaincodeData().Version), nil 1571 } 1572 return s.GetInstantiationPolicyRv, s.GetInstantiationPolicyErr 1573 } 1574 1575 func (s *MockSupport) CheckInstantiationPolicy(signedProp *peer.SignedProposal, chainName string, instantiationPolicy []byte) error { 1576 if s.CheckInstantiationPolicyMap != nil { 1577 return s.CheckInstantiationPolicyMap[string(instantiationPolicy)] 1578 } 1579 return s.CheckInstantiationPolicyErr 1580 } 1581 1582 func (s *MockSupport) CheckCollectionConfig(collectionConfig *peer.CollectionConfig, channelName string) error { 1583 return s.CheckCollectionConfigErr 1584 } 1585 1586 // getBadAccessPolicy creates a bad CollectionPolicyConfig with signedby index out of range of signers 1587 func getBadAccessPolicy(signers []string, badIndex int32) *peer.CollectionPolicyConfig { 1588 var data [][]byte 1589 for _, signer := range signers { 1590 data = append(data, []byte(signer)) 1591 } 1592 // use a out of range index to trigger error 1593 policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(badIndex)), data) 1594 return &peer.CollectionPolicyConfig{ 1595 Payload: &peer.CollectionPolicyConfig_SignaturePolicy{ 1596 SignaturePolicy: policyEnvelope, 1597 }, 1598 } 1599 }