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