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