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