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