github.com/anjalikarhana/fabric@v2.1.1+incompatible/core/handlers/validation/builtin/v12/validation_logic_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package v12 7 8 import ( 9 "archive/tar" 10 "bytes" 11 "compress/gzip" 12 "fmt" 13 "io/ioutil" 14 "os" 15 "testing" 16 17 "github.com/golang/protobuf/proto" 18 "github.com/hyperledger/fabric-protos-go/common" 19 "github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset" 20 mspproto "github.com/hyperledger/fabric-protos-go/msp" 21 "github.com/hyperledger/fabric-protos-go/peer" 22 "github.com/hyperledger/fabric/bccsp/sw" 23 "github.com/hyperledger/fabric/common/capabilities" 24 "github.com/hyperledger/fabric/common/channelconfig" 25 "github.com/hyperledger/fabric/common/policydsl" 26 "github.com/hyperledger/fabric/core/committer/txvalidator/v14" 27 "github.com/hyperledger/fabric/core/common/ccpackage" 28 "github.com/hyperledger/fabric/core/common/ccprovider" 29 "github.com/hyperledger/fabric/core/common/privdata" 30 validation "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities" 31 vs "github.com/hyperledger/fabric/core/handlers/validation/api/state" 32 "github.com/hyperledger/fabric/core/handlers/validation/builtin/v12/mocks" 33 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil" 34 "github.com/hyperledger/fabric/core/scc/lscc" 35 "github.com/hyperledger/fabric/msp" 36 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 37 msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools" 38 "github.com/hyperledger/fabric/protoutil" 39 "github.com/pkg/errors" 40 "github.com/stretchr/testify/assert" 41 ) 42 43 //go:generate counterfeiter -o mocks/state.go -fake-name State . vsState 44 45 type vsState interface { 46 vs.State 47 } 48 49 func createTx(endorsedByDuplicatedIdentity bool) (*common.Envelope, error) { 50 ccid := &peer.ChaincodeID{Name: "foo", Version: "v1"} 51 cis := &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeId: ccid}} 52 53 prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid) 54 if err != nil { 55 return nil, err 56 } 57 58 presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, []byte("res"), nil, ccid, id) 59 if err != nil { 60 return nil, err 61 } 62 63 var env *common.Envelope 64 if endorsedByDuplicatedIdentity { 65 env, err = protoutil.CreateSignedTx(prop, id, presp, presp) 66 } else { 67 env, err = protoutil.CreateSignedTx(prop, id, presp) 68 } 69 if err != nil { 70 return nil, err 71 } 72 return env, err 73 } 74 75 func processSignedCDS(cds *peer.ChaincodeDeploymentSpec, policy *common.SignaturePolicyEnvelope) ([]byte, error) { 76 env, err := ccpackage.OwnerCreateSignedCCDepSpec(cds, policy, nil) 77 if err != nil { 78 return nil, fmt.Errorf("could not create package %s", err) 79 } 80 81 b := protoutil.MarshalOrPanic(env) 82 83 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 84 if err != nil { 85 return nil, fmt.Errorf("could not create bootBCCSP %s", err) 86 } 87 ccpack := &ccprovider.SignedCDSPackage{GetHasher: cryptoProvider} 88 cd, err := ccpack.InitFromBuffer(b) 89 if err != nil { 90 return nil, fmt.Errorf("error owner creating package %s", err) 91 } 92 93 if err = ccpack.PutChaincodeToFS(); err != nil { 94 return nil, fmt.Errorf("error putting package on the FS %s", err) 95 } 96 97 cd.InstantiationPolicy = protoutil.MarshalOrPanic(policy) 98 99 return protoutil.MarshalOrPanic(cd), nil 100 } 101 102 func constructDeploymentSpec(name, path, version string, initArgs [][]byte, createFS bool) (*peer.ChaincodeDeploymentSpec, error) { 103 spec := &peer.ChaincodeSpec{Type: 1, ChaincodeId: &peer.ChaincodeID{Name: name, Path: path, Version: version}, Input: &peer.ChaincodeInput{Args: initArgs}} 104 105 codePackageBytes := bytes.NewBuffer(nil) 106 gz := gzip.NewWriter(codePackageBytes) 107 tw := tar.NewWriter(gz) 108 109 payload := []byte(name + path + version) 110 err := tw.WriteHeader(&tar.Header{ 111 Name: "src/garbage.go", 112 Size: int64(len(payload)), 113 Mode: 0100644, 114 }) 115 if err != nil { 116 return nil, err 117 } 118 119 _, err = tw.Write(payload) 120 if err != nil { 121 return nil, err 122 } 123 124 tw.Close() 125 gz.Close() 126 127 chaincodeDeploymentSpec := &peer.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes.Bytes()} 128 129 if createFS { 130 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 131 if err != nil { 132 return nil, err 133 } 134 ccinfoFSImpl := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider} 135 _, err = ccinfoFSImpl.PutChaincode(chaincodeDeploymentSpec) 136 if err != nil { 137 return nil, err 138 } 139 } 140 141 return chaincodeDeploymentSpec, nil 142 } 143 144 func createCCDataRWsetWithCollection(nameK, nameV, version string, policy []byte, collectionConfigPackage []byte) ([]byte, error) { 145 cd := &ccprovider.ChaincodeData{ 146 Name: nameV, 147 Version: version, 148 InstantiationPolicy: policy, 149 } 150 151 cdbytes := protoutil.MarshalOrPanic(cd) 152 153 rwsetBuilder := rwsetutil.NewRWSetBuilder() 154 rwsetBuilder.AddToWriteSet("lscc", nameK, cdbytes) 155 rwsetBuilder.AddToWriteSet("lscc", privdata.BuildCollectionKVSKey(nameK), collectionConfigPackage) 156 sr, err := rwsetBuilder.GetTxSimulationResults() 157 if err != nil { 158 return nil, err 159 } 160 return sr.GetPubSimulationBytes() 161 } 162 163 func createCCDataRWset(nameK, nameV, version string, policy []byte) ([]byte, error) { 164 cd := &ccprovider.ChaincodeData{ 165 Name: nameV, 166 Version: version, 167 InstantiationPolicy: policy, 168 } 169 170 cdbytes := protoutil.MarshalOrPanic(cd) 171 172 rwsetBuilder := rwsetutil.NewRWSetBuilder() 173 rwsetBuilder.AddToWriteSet("lscc", nameK, cdbytes) 174 sr, err := rwsetBuilder.GetTxSimulationResults() 175 if err != nil { 176 return nil, err 177 } 178 return sr.GetPubSimulationBytes() 179 } 180 181 func createLSCCTxWithCollection(ccname, ccver, f string, res []byte, policy []byte, ccpBytes []byte) (*common.Envelope, error) { 182 return createLSCCTxPutCdsWithCollection(ccname, ccver, f, res, nil, true, policy, ccpBytes) 183 } 184 185 func createLSCCTx(ccname, ccver, f string, res []byte) (*common.Envelope, error) { 186 return createLSCCTxPutCds(ccname, ccver, f, res, nil, true) 187 } 188 189 func createLSCCTxPutCdsWithCollection(ccname, ccver, f string, res, cdsbytes []byte, putcds bool, policy []byte, ccpBytes []byte) (*common.Envelope, error) { 190 cds := &peer.ChaincodeDeploymentSpec{ 191 ChaincodeSpec: &peer.ChaincodeSpec{ 192 ChaincodeId: &peer.ChaincodeID{ 193 Name: ccname, 194 Version: ccver, 195 }, 196 Type: peer.ChaincodeSpec_GOLANG, 197 }, 198 } 199 200 cdsBytes, err := proto.Marshal(cds) 201 if err != nil { 202 return nil, err 203 } 204 205 var cis *peer.ChaincodeInvocationSpec 206 if putcds { 207 if cdsbytes != nil { 208 cdsBytes = cdsbytes 209 } 210 cis = &peer.ChaincodeInvocationSpec{ 211 ChaincodeSpec: &peer.ChaincodeSpec{ 212 ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, 213 Input: &peer.ChaincodeInput{ 214 Args: [][]byte{[]byte(f), []byte("barf"), cdsBytes, []byte("escc"), []byte("vscc"), policy, ccpBytes}, 215 }, 216 Type: peer.ChaincodeSpec_GOLANG, 217 }, 218 } 219 } else { 220 cis = &peer.ChaincodeInvocationSpec{ 221 ChaincodeSpec: &peer.ChaincodeSpec{ 222 ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, 223 Input: &peer.ChaincodeInput{ 224 Args: [][]byte{[]byte(f), []byte("barf")}, 225 }, 226 Type: peer.ChaincodeSpec_GOLANG, 227 }, 228 } 229 } 230 231 prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid) 232 if err != nil { 233 return nil, err 234 } 235 236 ccid := &peer.ChaincodeID{Name: ccname, Version: ccver} 237 238 presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id) 239 if err != nil { 240 return nil, err 241 } 242 243 return protoutil.CreateSignedTx(prop, id, presp) 244 } 245 246 func createLSCCTxPutCds(ccname, ccver, f string, res, cdsbytes []byte, putcds bool) (*common.Envelope, error) { 247 cds := &peer.ChaincodeDeploymentSpec{ 248 ChaincodeSpec: &peer.ChaincodeSpec{ 249 ChaincodeId: &peer.ChaincodeID{ 250 Name: ccname, 251 Version: ccver, 252 }, 253 Type: peer.ChaincodeSpec_GOLANG, 254 }, 255 } 256 257 cdsBytes, err := proto.Marshal(cds) 258 if err != nil { 259 return nil, err 260 } 261 262 var cis *peer.ChaincodeInvocationSpec 263 if putcds { 264 if cdsbytes != nil { 265 cdsBytes = cdsbytes 266 } 267 cis = &peer.ChaincodeInvocationSpec{ 268 ChaincodeSpec: &peer.ChaincodeSpec{ 269 ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, 270 Input: &peer.ChaincodeInput{ 271 Args: [][]byte{[]byte(f), []byte("barf"), cdsBytes}, 272 }, 273 Type: peer.ChaincodeSpec_GOLANG, 274 }, 275 } 276 } else { 277 cis = &peer.ChaincodeInvocationSpec{ 278 ChaincodeSpec: &peer.ChaincodeSpec{ 279 ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, 280 Input: &peer.ChaincodeInput{ 281 Args: [][]byte{[]byte(f), []byte(ccname)}, 282 }, 283 Type: peer.ChaincodeSpec_GOLANG, 284 }, 285 } 286 } 287 288 prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid) 289 if err != nil { 290 return nil, err 291 } 292 293 ccid := &peer.ChaincodeID{Name: ccname, Version: ccver} 294 295 presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id) 296 if err != nil { 297 return nil, err 298 } 299 300 return protoutil.CreateSignedTx(prop, id, presp) 301 } 302 303 func getSignedByMSPMemberPolicy(mspID string) ([]byte, error) { 304 p := policydsl.SignedByMspMember(mspID) 305 306 b, err := protoutil.Marshal(p) 307 if err != nil { 308 return nil, fmt.Errorf("Could not marshal policy, err %s", err) 309 } 310 311 return b, err 312 } 313 314 func getSignedByOneMemberTwicePolicy(mspID string) ([]byte, error) { 315 principal := &mspproto.MSPPrincipal{ 316 PrincipalClassification: mspproto.MSPPrincipal_ROLE, 317 Principal: protoutil.MarshalOrPanic(&mspproto.MSPRole{Role: mspproto.MSPRole_MEMBER, MspIdentifier: mspID})} 318 319 p := &common.SignaturePolicyEnvelope{ 320 Version: 0, 321 Rule: policydsl.NOutOf(2, []*common.SignaturePolicy{policydsl.SignedBy(0), policydsl.SignedBy(0)}), 322 Identities: []*mspproto.MSPPrincipal{principal}, 323 } 324 b, err := protoutil.Marshal(p) 325 if err != nil { 326 return nil, fmt.Errorf("Could not marshal policy, err %s", err) 327 } 328 329 return b, err 330 } 331 332 func getSignedByMSPAdminPolicy(mspID string) ([]byte, error) { 333 p := policydsl.SignedByMspAdmin(mspID) 334 335 b, err := protoutil.Marshal(p) 336 if err != nil { 337 return nil, fmt.Errorf("Could not marshal policy, err %s", err) 338 } 339 340 return b, err 341 } 342 343 func newValidationInstance(state map[string]map[string][]byte) *Validator { 344 c := &mocks.Capabilities{} 345 c.On("PrivateChannelData").Return(false) 346 c.On("V1_1Validation").Return(false) 347 c.On("V1_2Validation").Return(false) 348 vs := &mocks.State{} 349 vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) { 350 if ns, ok := state[namespace]; ok { 351 return [][]byte{ns[keys[0]]}, nil 352 353 } else { 354 return nil, fmt.Errorf("could not retrieve namespace %s", namespace) 355 } 356 } 357 sf := &mocks.StateFetcher{} 358 sf.On("FetchState").Return(vs, nil) 359 return newCustomValidationInstance(sf, c) 360 } 361 362 func newCustomValidationInstance(sf StateFetcher, c validation.Capabilities) *Validator { 363 is := &mocks.IdentityDeserializer{} 364 pe := &txvalidator.PolicyEvaluator{ 365 IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"), 366 } 367 return New(c, sf, is, pe) 368 } 369 370 func TestDeduplicateIdentity(t *testing.T) { 371 // We allocate a slice with capacity greater than the length 372 proposalResponsePayload := []byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} 373 prpBuff := make([]byte, len(proposalResponsePayload), len(proposalResponsePayload)*2) 374 copy(prpBuff, proposalResponsePayload) 375 376 identity1 := protoutil.MarshalOrPanic(&mspproto.SerializedIdentity{ 377 IdBytes: []byte{1, 1, 1}, 378 }) 379 identity2 := protoutil.MarshalOrPanic(&mspproto.SerializedIdentity{ 380 IdBytes: []byte{2, 2, 2}, 381 }) 382 383 chaincodeActionPayload := &peer.ChaincodeActionPayload{ 384 Action: &peer.ChaincodeEndorsedAction{ 385 Endorsements: []*peer.Endorsement{ 386 { 387 Endorser: identity1, 388 }, 389 { 390 Endorser: identity2, 391 }, 392 }, 393 ProposalResponsePayload: prpBuff, 394 }, 395 } 396 397 signedData, err := (&Validator{}).deduplicateIdentity(chaincodeActionPayload) 398 assert.NoError(t, err) 399 // The original bytes of proposalResponsePayload are preserved 400 assert.Equal(t, proposalResponsePayload, signedData[0].Data[:len(proposalResponsePayload)]) 401 assert.Equal(t, proposalResponsePayload, signedData[1].Data[:len(proposalResponsePayload)]) 402 // And are suffixed with the identity bytes 403 assert.Equal(t, identity1, signedData[0].Data[len(proposalResponsePayload):]) 404 assert.Equal(t, identity2, signedData[1].Data[len(proposalResponsePayload):]) 405 } 406 407 func TestInvoke(t *testing.T) { 408 v := newValidationInstance(make(map[string]map[string][]byte)) 409 410 // broken Envelope 411 var err error 412 b := &common.Block{Data: &common.BlockData{Data: [][]byte{[]byte("a")}}} 413 err = v.Validate(b, "foo", 0, 0, []byte("a")) 414 assert.Error(t, err) 415 416 // (still) broken Envelope 417 b = &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{Payload: []byte("barf")})}}} 418 err = v.Validate(b, "foo", 0, 0, []byte("a")) 419 assert.Error(t, err) 420 421 // (still) broken Envelope 422 e := protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: []byte("barf")}})}) 423 b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}} 424 err = v.Validate(b, "foo", 0, 0, []byte("a")) 425 assert.Error(t, err) 426 427 tx, err := createTx(false) 428 if err != nil { 429 t.Fatalf("createTx returned err %s", err) 430 } 431 432 envBytes, err := protoutil.GetBytesEnvelope(tx) 433 if err != nil { 434 t.Fatalf("GetBytesEnvelope returned err %s", err) 435 } 436 437 // broken policy 438 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 439 err = v.Validate(b, "foo", 0, 0, []byte("barf")) 440 assert.Error(t, err) 441 442 policy, err := getSignedByMSPMemberPolicy(mspid) 443 if err != nil { 444 t.Fatalf("failed getting policy, err %s", err) 445 } 446 447 // broken type 448 e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})}) 449 b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}} 450 err = v.Validate(b, "foo", 0, 0, policy) 451 assert.Error(t, err) 452 453 // broken tx payload 454 e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})}) 455 b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}} 456 err = v.Validate(b, "foo", 0, 0, policy) 457 assert.Error(t, err) 458 459 // good path: signed by the right MSP 460 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 461 err = v.Validate(b, "foo", 0, 0, policy) 462 assert.NoError(t, err) 463 464 // bad path: signed by the wrong MSP 465 policy, err = getSignedByMSPMemberPolicy("barf") 466 if err != nil { 467 t.Fatalf("failed getting policy, err %s", err) 468 } 469 470 err = v.Validate(b, "foo", 0, 0, policy) 471 assert.Error(t, err) 472 473 // bad path: signed by duplicated MSP identity 474 policy, err = getSignedByOneMemberTwicePolicy(mspid) 475 if err != nil { 476 t.Fatalf("failed getting policy, err %s", err) 477 } 478 tx, err = createTx(true) 479 if err != nil { 480 t.Fatalf("createTx returned err %s", err) 481 } 482 envBytes, err = protoutil.GetBytesEnvelope(tx) 483 if err != nil { 484 t.Fatalf("GetBytesEnvelope returned err %s", err) 485 } 486 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 487 err = v.Validate(b, "foo", 0, 0, policy) 488 assert.Error(t, err) 489 } 490 491 func TestRWSetTooBig(t *testing.T) { 492 state := make(map[string]map[string][]byte) 493 state["lscc"] = make(map[string][]byte) 494 495 v := newValidationInstance(state) 496 497 ccname := "mycc" 498 ccver := "1" 499 500 cd := &ccprovider.ChaincodeData{ 501 Name: ccname, 502 Version: ccver, 503 InstantiationPolicy: nil, 504 } 505 506 cdbytes := protoutil.MarshalOrPanic(cd) 507 508 rwsetBuilder := rwsetutil.NewRWSetBuilder() 509 rwsetBuilder.AddToWriteSet("lscc", ccname, cdbytes) 510 rwsetBuilder.AddToWriteSet("lscc", "spurious", []byte("spurious")) 511 512 sr, err := rwsetBuilder.GetTxSimulationResults() 513 assert.NoError(t, err) 514 srBytes, err := sr.GetPubSimulationBytes() 515 assert.NoError(t, err) 516 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, srBytes) 517 if err != nil { 518 t.Fatalf("createTx returned err %s", err) 519 } 520 521 envBytes, err := protoutil.GetBytesEnvelope(tx) 522 if err != nil { 523 t.Fatalf("GetBytesEnvelope returned err %s", err) 524 } 525 526 // good path: signed by the right MSP 527 policy, err := getSignedByMSPMemberPolicy(mspid) 528 if err != nil { 529 t.Fatalf("failed getting policy, err %s", err) 530 } 531 532 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 533 err = v.Validate(b, "lscc", 0, 0, policy) 534 assert.EqualError(t, err, "LSCC can only issue a single putState upon deploy") 535 t.Logf("error: %s", err) 536 } 537 538 func TestValidateDeployFail(t *testing.T) { 539 state := make(map[string]map[string][]byte) 540 state["lscc"] = make(map[string][]byte) 541 542 v := newValidationInstance(state) 543 544 ccname := "mycc" 545 ccver := "1" 546 547 /*********************/ 548 /* test no write set */ 549 /*********************/ 550 551 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, nil) 552 if err != nil { 553 t.Fatalf("createTx returned err %s", err) 554 } 555 556 envBytes, err := protoutil.GetBytesEnvelope(tx) 557 if err != nil { 558 t.Fatalf("GetBytesEnvelope returned err %s", err) 559 } 560 561 // good path: signed by the right MSP 562 policy, err := getSignedByMSPMemberPolicy(mspid) 563 if err != nil { 564 t.Fatalf("failed getting policy, err %s", err) 565 } 566 567 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 568 err = v.Validate(b, "lscc", 0, 0, policy) 569 assert.EqualError(t, err, "No read write set for lscc was found") 570 571 /************************/ 572 /* test bogus write set */ 573 /************************/ 574 575 rwsetBuilder := rwsetutil.NewRWSetBuilder() 576 rwsetBuilder.AddToWriteSet("lscc", ccname, []byte("barf")) 577 sr, err := rwsetBuilder.GetTxSimulationResults() 578 assert.NoError(t, err) 579 resBogusBytes, err := sr.GetPubSimulationBytes() 580 assert.NoError(t, err) 581 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, resBogusBytes) 582 if err != nil { 583 t.Fatalf("createTx returned err %s", err) 584 } 585 586 envBytes, err = protoutil.GetBytesEnvelope(tx) 587 if err != nil { 588 t.Fatalf("GetBytesEnvelope returned err %s", err) 589 } 590 591 // good path: signed by the right MSP 592 policy, err = getSignedByMSPMemberPolicy(mspid) 593 if err != nil { 594 t.Fatalf("failed getting policy, err %s", err) 595 } 596 597 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 598 err = v.Validate(b, "lscc", 0, 0, policy) 599 assert.EqualError(t, err, "unmarhsalling of ChaincodeData failed, error unexpected EOF") 600 601 /**********************/ 602 /* test bad LSCC args */ 603 /**********************/ 604 605 res, err := createCCDataRWset(ccname, ccname, ccver, nil) 606 assert.NoError(t, err) 607 608 tx, err = createLSCCTxPutCds(ccname, ccver, lscc.DEPLOY, res, nil, false) 609 if err != nil { 610 t.Fatalf("createTx returned err %s", err) 611 } 612 613 envBytes, err = protoutil.GetBytesEnvelope(tx) 614 if err != nil { 615 t.Fatalf("GetBytesEnvelope returned err %s", err) 616 } 617 618 // good path: signed by the right MSP 619 policy, err = getSignedByMSPMemberPolicy(mspid) 620 if err != nil { 621 t.Fatalf("failed getting policy, err %s", err) 622 } 623 624 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 625 err = v.Validate(b, "lscc", 0, 0, policy) 626 assert.EqualError(t, err, "Wrong number of arguments for invocation lscc(deploy): expected at least 2, received 1") 627 628 /**********************/ 629 /* test bad LSCC args */ 630 /**********************/ 631 632 res, err = createCCDataRWset(ccname, ccname, ccver, nil) 633 assert.NoError(t, err) 634 635 tx, err = createLSCCTxPutCds(ccname, ccver, lscc.DEPLOY, res, []byte("barf"), true) 636 if err != nil { 637 t.Fatalf("createTx returned err %s", err) 638 } 639 640 envBytes, err = protoutil.GetBytesEnvelope(tx) 641 if err != nil { 642 t.Fatalf("GetBytesEnvelope returned err %s", err) 643 } 644 645 // good path: signed by the right MSP 646 policy, err = getSignedByMSPMemberPolicy(mspid) 647 if err != nil { 648 t.Fatalf("failed getting policy, err %s", err) 649 } 650 651 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 652 err = v.Validate(b, "lscc", 0, 0, policy) 653 assert.EqualError(t, err, "GetChaincodeDeploymentSpec error error unmarshaling ChaincodeDeploymentSpec: unexpected EOF") 654 655 /***********************/ 656 /* test bad cc version */ 657 /***********************/ 658 659 res, err = createCCDataRWset(ccname, ccname, ccver+".1", nil) 660 assert.NoError(t, err) 661 662 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 663 if err != nil { 664 t.Fatalf("createTx returned err %s", err) 665 } 666 667 envBytes, err = protoutil.GetBytesEnvelope(tx) 668 if err != nil { 669 t.Fatalf("GetBytesEnvelope returned err %s", err) 670 } 671 672 // good path: signed by the right MSP 673 policy, err = getSignedByMSPMemberPolicy(mspid) 674 if err != nil { 675 t.Fatalf("failed getting policy, err %s", err) 676 } 677 678 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 679 err = v.Validate(b, "lscc", 0, 0, policy) 680 assert.EqualError(t, err, "expected cc version 1, found 1.1") 681 682 /*************/ 683 /* bad rwset */ 684 /*************/ 685 686 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, []byte("barf")) 687 if err != nil { 688 t.Fatalf("createTx returned err %s", err) 689 } 690 691 envBytes, err = protoutil.GetBytesEnvelope(tx) 692 if err != nil { 693 t.Fatalf("GetBytesEnvelope returned err %s", err) 694 } 695 696 // good path: signed by the right MSP 697 policy, err = getSignedByMSPMemberPolicy(mspid) 698 if err != nil { 699 t.Fatalf("failed getting policy, err %s", err) 700 } 701 702 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 703 err = v.Validate(b, "lscc", 0, 0, policy) 704 assert.EqualError(t, err, "txRWSet.FromProtoBytes error unexpected EOF") 705 706 /********************/ 707 /* test bad cc name */ 708 /********************/ 709 710 res, err = createCCDataRWset(ccname+".badbad", ccname, ccver, nil) 711 assert.NoError(t, err) 712 713 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 714 if err != nil { 715 t.Fatalf("createTx returned err %s", err) 716 } 717 718 envBytes, err = protoutil.GetBytesEnvelope(tx) 719 if err != nil { 720 t.Fatalf("GetBytesEnvelope returned err %s", err) 721 } 722 723 policy, err = getSignedByMSPMemberPolicy(mspid) 724 if err != nil { 725 t.Fatalf("failed getting policy, err %s", err) 726 } 727 728 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 729 err = v.Validate(b, "lscc", 0, 0, policy) 730 assert.EqualError(t, err, "expected key mycc, found mycc.badbad") 731 732 /**********************/ 733 /* test bad cc name 2 */ 734 /**********************/ 735 736 res, err = createCCDataRWset(ccname, ccname+".badbad", ccver, nil) 737 assert.NoError(t, err) 738 739 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 740 if err != nil { 741 t.Fatalf("createTx returned err %s", err) 742 } 743 744 envBytes, err = protoutil.GetBytesEnvelope(tx) 745 if err != nil { 746 t.Fatalf("GetBytesEnvelope returned err %s", err) 747 } 748 749 policy, err = getSignedByMSPMemberPolicy(mspid) 750 if err != nil { 751 t.Fatalf("failed getting policy, err %s", err) 752 } 753 754 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 755 err = v.Validate(b, "lscc", 0, 0, policy) 756 assert.EqualError(t, err, "expected cc name mycc, found mycc.badbad") 757 758 /************************/ 759 /* test spurious writes */ 760 /************************/ 761 762 cd := &ccprovider.ChaincodeData{ 763 Name: ccname, 764 Version: ccver, 765 InstantiationPolicy: nil, 766 } 767 768 cdbytes := protoutil.MarshalOrPanic(cd) 769 rwsetBuilder = rwsetutil.NewRWSetBuilder() 770 rwsetBuilder.AddToWriteSet("lscc", ccname, cdbytes) 771 rwsetBuilder.AddToWriteSet("bogusbogus", "key", []byte("val")) 772 sr, err = rwsetBuilder.GetTxSimulationResults() 773 assert.NoError(t, err) 774 srBytes, err := sr.GetPubSimulationBytes() 775 assert.NoError(t, err) 776 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, srBytes) 777 if err != nil { 778 t.Fatalf("createTx returned err %s", err) 779 } 780 781 envBytes, err = protoutil.GetBytesEnvelope(tx) 782 if err != nil { 783 t.Fatalf("GetBytesEnvelope returned err %s", err) 784 } 785 786 policy, err = getSignedByMSPMemberPolicy(mspid) 787 if err != nil { 788 t.Fatalf("failed getting policy, err %s", err) 789 } 790 791 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 792 err = v.Validate(b, "lscc", 0, 0, policy) 793 assert.EqualError(t, err, "LSCC invocation is attempting to write to namespace bogusbogus") 794 795 } 796 797 func TestAlreadyDeployed(t *testing.T) { 798 state := make(map[string]map[string][]byte) 799 state["lscc"] = make(map[string][]byte) 800 801 v := newValidationInstance(state) 802 803 ccname := "mycc" 804 ccver := "alreadydeployed" 805 806 // create state for ccname to simulate deployment 807 state["lscc"][ccname] = []byte{} 808 809 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 810 assert.NoError(t, err) 811 812 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, simresres) 813 if err != nil { 814 t.Fatalf("createTx returned err %s", err) 815 } 816 817 envBytes, err := protoutil.GetBytesEnvelope(tx) 818 if err != nil { 819 t.Fatalf("GetBytesEnvelope returned err %s", err) 820 } 821 822 // good path: signed by the right MSP 823 policy, err := getSignedByMSPMemberPolicy(mspid) 824 if err != nil { 825 t.Fatalf("failed getting policy, err %s", err) 826 } 827 828 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 829 err = v.Validate(bl, "lscc", 0, 0, policy) 830 assert.EqualError(t, err, "Chaincode mycc is already instantiated") 831 } 832 833 func TestValidateDeployNoLedger(t *testing.T) { 834 sf := &mocks.StateFetcher{} 835 sf.On("FetchState").Return(nil, errors.New("failed obtaining query executor")) 836 capabilities := &mocks.Capabilities{} 837 capabilities.On("PrivateChannelData").Return(false) 838 capabilities.On("V1_1Validation").Return(false) 839 capabilities.On("V1_2Validation").Return(false) 840 v := newCustomValidationInstance(sf, capabilities) 841 842 ccname := "mycc" 843 ccver := "1" 844 845 defaultPolicy, err := getSignedByMSPAdminPolicy(mspid) 846 assert.NoError(t, err) 847 res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy) 848 assert.NoError(t, err) 849 850 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 851 if err != nil { 852 t.Fatalf("createTx returned err %s", err) 853 } 854 855 envBytes, err := protoutil.GetBytesEnvelope(tx) 856 if err != nil { 857 t.Fatalf("GetBytesEnvelope returned err %s", err) 858 } 859 860 // good path: signed by the right MSP 861 policy, err := getSignedByMSPMemberPolicy(mspid) 862 if err != nil { 863 t.Fatalf("failed getting policy, err %s", err) 864 } 865 866 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 867 err = v.Validate(b, "lscc", 0, 0, policy) 868 assert.EqualError(t, err, "could not retrieve QueryExecutor for channel testchannelid, error failed obtaining query executor") 869 } 870 871 func TestValidateDeployNOKNilChaincodeSpec(t *testing.T) { 872 state := make(map[string]map[string][]byte) 873 state["lscc"] = make(map[string][]byte) 874 875 v := newValidationInstance(state) 876 877 ccname := "mycc" 878 ccver := "1" 879 880 defaultPolicy, err := getSignedByMSPAdminPolicy(mspid) 881 assert.NoError(t, err) 882 res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy) 883 assert.NoError(t, err) 884 885 // Create a ChaincodeDeploymentSpec with nil ChaincodeSpec for negative test 886 cdsBytes, err := proto.Marshal(&peer.ChaincodeDeploymentSpec{}) 887 assert.NoError(t, err) 888 889 // ChaincodeDeploymentSpec/ChaincodeSpec are derived from cdsBytes (i.e., cis.ChaincodeSpec.Input.Args[2]) 890 cis := &peer.ChaincodeInvocationSpec{ 891 ChaincodeSpec: &peer.ChaincodeSpec{ 892 ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, 893 Input: &peer.ChaincodeInput{ 894 Args: [][]byte{[]byte(lscc.DEPLOY), []byte("barf"), cdsBytes}, 895 }, 896 Type: peer.ChaincodeSpec_GOLANG, 897 }, 898 } 899 900 prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid) 901 assert.NoError(t, err) 902 903 ccid := &peer.ChaincodeID{Name: ccname, Version: ccver} 904 905 presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, res, nil, ccid, id) 906 assert.NoError(t, err) 907 908 env, err := protoutil.CreateSignedTx(prop, id, presp) 909 assert.NoError(t, err) 910 911 // good path: signed by the right MSP 912 policy, err := getSignedByMSPMemberPolicy(mspid) 913 if err != nil { 914 t.Fatalf("failed getting policy, err %s", err) 915 } 916 917 b := &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(env)}}, Header: &common.BlockHeader{}} 918 err = v.Validate(b, "lscc", 0, 0, policy) 919 assert.EqualError(t, err, "VSCC error: invocation of lscc(deploy) does not have appropriate arguments") 920 } 921 922 func TestValidateDeployOK(t *testing.T) { 923 state := make(map[string]map[string][]byte) 924 state["lscc"] = make(map[string][]byte) 925 926 v := newValidationInstance(state) 927 928 ccname := "mycc" 929 ccver := "1" 930 931 defaultPolicy, err := getSignedByMSPAdminPolicy(mspid) 932 assert.NoError(t, err) 933 res, err := createCCDataRWset(ccname, ccname, ccver, defaultPolicy) 934 assert.NoError(t, err) 935 936 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 937 if err != nil { 938 t.Fatalf("createTx returned err %s", err) 939 } 940 941 envBytes, err := protoutil.GetBytesEnvelope(tx) 942 if err != nil { 943 t.Fatalf("GetBytesEnvelope returned err %s", err) 944 } 945 946 // good path: signed by the right MSP 947 policy, err := getSignedByMSPMemberPolicy(mspid) 948 if err != nil { 949 t.Fatalf("failed getting policy, err %s", err) 950 } 951 952 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 953 err = v.Validate(b, "lscc", 0, 0, policy) 954 assert.NoError(t, err) 955 } 956 957 func TestValidateDeployNOK(t *testing.T) { 958 var testCases = []struct { 959 description string 960 ccName string 961 ccVersion string 962 errMsg string 963 }{ 964 {description: "empty cc name", ccName: "", ccVersion: "1", errMsg: "invalid chaincode name ''"}, 965 {description: "bad first character in cc name", ccName: "_badname", ccVersion: "1.2", errMsg: "invalid chaincode name '_badname'"}, 966 {description: "bad character in cc name", ccName: "bad.name", ccVersion: "1-5", errMsg: "invalid chaincode name 'bad.name'"}, 967 {description: "empty cc version", ccName: "1good_name", ccVersion: "", errMsg: "invalid chaincode version ''"}, 968 {description: "bad cc version", ccName: "good-name", ccVersion: "$badversion", errMsg: "invalid chaincode version '$badversion'"}, 969 {description: "use system cc name", ccName: "qscc", ccVersion: "2.1", errMsg: "chaincode name 'qscc' is reserved for system chaincodes"}, 970 } 971 972 // create validator and policy 973 state := make(map[string]map[string][]byte) 974 state["lscc"] = make(map[string][]byte) 975 976 v := newValidationInstance(state) 977 978 policy, err := getSignedByMSPAdminPolicy(mspid) 979 assert.NoError(t, err) 980 981 for _, tc := range testCases { 982 t.Run(tc.description, func(t *testing.T) { 983 testChaincodeDeployNOK(t, tc.ccName, tc.ccVersion, tc.errMsg, v, policy) 984 }) 985 } 986 } 987 988 func testChaincodeDeployNOK(t *testing.T, ccName, ccVersion, errMsg string, v *Validator, policy []byte) { 989 res, err := createCCDataRWset(ccName, ccName, ccVersion, policy) 990 assert.NoError(t, err) 991 992 tx, err := createLSCCTx(ccName, ccVersion, lscc.DEPLOY, res) 993 if err != nil { 994 t.Fatalf("createTx returned err %s", err) 995 } 996 997 envBytes, err := protoutil.GetBytesEnvelope(tx) 998 if err != nil { 999 t.Fatalf("GetBytesEnvelope returned err %s", err) 1000 } 1001 1002 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}} 1003 err = v.Validate(b, "lscc", 0, 0, policy) 1004 assert.EqualError(t, err, errMsg) 1005 } 1006 1007 func TestValidateDeployWithCollection(t *testing.T) { 1008 state := make(map[string]map[string][]byte) 1009 state["lscc"] = make(map[string][]byte) 1010 1011 vs := &mocks.State{} 1012 vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) { 1013 if ns, ok := state[namespace]; ok { 1014 return [][]byte{ns[keys[0]]}, nil 1015 1016 } else { 1017 return nil, fmt.Errorf("could not retrieve namespace %s", namespace) 1018 } 1019 } 1020 sf := &mocks.StateFetcher{} 1021 sf.On("FetchState").Return(vs, nil) 1022 capabilities := &mocks.Capabilities{} 1023 capabilities.On("PrivateChannelData").Return(true) 1024 capabilities.On("V1_1Validation").Return(true) 1025 capabilities.On("V1_2Validation").Return(false) 1026 v := newCustomValidationInstance(sf, capabilities) 1027 1028 ccname := "mycc" 1029 ccver := "1" 1030 1031 collName1 := "mycollection1" 1032 collName2 := "mycollection2" 1033 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 1034 policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1035 var requiredPeerCount, maximumPeerCount int32 1036 var blockToLive uint64 1037 requiredPeerCount = 1 1038 maximumPeerCount = 2 1039 blockToLive = 1000 1040 coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1041 coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1042 1043 // Test 1: Deploy chaincode with a valid collection configs --> success 1044 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}} 1045 ccpBytes, err := proto.Marshal(ccp) 1046 assert.NoError(t, err) 1047 assert.NotNil(t, ccpBytes) 1048 1049 defaultPolicy, err := getSignedByMSPAdminPolicy(mspid) 1050 assert.NoError(t, err) 1051 res, err := createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1052 assert.NoError(t, err) 1053 1054 tx, err := createLSCCTxWithCollection(ccname, ccver, lscc.DEPLOY, res, defaultPolicy, ccpBytes) 1055 if err != nil { 1056 t.Fatalf("createTx returned err %s", err) 1057 } 1058 1059 envBytes, err := protoutil.GetBytesEnvelope(tx) 1060 if err != nil { 1061 t.Fatalf("GetBytesEnvelope returned err %s", err) 1062 } 1063 1064 // good path: signed by the right MSP 1065 policy, err := getSignedByMSPMemberPolicy(mspid) 1066 if err != nil { 1067 t.Fatalf("failed getting policy, err %s", err) 1068 } 1069 1070 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1071 err = v.Validate(b, "lscc", 0, 0, policy) 1072 assert.NoError(t, err) 1073 1074 // Test 2: Deploy the chaincode with duplicate collection configs --> no error as the 1075 // peer is not in V1_2Validation mode 1076 ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2, coll1}} 1077 ccpBytes, err = proto.Marshal(ccp) 1078 assert.NoError(t, err) 1079 assert.NotNil(t, ccpBytes) 1080 1081 res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1082 assert.NoError(t, err) 1083 1084 tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.DEPLOY, res, defaultPolicy, ccpBytes) 1085 if err != nil { 1086 t.Fatalf("createTx returned err %s", err) 1087 } 1088 1089 envBytes, err = protoutil.GetBytesEnvelope(tx) 1090 if err != nil { 1091 t.Fatalf("GetBytesEnvelope returned err %s", err) 1092 } 1093 1094 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1095 err = v.Validate(b, "lscc", 0, 0, policy) 1096 assert.NoError(t, err) 1097 1098 // Test 3: Once the V1_2Validation is enabled, validation should fail due to duplicate collection configs 1099 capabilities = &mocks.Capabilities{} 1100 capabilities.On("PrivateChannelData").Return(true) 1101 capabilities.On("V1_2Validation").Return(true) 1102 v = newCustomValidationInstance(sf, capabilities) 1103 1104 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1105 err = v.Validate(b, "lscc", 0, 0, policy) 1106 assert.EqualError(t, err, "collection-name: mycollection1 -- found duplicate collection configuration") 1107 } 1108 1109 func TestValidateDeployWithPolicies(t *testing.T) { 1110 state := make(map[string]map[string][]byte) 1111 state["lscc"] = make(map[string][]byte) 1112 1113 v := newValidationInstance(state) 1114 1115 ccname := "mycc" 1116 ccver := "1" 1117 1118 /*********************************************/ 1119 /* test 1: success with an accept-all policy */ 1120 /*********************************************/ 1121 1122 res, err := createCCDataRWset(ccname, ccname, ccver, policydsl.MarshaledAcceptAllPolicy) 1123 assert.NoError(t, err) 1124 1125 tx, err := createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 1126 if err != nil { 1127 t.Fatalf("createTx returned err %s", err) 1128 } 1129 1130 envBytes, err := protoutil.GetBytesEnvelope(tx) 1131 if err != nil { 1132 t.Fatalf("GetBytesEnvelope returned err %s", err) 1133 } 1134 1135 // good path: signed by the right MSP 1136 policy, err := getSignedByMSPMemberPolicy(mspid) 1137 if err != nil { 1138 t.Fatalf("failed getting policy, err %s", err) 1139 } 1140 1141 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1142 err = v.Validate(b, "lscc", 0, 0, policy) 1143 assert.NoError(t, err) 1144 1145 /********************************************/ 1146 /* test 2: failure with a reject-all policy */ 1147 /********************************************/ 1148 1149 res, err = createCCDataRWset(ccname, ccname, ccver, policydsl.MarshaledRejectAllPolicy) 1150 assert.NoError(t, err) 1151 1152 tx, err = createLSCCTx(ccname, ccver, lscc.DEPLOY, res) 1153 if err != nil { 1154 t.Fatalf("createTx returned err %s", err) 1155 } 1156 1157 envBytes, err = protoutil.GetBytesEnvelope(tx) 1158 if err != nil { 1159 t.Fatalf("GetBytesEnvelope returned err %s", err) 1160 } 1161 1162 // good path: signed by the right MSP 1163 policy, err = getSignedByMSPMemberPolicy(mspid) 1164 if err != nil { 1165 t.Fatalf("failed getting policy, err %s", err) 1166 } 1167 1168 b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1169 err = v.Validate(b, "lscc", 0, 0, policy) 1170 assert.EqualError(t, err, "chaincode instantiation policy violated, error signature set did not satisfy policy") 1171 } 1172 1173 func TestInvalidUpgrade(t *testing.T) { 1174 state := make(map[string]map[string][]byte) 1175 state["lscc"] = make(map[string][]byte) 1176 1177 v := newValidationInstance(state) 1178 1179 ccname := "mycc" 1180 ccver := "2" 1181 1182 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 1183 assert.NoError(t, err) 1184 1185 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1186 if err != nil { 1187 t.Fatalf("createTx returned err %s", err) 1188 } 1189 1190 envBytes, err := protoutil.GetBytesEnvelope(tx) 1191 if err != nil { 1192 t.Fatalf("GetBytesEnvelope returned err %s", err) 1193 } 1194 1195 // good path: signed by the right MSP 1196 policy, err := getSignedByMSPMemberPolicy(mspid) 1197 if err != nil { 1198 t.Fatalf("failed getting policy, err %s", err) 1199 } 1200 1201 b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1202 err = v.Validate(b, "lscc", 0, 0, policy) 1203 assert.EqualError(t, err, "Upgrading non-existent chaincode mycc") 1204 } 1205 1206 func TestValidateUpgradeOK(t *testing.T) { 1207 state := make(map[string]map[string][]byte) 1208 state["lscc"] = make(map[string][]byte) 1209 1210 v := newValidationInstance(state) 1211 1212 ccname := "mycc" 1213 ccver := "upgradeok" 1214 ccver = "2" 1215 1216 // policy signed by the right MSP 1217 policy, err := getSignedByMSPMemberPolicy(mspid) 1218 if err != nil { 1219 t.Fatalf("failed getting policy, err %s", err) 1220 } 1221 1222 // create lscc record 1223 cd := &ccprovider.ChaincodeData{ 1224 InstantiationPolicy: policy, 1225 } 1226 cdbytes, err := proto.Marshal(cd) 1227 if err != nil { 1228 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1229 } 1230 state["lscc"][ccname] = cdbytes 1231 1232 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 1233 assert.NoError(t, err) 1234 1235 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1236 if err != nil { 1237 t.Fatalf("createTx returned err %s", err) 1238 } 1239 1240 envBytes, err := protoutil.GetBytesEnvelope(tx) 1241 if err != nil { 1242 t.Fatalf("GetBytesEnvelope returned err %s", err) 1243 } 1244 1245 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1246 err = v.Validate(bl, "lscc", 0, 0, policy) 1247 assert.NoError(t, err) 1248 } 1249 1250 func TestInvalidateUpgradeBadVersion(t *testing.T) { 1251 state := make(map[string]map[string][]byte) 1252 state["lscc"] = make(map[string][]byte) 1253 1254 v := newValidationInstance(state) 1255 1256 ccname := "mycc" 1257 ccver := "upgradebadversion" 1258 1259 // policy signed by the right MSP 1260 policy, err := getSignedByMSPMemberPolicy(mspid) 1261 if err != nil { 1262 t.Fatalf("failed getting policy, err %s", err) 1263 } 1264 1265 // create lscc record 1266 cd := &ccprovider.ChaincodeData{ 1267 InstantiationPolicy: policy, 1268 Version: ccver, 1269 } 1270 cdbytes, err := proto.Marshal(cd) 1271 if err != nil { 1272 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1273 } 1274 state["lscc"][ccname] = cdbytes 1275 1276 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 1277 assert.NoError(t, err) 1278 1279 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1280 if err != nil { 1281 t.Fatalf("createTx returned err %s", err) 1282 } 1283 1284 envBytes, err := protoutil.GetBytesEnvelope(tx) 1285 if err != nil { 1286 t.Fatalf("GetBytesEnvelope returned err %s", err) 1287 } 1288 1289 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1290 err = v.Validate(bl, "lscc", 0, 0, policy) 1291 assert.EqualError(t, err, fmt.Sprintf("Existing version of the cc on the ledger (%s) should be different from the upgraded one", ccver)) 1292 } 1293 1294 func validateUpgradeWithCollection(t *testing.T, ccver string, V1_2Validation bool) { 1295 state := make(map[string]map[string][]byte) 1296 state["lscc"] = make(map[string][]byte) 1297 1298 vs := &mocks.State{} 1299 vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) { 1300 if ns, ok := state[namespace]; ok { 1301 return [][]byte{ns[keys[0]]}, nil 1302 1303 } else { 1304 return nil, fmt.Errorf("could not retrieve namespace %s", namespace) 1305 } 1306 } 1307 sf := &mocks.StateFetcher{} 1308 sf.On("FetchState").Return(vs, nil) 1309 capabilities := &mocks.Capabilities{} 1310 capabilities.On("PrivateChannelData").Return(true) 1311 capabilities.On("V1_1Validation").Return(true) 1312 capabilities.On("V1_2Validation").Return(V1_2Validation) 1313 v := newCustomValidationInstance(sf, capabilities) 1314 1315 ccname := "mycc" 1316 ccver = "2" 1317 1318 policy, err := getSignedByMSPMemberPolicy(mspid) 1319 if err != nil { 1320 t.Fatalf("failed getting policy, err %s", err) 1321 } 1322 1323 // create lscc record 1324 cd := &ccprovider.ChaincodeData{ 1325 InstantiationPolicy: policy, 1326 } 1327 cdbytes, err := proto.Marshal(cd) 1328 if err != nil { 1329 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1330 } 1331 state["lscc"][ccname] = cdbytes 1332 1333 collName1 := "mycollection1" 1334 collName2 := "mycollection2" 1335 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 1336 policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1337 var requiredPeerCount, maximumPeerCount int32 1338 var blockToLive uint64 1339 requiredPeerCount = 1 1340 maximumPeerCount = 2 1341 blockToLive = 1000 1342 coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1343 coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1344 1345 // Test 1: Valid Collection Config in the upgrade. 1346 // V1_2Validation enabled: success 1347 // V1_2Validation disable: fail (as no collection updates are allowed) 1348 // Note: We might change V1_2Validation with CollectionUpdate capability 1349 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}} 1350 ccpBytes, err := proto.Marshal(ccp) 1351 assert.NoError(t, err) 1352 assert.NotNil(t, ccpBytes) 1353 1354 defaultPolicy, err := getSignedByMSPAdminPolicy(mspid) 1355 assert.NoError(t, err) 1356 res, err := createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1357 assert.NoError(t, err) 1358 1359 tx, err := createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes) 1360 if err != nil { 1361 t.Fatalf("createTx returned err %s", err) 1362 } 1363 1364 envBytes, err := protoutil.GetBytesEnvelope(tx) 1365 if err != nil { 1366 t.Fatalf("GetBytesEnvelope returned err %s", err) 1367 } 1368 1369 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1370 err = v.Validate(bl, "lscc", 0, 0, policy) 1371 if V1_2Validation { 1372 assert.NoError(t, err) 1373 } else { 1374 assert.Error(t, err, "LSCC can only issue a single putState upon deploy/upgrade") 1375 } 1376 1377 state["lscc"][privdata.BuildCollectionKVSKey(ccname)] = ccpBytes 1378 1379 if V1_2Validation { 1380 ccver = "3" 1381 1382 collName3 := "mycollection3" 1383 coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1384 1385 // Test 2: some existing collections are missing in the updated config and peer in 1386 // V1_2Validation mode --> error 1387 ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll3}} 1388 ccpBytes, err = proto.Marshal(ccp) 1389 assert.NoError(t, err) 1390 assert.NotNil(t, ccpBytes) 1391 1392 res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1393 assert.NoError(t, err) 1394 1395 tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes) 1396 if err != nil { 1397 t.Fatalf("createTx returned err %s", err) 1398 } 1399 1400 envBytes, err = protoutil.GetBytesEnvelope(tx) 1401 if err != nil { 1402 t.Fatalf("GetBytesEnvelope returned err %s", err) 1403 } 1404 1405 bl = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1406 err = v.Validate(bl, "lscc", 0, 0, policy) 1407 assert.Error(t, err, "Some existing collection configurations are missing in the new collection configuration package") 1408 1409 ccver = "3" 1410 1411 // Test 3: some existing collections are missing in the updated config and peer in 1412 // V1_2Validation mode --> error 1413 ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll3}} 1414 ccpBytes, err = proto.Marshal(ccp) 1415 assert.NoError(t, err) 1416 assert.NotNil(t, ccpBytes) 1417 1418 res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1419 assert.NoError(t, err) 1420 1421 tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes) 1422 if err != nil { 1423 t.Fatalf("createTx returned err %s", err) 1424 } 1425 1426 envBytes, err = protoutil.GetBytesEnvelope(tx) 1427 if err != nil { 1428 t.Fatalf("GetBytesEnvelope returned err %s", err) 1429 } 1430 1431 bl = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1432 err = v.Validate(bl, "lscc", 0, 0, policy) 1433 assert.Error(t, err, "existing collection named mycollection2 is missing in the new collection configuration package") 1434 1435 ccver = "3" 1436 1437 // Test 4: valid collection config config and peer in V1_2Validation mode --> success 1438 ccp = &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2, coll3}} 1439 ccpBytes, err = proto.Marshal(ccp) 1440 assert.NoError(t, err) 1441 assert.NotNil(t, ccpBytes) 1442 1443 res, err = createCCDataRWsetWithCollection(ccname, ccname, ccver, defaultPolicy, ccpBytes) 1444 assert.NoError(t, err) 1445 1446 tx, err = createLSCCTxWithCollection(ccname, ccver, lscc.UPGRADE, res, defaultPolicy, ccpBytes) 1447 if err != nil { 1448 t.Fatalf("createTx returned err %s", err) 1449 } 1450 1451 envBytes, err = protoutil.GetBytesEnvelope(tx) 1452 if err != nil { 1453 t.Fatalf("GetBytesEnvelope returned err %s", err) 1454 } 1455 1456 bl = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1457 err = v.Validate(bl, "lscc", 0, 0, policy) 1458 assert.NoError(t, err) 1459 } 1460 } 1461 1462 func TestValidateUpgradeWithCollection(t *testing.T) { 1463 // with V1_2Validation enabled 1464 validateUpgradeWithCollection(t, "v12-validation-enabled", true) 1465 // with V1_2Validation disabled 1466 validateUpgradeWithCollection(t, "v12-validation-disabled", false) 1467 } 1468 1469 func TestValidateUpgradeWithPoliciesOK(t *testing.T) { 1470 state := make(map[string]map[string][]byte) 1471 state["lscc"] = make(map[string][]byte) 1472 1473 v := newValidationInstance(state) 1474 1475 ccname := "mycc" 1476 ccver := "upgradewithpoliciesok" 1477 1478 // policy signed by the right MSP 1479 policy, err := getSignedByMSPMemberPolicy(mspid) 1480 if err != nil { 1481 t.Fatalf("failed getting policy, err %s", err) 1482 } 1483 1484 // create lscc record 1485 cd := &ccprovider.ChaincodeData{ 1486 InstantiationPolicy: policy, 1487 } 1488 cdbytes, err := proto.Marshal(cd) 1489 if err != nil { 1490 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1491 } 1492 state["lscc"][ccname] = cdbytes 1493 1494 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 1495 assert.NoError(t, err) 1496 1497 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1498 if err != nil { 1499 t.Fatalf("createTx returned err %s", err) 1500 } 1501 1502 envBytes, err := protoutil.GetBytesEnvelope(tx) 1503 if err != nil { 1504 t.Fatalf("GetBytesEnvelope returned err %s", err) 1505 } 1506 1507 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1508 err = v.Validate(bl, "lscc", 0, 0, policy) 1509 assert.NoError(t, err) 1510 } 1511 1512 func TestValidateUpgradeWithNewFailAllIP(t *testing.T) { 1513 // we're testing upgrade. 1514 // In particular, we want to test the scenario where the upgrade 1515 // complies with the instantiation policy of the current version 1516 // BUT NOT the instantiation policy of the new version. For this 1517 // reason we first deploy a cc with IP which is equal to the AcceptAllPolicy 1518 // and then try to upgrade with a cc with the RejectAllPolicy. 1519 // We run this test twice, once with the V11 capability (and expect 1520 // a failure) and once without (and we expect success). 1521 1522 validateUpgradeWithNewFailAllIP(t, "v11-capabilityenabled", true, true) 1523 validateUpgradeWithNewFailAllIP(t, "v11-capabilitydisabled", false, false) 1524 } 1525 1526 func validateUpgradeWithNewFailAllIP(t *testing.T, ccver string, v11capability, expecterr bool) { 1527 state := make(map[string]map[string][]byte) 1528 state["lscc"] = make(map[string][]byte) 1529 1530 vs := &mocks.State{} 1531 vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) { 1532 if ns, ok := state[namespace]; ok { 1533 return [][]byte{ns[keys[0]]}, nil 1534 1535 } else { 1536 return nil, fmt.Errorf("could not retrieve namespace %s", namespace) 1537 } 1538 } 1539 sf := &mocks.StateFetcher{} 1540 sf.On("FetchState").Return(vs, nil) 1541 capabilities := &mocks.Capabilities{} 1542 capabilities.On("PrivateChannelData").Return(true) 1543 capabilities.On("V1_1Validation").Return(v11capability) 1544 capabilities.On("V1_2Validation").Return(false) 1545 v := newCustomValidationInstance(sf, capabilities) 1546 1547 ccname := "mycc" 1548 ccver = "2" 1549 1550 // create lscc record with accept all instantiation policy 1551 ipbytes, err := proto.Marshal(policydsl.AcceptAllPolicy) 1552 if err != nil { 1553 t.Fatalf("Failed to marshal AcceptAllPolicy: %s", err) 1554 } 1555 cd := &ccprovider.ChaincodeData{ 1556 InstantiationPolicy: ipbytes, 1557 } 1558 cdbytes, err := proto.Marshal(cd) 1559 if err != nil { 1560 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1561 } 1562 state["lscc"][ccname] = cdbytes 1563 1564 // now we upgrade, with v 2 of the same cc, with the crucial difference that it has a reject all IP 1565 ccver = ccver + ".2" 1566 1567 simresres, err := createCCDataRWset(ccname, ccname, ccver, 1568 policydsl.MarshaledRejectAllPolicy, // here's where we specify the IP of the upgraded cc 1569 ) 1570 assert.NoError(t, err) 1571 1572 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1573 if err != nil { 1574 t.Fatalf("createTx returned err %s", err) 1575 } 1576 1577 envBytes, err := protoutil.GetBytesEnvelope(tx) 1578 if err != nil { 1579 t.Fatalf("GetBytesEnvelope returned err %s", err) 1580 } 1581 1582 policy, err := getSignedByMSPMemberPolicy(mspid) 1583 if err != nil { 1584 t.Fatalf("failed getting policy, err %s", err) 1585 } 1586 1587 // execute the upgrade tx 1588 if expecterr { 1589 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1590 err = v.Validate(bl, "lscc", 0, 0, policy) 1591 assert.Error(t, err) 1592 } else { 1593 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1594 err = v.Validate(bl, "lscc", 0, 0, policy) 1595 assert.NoError(t, err) 1596 } 1597 } 1598 1599 func TestValidateUpgradeWithPoliciesFail(t *testing.T) { 1600 ccname := "mycc" 1601 ccver := "upgradewithpoliciesfail" 1602 1603 state := make(map[string]map[string][]byte) 1604 state["lscc"] = make(map[string][]byte) 1605 1606 v := newValidationInstance(state) 1607 1608 // create lscc record with reject all instantiation policy 1609 ipbytes, err := proto.Marshal(policydsl.RejectAllPolicy) 1610 if err != nil { 1611 t.Fatalf("Failed to marshal RejectAllPolicy: %s", err) 1612 } 1613 cd := &ccprovider.ChaincodeData{ 1614 InstantiationPolicy: ipbytes, 1615 Version: ccver, 1616 } 1617 cdbytes, err := proto.Marshal(cd) 1618 if err != nil { 1619 t.Fatalf("Failed to marshal ChaincodeData: %s", err) 1620 } 1621 state["lscc"][ccname] = cdbytes 1622 1623 ccver = "2" 1624 simresres, err := createCCDataRWset(ccname, ccname, ccver, nil) 1625 assert.NoError(t, err) 1626 1627 tx, err := createLSCCTx(ccname, ccver, lscc.UPGRADE, simresres) 1628 if err != nil { 1629 t.Fatalf("createTx returned err %s", err) 1630 } 1631 1632 envBytes, err := protoutil.GetBytesEnvelope(tx) 1633 if err != nil { 1634 t.Fatalf("GetBytesEnvelope returned err %s", err) 1635 } 1636 1637 // good path: signed by the right MSP 1638 policy, err := getSignedByMSPMemberPolicy(mspid) 1639 if err != nil { 1640 t.Fatalf("failed getting policy, err %s", err) 1641 } 1642 1643 bl := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}} 1644 err = v.Validate(bl, "lscc", 0, 0, policy) 1645 assert.EqualError(t, err, "chaincode instantiation policy violated, error signature set did not satisfy policy") 1646 } 1647 1648 var id msp.SigningIdentity 1649 var sid []byte 1650 var mspid string 1651 var chainId string = "testchannelid" 1652 1653 type mockPolicyChecker struct{} 1654 1655 func (c *mockPolicyChecker) CheckPolicy(channelID, policyName string, signedProp *peer.SignedProposal) error { 1656 return nil 1657 } 1658 1659 func (c *mockPolicyChecker) CheckPolicyBySignedData(channelID, policyName string, sd []*protoutil.SignedData) error { 1660 return nil 1661 } 1662 1663 func (c *mockPolicyChecker) CheckPolicyNoChannel(policyName string, signedProp *peer.SignedProposal) error { 1664 return nil 1665 } 1666 1667 func createCollectionConfig(collectionName string, signaturePolicyEnvelope *common.SignaturePolicyEnvelope, 1668 requiredPeerCount int32, maximumPeerCount int32, blockToLive uint64, 1669 ) *peer.CollectionConfig { 1670 signaturePolicy := &peer.CollectionPolicyConfig_SignaturePolicy{ 1671 SignaturePolicy: signaturePolicyEnvelope, 1672 } 1673 accessPolicy := &peer.CollectionPolicyConfig{ 1674 Payload: signaturePolicy, 1675 } 1676 1677 return &peer.CollectionConfig{ 1678 Payload: &peer.CollectionConfig_StaticCollectionConfig{ 1679 StaticCollectionConfig: &peer.StaticCollectionConfig{ 1680 Name: collectionName, 1681 MemberOrgsPolicy: accessPolicy, 1682 RequiredPeerCount: requiredPeerCount, 1683 MaximumPeerCount: maximumPeerCount, 1684 BlockToLive: blockToLive, 1685 }, 1686 }, 1687 } 1688 } 1689 1690 func testValidateCollection(t *testing.T, v *Validator, collectionConfigs []*peer.CollectionConfig, cdRWSet *ccprovider.ChaincodeData, 1691 lsccFunc string, ac channelconfig.ApplicationCapabilities, chid string, 1692 ) error { 1693 ccp := &peer.CollectionConfigPackage{Config: collectionConfigs} 1694 ccpBytes, err := proto.Marshal(ccp) 1695 assert.NoError(t, err) 1696 assert.NotNil(t, ccpBytes) 1697 1698 lsccargs := [][]byte{nil, nil, nil, nil, nil, ccpBytes} 1699 rwset := &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: cdRWSet.Name}, {Key: privdata.BuildCollectionKVSKey(cdRWSet.Name), Value: ccpBytes}}} 1700 1701 err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid) 1702 return err 1703 1704 } 1705 1706 func TestValidateRWSetAndCollectionForDeploy(t *testing.T) { 1707 var err error 1708 chid := "ch" 1709 ccid := "mycc" 1710 ccver := "1.0" 1711 cdRWSet := &ccprovider.ChaincodeData{Name: ccid, Version: ccver} 1712 1713 state := make(map[string]map[string][]byte) 1714 state["lscc"] = make(map[string][]byte) 1715 1716 v := newValidationInstance(state) 1717 1718 ac := capabilities.NewApplicationProvider(map[string]*common.Capability{ 1719 capabilities.ApplicationV1_1: {}, 1720 }) 1721 1722 lsccFunc := lscc.DEPLOY 1723 // Test 1: More than two entries in the rwset -> error 1724 rwset := &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: "b"}, {Key: "c"}}} 1725 err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid) 1726 assert.EqualError(t, err, "LSCC can only issue one or two putState upon deploy") 1727 1728 // Test 2: Invalid key for the collection config package -> error 1729 rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: "b"}}} 1730 err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid) 1731 assert.EqualError(t, err, "invalid key for the collection of chaincode mycc:1.0; expected 'mycc~collection', received 'b'") 1732 1733 // Test 3: No collection config package -> success 1734 rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}}} 1735 err = v.validateRWSetAndCollection(rwset, cdRWSet, nil, lsccFunc, ac, chid) 1736 assert.NoError(t, err) 1737 1738 lsccargs := [][]byte{nil, nil, nil, nil, nil, nil} 1739 err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid) 1740 assert.NoError(t, err) 1741 1742 // Test 4: Valid key for the collection config package -> success 1743 rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: privdata.BuildCollectionKVSKey(ccid)}}} 1744 err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid) 1745 assert.NoError(t, err) 1746 1747 // Test 5: Collection configuration of the lscc args doesn't match the rwset 1748 lsccargs = [][]byte{nil, nil, nil, nil, nil, []byte("barf")} 1749 err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid) 1750 assert.EqualError(t, err, "collection configuration arguments supplied for chaincode mycc:1.0 do not match the configuration in the lscc writeset") 1751 1752 // Test 6: Invalid collection config package -> error 1753 rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: ccid}, {Key: privdata.BuildCollectionKVSKey("mycc"), Value: []byte("barf")}}} 1754 err = v.validateRWSetAndCollection(rwset, cdRWSet, lsccargs, lsccFunc, ac, chid) 1755 assert.EqualError(t, err, "invalid collection configuration supplied for chaincode mycc:1.0") 1756 1757 // Test 7: Valid collection config package -> success 1758 collName1 := "mycollection1" 1759 collName2 := "mycollection2" 1760 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 1761 policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1762 var requiredPeerCount, maximumPeerCount int32 1763 var blockToLive uint64 1764 requiredPeerCount = 1 1765 maximumPeerCount = 2 1766 blockToLive = 10000 1767 coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1768 coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1769 1770 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2}, cdRWSet, lsccFunc, ac, chid) 1771 assert.NoError(t, err) 1772 1773 // Test 8: Duplicate collections in the collection config package -> success as the peer is in v1.1 validation mode 1774 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll1}, cdRWSet, lsccFunc, ac, chid) 1775 assert.NoError(t, err) 1776 1777 // Test 9: requiredPeerCount > maximumPeerCount -> success as the peer is in v1.1 validation mode 1778 collName3 := "mycollection3" 1779 requiredPeerCount = 2 1780 maximumPeerCount = 1 1781 blockToLive = 10000 1782 coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1783 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid) 1784 assert.NoError(t, err) 1785 1786 // Enable v1.2 validation mode 1787 ac = capabilities.NewApplicationProvider(map[string]*common.Capability{ 1788 capabilities.ApplicationV1_2: {}, 1789 }) 1790 1791 // Test 10: Duplicate collections in the collection config package -> error 1792 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll1}, cdRWSet, lsccFunc, ac, chid) 1793 assert.EqualError(t, err, "collection-name: mycollection1 -- found duplicate collection configuration") 1794 1795 // Test 11: requiredPeerCount < 0 -> error 1796 requiredPeerCount = -2 1797 maximumPeerCount = 1 1798 blockToLive = 10000 1799 coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1800 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid) 1801 assert.EqualError(t, err, "collection-name: mycollection3 -- requiredPeerCount (-2) cannot be less than zero", 1802 collName3, maximumPeerCount, requiredPeerCount) 1803 1804 // Test 11: requiredPeerCount > maximumPeerCount -> error 1805 requiredPeerCount = 2 1806 maximumPeerCount = 1 1807 blockToLive = 10000 1808 coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1809 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid) 1810 assert.EqualError(t, err, "collection-name: mycollection3 -- maximum peer count (1) cannot be less than the required peer count (2)") 1811 1812 // Test 12: AND concatenation of orgs in access policy -> error 1813 requiredPeerCount = 1 1814 maximumPeerCount = 2 1815 policyEnvelope = policydsl.Envelope(policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1816 coll3 = createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1817 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll3}, cdRWSet, lsccFunc, ac, chid) 1818 assert.EqualError(t, err, "collection-name: mycollection3 -- error in member org policy: signature policy is not an OR concatenation, NOutOf 2") 1819 1820 // Test 13: deploy with existing collection config on the ledger -> error 1821 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1}} 1822 ccpBytes, err := proto.Marshal(ccp) 1823 assert.NoError(t, err) 1824 state["lscc"][privdata.BuildCollectionKVSKey(ccid)] = ccpBytes 1825 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid) 1826 assert.EqualError(t, err, "collection data should not exist for chaincode mycc:1.0") 1827 } 1828 1829 func TestValidateRWSetAndCollectionForUpgrade(t *testing.T) { 1830 chid := "ch" 1831 ccid := "mycc" 1832 ccver := "1.0" 1833 cdRWSet := &ccprovider.ChaincodeData{Name: ccid, Version: ccver} 1834 1835 state := make(map[string]map[string][]byte) 1836 state["lscc"] = make(map[string][]byte) 1837 1838 v := newValidationInstance(state) 1839 1840 ac := capabilities.NewApplicationProvider(map[string]*common.Capability{ 1841 capabilities.ApplicationV1_2: {}, 1842 }) 1843 1844 lsccFunc := lscc.UPGRADE 1845 1846 collName1 := "mycollection1" 1847 collName2 := "mycollection2" 1848 collName3 := "mycollection3" 1849 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 1850 policyEnvelope := policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 1851 var requiredPeerCount, maximumPeerCount int32 1852 var blockToLive uint64 1853 requiredPeerCount = 1 1854 maximumPeerCount = 2 1855 blockToLive = 3 1856 coll1 := createCollectionConfig(collName1, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1857 coll2 := createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1858 coll3 := createCollectionConfig(collName3, policyEnvelope, requiredPeerCount, maximumPeerCount, blockToLive) 1859 1860 ccp := &peer.CollectionConfigPackage{Config: []*peer.CollectionConfig{coll1, coll2}} 1861 ccpBytes, err := proto.Marshal(ccp) 1862 assert.NoError(t, err) 1863 1864 // Test 1: no existing collection config package -> success 1865 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid) 1866 assert.NoError(t, err) 1867 1868 state["lscc"][privdata.BuildCollectionKVSKey(ccid)] = ccpBytes 1869 1870 // Test 2: exactly same as the existing collection config package -> success 1871 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2}, cdRWSet, lsccFunc, ac, chid) 1872 assert.NoError(t, err) 1873 1874 // Test 3: missing one existing collection (check based on the length) -> error 1875 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1}, cdRWSet, lsccFunc, ac, chid) 1876 assert.EqualError(t, err, "the following existing collections are missing in the new collection configuration package: [mycollection2]") 1877 1878 // Test 4: missing one existing collection (check based on the collection names) -> error 1879 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll3}, cdRWSet, lsccFunc, ac, chid) 1880 assert.EqualError(t, err, "the following existing collections are missing in the new collection configuration package: [mycollection2]") 1881 1882 // Test 5: adding a new collection along with the existing collections -> success 1883 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid) 1884 assert.NoError(t, err) 1885 1886 newBlockToLive := blockToLive + 1 1887 coll2 = createCollectionConfig(collName2, policyEnvelope, requiredPeerCount, maximumPeerCount, newBlockToLive) 1888 1889 // Test 6: modify the BlockToLive in an existing collection -> error 1890 err = testValidateCollection(t, v, []*peer.CollectionConfig{coll1, coll2, coll3}, cdRWSet, lsccFunc, ac, chid) 1891 assert.EqualError(t, err, "the BlockToLive in the following existing collections must not be modified: [mycollection2]") 1892 } 1893 1894 var mockMSPIDGetter = func(cid string) []string { 1895 return []string{"SampleOrg"} 1896 } 1897 1898 func TestMain(m *testing.M) { 1899 code := -1 1900 defer func() { 1901 os.Exit(code) 1902 }() 1903 testDir, err := ioutil.TempDir("", "v1.2-validation") 1904 if err != nil { 1905 fmt.Printf("Could not create temp dir: %s", err) 1906 return 1907 } 1908 defer os.RemoveAll(testDir) 1909 ccprovider.SetChaincodesPath(testDir) 1910 1911 // setup the MSP manager so that we can sign/verify 1912 msptesttools.LoadMSPSetupForTesting() 1913 1914 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1915 if err != nil { 1916 fmt.Printf("Initialize cryptoProvider bccsp failed: %s", cryptoProvider) 1917 return 1918 } 1919 1920 id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity() 1921 if err != nil { 1922 fmt.Printf("GetSigningIdentity failed with err %s", err) 1923 return 1924 } 1925 1926 sid, err = id.Serialize() 1927 if err != nil { 1928 fmt.Printf("Serialize failed with err %s", err) 1929 return 1930 } 1931 1932 // determine the MSP identifier for the first MSP in the default chain 1933 var msp msp.MSP 1934 mspMgr := mspmgmt.GetManagerForChain(chainId) 1935 msps, err := mspMgr.GetMSPs() 1936 if err != nil { 1937 fmt.Printf("Could not retrieve the MSPs for the chain manager, err %s", err) 1938 return 1939 } 1940 if len(msps) == 0 { 1941 fmt.Printf("At least one MSP was expected") 1942 return 1943 } 1944 for _, m := range msps { 1945 msp = m 1946 break 1947 } 1948 mspid, err = msp.GetIdentifier() 1949 if err != nil { 1950 fmt.Printf("Failure getting the msp identifier, err %s", err) 1951 return 1952 } 1953 1954 // also set the MSP for the "test" chain 1955 mspmgmt.XXXSetMSPManager("mycc", mspmgmt.GetManagerForChain("testchannelid")) 1956 1957 code = m.Run() 1958 } 1959 1960 func TestInValidCollectionName(t *testing.T) { 1961 validNames := []string{"collection1", "collection_2"} 1962 inValidNames := []string{"collection.1", "collection%2", ""} 1963 1964 for _, name := range validNames { 1965 assert.NoError(t, validateCollectionName(name), "Testing for name = "+name) 1966 } 1967 for _, name := range inValidNames { 1968 assert.Error(t, validateCollectionName(name), "Testing for name = "+name) 1969 } 1970 }