github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/config_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package configtx 8 9 import ( 10 "bytes" 11 "errors" 12 "fmt" 13 "github.com/hellobchain/newcryptosm/ecdsa" 14 "github.com/hellobchain/third_party/hyperledger/fabric-config/protolator" 15 "testing" 16 17 "github.com/golang/protobuf/proto" 18 cb "github.com/hyperledger/fabric-protos-go/common" 19 . "github.com/onsi/gomega" 20 ) 21 22 func TestNewConfigTx(t *testing.T) { 23 t.Parallel() 24 25 gt := NewGomegaWithT(t) 26 27 channel, _, err := baseApplicationChannelGroup(t) 28 gt.Expect(err).NotTo(HaveOccurred()) 29 30 original := &cb.Config{ 31 ChannelGroup: channel, 32 } 33 34 c := New(original) 35 gt.Expect(proto.Equal(c.OriginalConfig(), original)).To(BeTrue()) 36 gt.Expect(proto.Equal(c.UpdatedConfig(), original)).To(BeTrue()) 37 38 err = c.Application().AddCapability("fake-capability") 39 gt.Expect(err).NotTo(HaveOccurred()) 40 41 gt.Expect(proto.Equal(c.OriginalConfig(), original)).To(BeTrue()) 42 gt.Expect(proto.Equal(c.UpdatedConfig(), original)).To(BeFalse()) 43 } 44 45 func TestNewCreateChannelTx(t *testing.T) { 46 t.Parallel() 47 48 gt := NewGomegaWithT(t) 49 50 // The TwoOrgsChannel profile is defined in standard_networks.go under the BasicSolo configuration 51 // configtxgen -profile TwoOrgsChannel -channelID testChannel 52 expectedEnvelopeJSON := `{ 53 "payload": { 54 "data": { 55 "config_update": { 56 "channel_id": "testchannel", 57 "isolated_data": {}, 58 "read_set": { 59 "groups": { 60 "Application": { 61 "groups": { 62 "Org1": { 63 "groups": {}, 64 "mod_policy": "", 65 "policies": {}, 66 "values": {}, 67 "version": "0" 68 }, 69 "Org2": { 70 "groups": {}, 71 "mod_policy": "", 72 "policies": {}, 73 "values": {}, 74 "version": "0" 75 } 76 }, 77 "mod_policy": "", 78 "policies": {}, 79 "values": {}, 80 "version": "0" 81 } 82 }, 83 "mod_policy": "", 84 "policies": {}, 85 "values": { 86 "Consortium": { 87 "mod_policy": "", 88 "value": null, 89 "version": "0" 90 } 91 }, 92 "version": "0" 93 }, 94 "write_set": { 95 "groups": { 96 "Application": { 97 "groups": { 98 "Org1": { 99 "groups": {}, 100 "mod_policy": "", 101 "policies": {}, 102 "values": {}, 103 "version": "0" 104 }, 105 "Org2": { 106 "groups": {}, 107 "mod_policy": "", 108 "policies": {}, 109 "values": {}, 110 "version": "0" 111 } 112 }, 113 "mod_policy": "Admins", 114 "policies": { 115 "Admins": { 116 "mod_policy": "Admins", 117 "policy": { 118 "type": 3, 119 "value": { 120 "rule": "MAJORITY", 121 "sub_policy": "Admins" 122 } 123 }, 124 "version": "0" 125 }, 126 "Readers": { 127 "mod_policy": "Admins", 128 "policy": { 129 "type": 3, 130 "value": { 131 "rule": "ANY", 132 "sub_policy": "Readers" 133 } 134 }, 135 "version": "0" 136 }, 137 "Writers": { 138 "mod_policy": "Admins", 139 "policy": { 140 "type": 3, 141 "value": { 142 "rule": "ANY", 143 "sub_policy": "Writers" 144 } 145 }, 146 "version": "0" 147 } 148 }, 149 "values": { 150 "Capabilities": { 151 "mod_policy": "Admins", 152 "value": { 153 "capabilities": { 154 "V1_3": {} 155 } 156 }, 157 "version": "0" 158 }, 159 "ACLs": { 160 "mod_policy": "Admins", 161 "value": { 162 "acls": { 163 "acl1": { 164 "policy_ref": "hi" 165 } 166 } 167 }, 168 "version": "0" 169 } 170 }, 171 "version": "1" 172 } 173 }, 174 "mod_policy": "", 175 "policies": {}, 176 "values": { 177 "Consortium": { 178 "mod_policy": "", 179 "value": { 180 "name": "SampleConsortium" 181 }, 182 "version": "0" 183 } 184 }, 185 "version": "0" 186 } 187 }, 188 "signatures": [] 189 }, 190 "header": { 191 "channel_header": { 192 "channel_id": "testchannel", 193 "epoch": "0", 194 "extension": null, 195 "timestamp": "2020-02-17T15:49:56Z", 196 "tls_cert_hash": null, 197 "tx_id": "", 198 "type": 2, 199 "version": 0 200 }, 201 "signature_header": null 202 } 203 }, 204 "signature": null 205 }` 206 207 profile := baseProfile(t) 208 209 // creating a create channel transaction 210 marshaledCreateChannelTx, err := NewMarshaledCreateChannelTx(profile, "testchannel") 211 gt.Expect(err).NotTo(HaveOccurred()) 212 envelope, err := NewEnvelope(marshaledCreateChannelTx) 213 gt.Expect(err).NotTo(HaveOccurred()) 214 gt.Expect(envelope).ToNot(BeNil()) 215 216 // Unmarshaling actual and expected envelope to set 217 // the expected timestamp to the actual timestamp 218 expectedEnvelope := cb.Envelope{} 219 err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedEnvelopeJSON), &expectedEnvelope) 220 gt.Expect(err).NotTo(HaveOccurred()) 221 222 expectedPayload := cb.Payload{} 223 err = proto.Unmarshal(expectedEnvelope.Payload, &expectedPayload) 224 gt.Expect(err).NotTo(HaveOccurred()) 225 226 expectedHeader := cb.ChannelHeader{} 227 err = proto.Unmarshal(expectedPayload.Header.ChannelHeader, &expectedHeader) 228 gt.Expect(err).NotTo(HaveOccurred()) 229 230 expectedData := cb.ConfigUpdateEnvelope{} 231 err = proto.Unmarshal(expectedPayload.Data, &expectedData) 232 gt.Expect(err).NotTo(HaveOccurred()) 233 234 expectedConfigUpdate := cb.ConfigUpdate{} 235 err = proto.Unmarshal(expectedData.ConfigUpdate, &expectedConfigUpdate) 236 gt.Expect(err).NotTo(HaveOccurred()) 237 238 actualPayload := cb.Payload{} 239 err = proto.Unmarshal(envelope.Payload, &actualPayload) 240 gt.Expect(err).NotTo(HaveOccurred()) 241 242 actualHeader := cb.ChannelHeader{} 243 err = proto.Unmarshal(actualPayload.Header.ChannelHeader, &actualHeader) 244 gt.Expect(err).NotTo(HaveOccurred()) 245 246 actualData := cb.ConfigUpdateEnvelope{} 247 err = proto.Unmarshal(actualPayload.Data, &actualData) 248 gt.Expect(err).NotTo(HaveOccurred()) 249 250 actualConfigUpdate := cb.ConfigUpdate{} 251 err = proto.Unmarshal(actualData.ConfigUpdate, &actualConfigUpdate) 252 gt.Expect(err).NotTo(HaveOccurred()) 253 254 gt.Expect(actualConfigUpdate).To(Equal(expectedConfigUpdate)) 255 256 // setting timestamps to match in ConfigUpdate 257 actualTimestamp := actualHeader.Timestamp 258 259 expectedHeader.Timestamp = actualTimestamp 260 261 expectedData.ConfigUpdate = actualData.ConfigUpdate 262 263 // Remarshaling envelopes with updated timestamps 264 expectedPayload.Data, err = proto.Marshal(&expectedData) 265 gt.Expect(err).NotTo(HaveOccurred()) 266 267 expectedPayload.Header.ChannelHeader, err = proto.Marshal(&expectedHeader) 268 gt.Expect(err).NotTo(HaveOccurred()) 269 270 expectedEnvelope.Payload, err = proto.Marshal(&expectedPayload) 271 gt.Expect(err).NotTo(HaveOccurred()) 272 273 gt.Expect(envelope).To(Equal(&expectedEnvelope)) 274 } 275 276 func TestNewCreateChannelTxFailure(t *testing.T) { 277 t.Parallel() 278 279 tests := []struct { 280 testName string 281 profileMod func() Channel 282 channelID string 283 err error 284 }{ 285 { 286 testName: "When creating the default config template with no Admins policies defined fails", 287 profileMod: func() Channel { 288 profile := baseProfile(t) 289 delete(profile.Application.Policies, AdminsPolicyKey) 290 return profile 291 }, 292 channelID: "testchannel", 293 err: errors.New("creating default config template: failed to create application group: " + 294 "no Admins policy defined"), 295 }, 296 { 297 testName: "When creating the default config template with no Readers policies defined fails", 298 profileMod: func() Channel { 299 profile := baseProfile(t) 300 delete(profile.Application.Policies, ReadersPolicyKey) 301 return profile 302 }, 303 channelID: "testchannel", 304 err: errors.New("creating default config template: failed to create application group: " + 305 "no Readers policy defined"), 306 }, 307 { 308 testName: "When creating the default config template with no Writers policies defined fails", 309 profileMod: func() Channel { 310 profile := baseProfile(t) 311 delete(profile.Application.Policies, WritersPolicyKey) 312 return profile 313 }, 314 channelID: "testchannel", 315 err: errors.New("creating default config template: failed to create application group: " + 316 "no Writers policy defined"), 317 }, 318 { 319 testName: "When creating the default config template with an invalid ImplicitMetaPolicy rule fails", 320 profileMod: func() Channel { 321 profile := baseProfile(t) 322 profile.Application.Policies[ReadersPolicyKey] = Policy{ 323 Rule: "ALL", 324 Type: ImplicitMetaPolicyType, 325 } 326 return profile 327 }, 328 channelID: "testchannel", 329 err: errors.New("creating default config template: failed to create application group: " + 330 "invalid implicit meta policy rule: 'ALL': expected two space separated " + 331 "tokens, but got 1"), 332 }, 333 { 334 testName: "When creating the default config template with an invalid ImplicitMetaPolicy rule fails", 335 profileMod: func() Channel { 336 profile := baseProfile(t) 337 profile.Application.Policies[ReadersPolicyKey] = Policy{ 338 Rule: "ANYY Readers", 339 Type: ImplicitMetaPolicyType, 340 } 341 return profile 342 }, 343 channelID: "testchannel", 344 err: errors.New("creating default config template: failed to create application group: " + 345 "invalid implicit meta policy rule: 'ANYY Readers': unknown rule type " + 346 "'ANYY', expected ALL, ANY, or MAJORITY"), 347 }, 348 { 349 testName: "When creating the default config template with SignatureTypePolicy and bad rule fails", 350 profileMod: func() Channel { 351 profile := baseProfile(t) 352 profile.Application.Policies[ReadersPolicyKey] = Policy{ 353 Rule: "ANYY Readers", 354 Type: SignaturePolicyType, 355 } 356 return profile 357 }, 358 channelID: "testchannel", 359 err: errors.New("creating default config template: failed to create application group: " + 360 "invalid signature policy rule: 'ANYY Readers': Cannot transition " + 361 "token types from VARIABLE [ANYY] to VARIABLE [Readers]"), 362 }, 363 { 364 testName: "When creating the default config template with an unknown policy type fails", 365 profileMod: func() Channel { 366 profile := baseProfile(t) 367 profile.Application.Policies[ReadersPolicyKey] = Policy{ 368 Rule: "ALL", 369 Type: "GreenPolicy", 370 } 371 return profile 372 }, 373 channelID: "testchannel", 374 err: errors.New("creating default config template: failed to create application group: " + 375 "unknown policy type: GreenPolicy"), 376 }, 377 { 378 testName: "When creating the default config template without consortium", 379 profileMod: func() Channel { 380 profile := baseProfile(t) 381 profile.Consortium = "" 382 return profile 383 }, 384 channelID: "testchannel", 385 err: errors.New("creating default config template: consortium is not defined in channel config"), 386 }, 387 { 388 testName: "When channel ID is not specified in config", 389 profileMod: func() Channel { 390 profile := baseProfile(t) 391 return profile 392 }, 393 channelID: "", 394 err: errors.New("profile's channel ID is required"), 395 }, 396 { 397 testName: "When creating the application group fails", 398 profileMod: func() Channel { 399 profile := baseProfile(t) 400 profile.Application.Policies = nil 401 return profile 402 }, 403 channelID: "testchannel", 404 err: errors.New("creating default config template: " + 405 "failed to create application group: no policies defined"), 406 }, 407 } 408 409 for _, tt := range tests { 410 tt := tt // capture range variable 411 t.Run(tt.testName, func(t *testing.T) { 412 t.Parallel() 413 414 gt := NewGomegaWithT(t) 415 416 profile := tt.profileMod() 417 418 marshaledCreateChannelTx, err := NewMarshaledCreateChannelTx(profile, tt.channelID) 419 gt.Expect(marshaledCreateChannelTx).To(BeNil()) 420 gt.Expect(err).To(MatchError(tt.err)) 421 }) 422 } 423 } 424 425 func TestNewSystemChannelGenesisBlock(t *testing.T) { 426 t.Parallel() 427 428 gt := NewGomegaWithT(t) 429 430 profile, _, _ := baseSystemChannelProfile(t) 431 432 block, err := NewSystemChannelGenesisBlock(profile, "testsystemchannel") 433 gt.Expect(err).ToNot(HaveOccurred()) 434 gt.Expect(block).ToNot(BeNil()) 435 gt.Expect(block.Header.Number).To(Equal(uint64(0))) 436 437 org1CertBase64, org1CrlBase64 := certCRLBase64(t, profile.Consortiums[0].Organizations[0].MSP) 438 org2CertBase64, org2CrlBase64 := certCRLBase64(t, profile.Consortiums[0].Organizations[1].MSP) 439 ordererOrgCertBase64, ordererOrgCrlBase64 := certCRLBase64(t, profile.Orderer.Organizations[0].MSP) 440 441 expectBlockJSON := fmt.Sprintf(` 442 { 443 "data": { 444 "data": [ 445 { 446 "payload": { 447 "data": { 448 "config": { 449 "channel_group": { 450 "groups": { 451 "Consortiums": { 452 "groups": { 453 "Consortium1": { 454 "groups": { 455 "Org1": { 456 "groups": {}, 457 "mod_policy": "Admins", 458 "policies": { 459 "Admins": { 460 "mod_policy": "Admins", 461 "policy": { 462 "type": 3, 463 "value": { 464 "rule": "MAJORITY", 465 "sub_policy": "Admins" 466 } 467 }, 468 "version": "0" 469 }, 470 "Endorsement": { 471 "mod_policy": "Admins", 472 "policy": { 473 "type": 3, 474 "value": { 475 "rule": "MAJORITY", 476 "sub_policy": "Endorsement" 477 } 478 }, 479 "version": "0" 480 }, 481 "Readers": { 482 "mod_policy": "Admins", 483 "policy": { 484 "type": 3, 485 "value": { 486 "rule": "ANY", 487 "sub_policy": "Readers" 488 } 489 }, 490 "version": "0" 491 }, 492 "Writers": { 493 "mod_policy": "Admins", 494 "policy": { 495 "type": 3, 496 "value": { 497 "rule": "ANY", 498 "sub_policy": "Writers" 499 } 500 }, 501 "version": "0" 502 } 503 }, 504 "values": { 505 "MSP": { 506 "mod_policy": "Admins", 507 "value": { 508 "config": { 509 "admins": [ 510 "%[1]s" 511 ], 512 "crypto_config": { 513 "identity_identifier_hash_function": "SHA256", 514 "signature_hash_family": "SHA3" 515 }, 516 "fabric_node_ous": { 517 "admin_ou_identifier": { 518 "certificate": "%[1]s", 519 "organizational_unit_identifier": "OUID" 520 }, 521 "client_ou_identifier": { 522 "certificate": "%[1]s", 523 "organizational_unit_identifier": "OUID" 524 }, 525 "enable": false, 526 "orderer_ou_identifier": { 527 "certificate": "%[1]s", 528 "organizational_unit_identifier": "OUID" 529 }, 530 "peer_ou_identifier": { 531 "certificate": "%[1]s", 532 "organizational_unit_identifier": "OUID" 533 } 534 }, 535 "intermediate_certs": [ 536 "%[1]s" 537 ], 538 "name": "MSPID", 539 "organizational_unit_identifiers": [ 540 { 541 "certificate": "%[1]s", 542 "organizational_unit_identifier": "OUID" 543 } 544 ], 545 "revocation_list": [ 546 "%[2]s" 547 ], 548 "root_certs": [ 549 "%[1]s" 550 ], 551 "signing_identity": null, 552 "tls_intermediate_certs": [ 553 "%[1]s" 554 ], 555 "tls_root_certs": [ 556 "%[1]s" 557 ] 558 }, 559 "type": 0 560 }, 561 "version": "0" 562 } 563 }, 564 "version": "0" 565 }, 566 "Org2": { 567 "groups": {}, 568 "mod_policy": "Admins", 569 "policies": { 570 "Admins": { 571 "mod_policy": "Admins", 572 "policy": { 573 "type": 3, 574 "value": { 575 "rule": "MAJORITY", 576 "sub_policy": "Admins" 577 } 578 }, 579 "version": "0" 580 }, 581 "Endorsement": { 582 "mod_policy": "Admins", 583 "policy": { 584 "type": 3, 585 "value": { 586 "rule": "MAJORITY", 587 "sub_policy": "Endorsement" 588 } 589 }, 590 "version": "0" 591 }, 592 "Readers": { 593 "mod_policy": "Admins", 594 "policy": { 595 "type": 3, 596 "value": { 597 "rule": "ANY", 598 "sub_policy": "Readers" 599 } 600 }, 601 "version": "0" 602 }, 603 "Writers": { 604 "mod_policy": "Admins", 605 "policy": { 606 "type": 3, 607 "value": { 608 "rule": "ANY", 609 "sub_policy": "Writers" 610 } 611 }, 612 "version": "0" 613 } 614 }, 615 "values": { 616 "MSP": { 617 "mod_policy": "Admins", 618 "value": { 619 "config": { 620 "admins": [ 621 "%[3]s" 622 ], 623 "crypto_config": { 624 "identity_identifier_hash_function": "SHA256", 625 "signature_hash_family": "SHA3" 626 }, 627 "fabric_node_ous": { 628 "admin_ou_identifier": { 629 "certificate": "%[3]s", 630 "organizational_unit_identifier": "OUID" 631 }, 632 "client_ou_identifier": { 633 "certificate": "%[3]s", 634 "organizational_unit_identifier": "OUID" 635 }, 636 "enable": false, 637 "orderer_ou_identifier": { 638 "certificate": "%[3]s", 639 "organizational_unit_identifier": "OUID" 640 }, 641 "peer_ou_identifier": { 642 "certificate": "%[3]s", 643 "organizational_unit_identifier": "OUID" 644 } 645 }, 646 "intermediate_certs": [ 647 "%[3]s" 648 ], 649 "name": "MSPID", 650 "organizational_unit_identifiers": [ 651 { 652 "certificate": "%[3]s", 653 "organizational_unit_identifier": "OUID" 654 } 655 ], 656 "revocation_list": [ 657 "%[4]s" 658 ], 659 "root_certs": [ 660 "%[3]s" 661 ], 662 "signing_identity": null, 663 "tls_intermediate_certs": [ 664 "%[3]s" 665 ], 666 "tls_root_certs": [ 667 "%[3]s" 668 ] 669 }, 670 "type": 0 671 }, 672 "version": "0" 673 } 674 }, 675 "version": "0" 676 } 677 }, 678 "mod_policy": "/Channel/Orderer/Admins", 679 "policies": {}, 680 "values": { 681 "ChannelCreationPolicy": { 682 "mod_policy": "/Channel/Orderer/Admins", 683 "value": { 684 "type": 3, 685 "value": { 686 "rule": "ANY", 687 "sub_policy": "Admins" 688 } 689 }, 690 "version": "0" 691 } 692 }, 693 "version": "0" 694 } 695 }, 696 "mod_policy": "/Channel/Orderer/Admins", 697 "policies": { 698 "Admins": { 699 "mod_policy": "/Channel/Orderer/Admins", 700 "policy": { 701 "type": 1, 702 "value": { 703 "identities": [], 704 "rule": { 705 "n_out_of": { 706 "n": 0, 707 "rules": [] 708 } 709 }, 710 "version": 0 711 } 712 }, 713 "version": "0" 714 } 715 }, 716 "values": {}, 717 "version": "0" 718 }, 719 "Orderer": { 720 "groups": { 721 "OrdererOrg": { 722 "groups": {}, 723 "mod_policy": "Admins", 724 "policies": { 725 "Admins": { 726 "mod_policy": "Admins", 727 "policy": { 728 "type": 3, 729 "value": { 730 "rule": "MAJORITY", 731 "sub_policy": "Admins" 732 } 733 }, 734 "version": "0" 735 }, 736 "Endorsement": { 737 "mod_policy": "Admins", 738 "policy": { 739 "type": 3, 740 "value": { 741 "rule": "MAJORITY", 742 "sub_policy": "Endorsement" 743 } 744 }, 745 "version": "0" 746 }, 747 "Readers": { 748 "mod_policy": "Admins", 749 "policy": { 750 "type": 3, 751 "value": { 752 "rule": "ANY", 753 "sub_policy": "Readers" 754 } 755 }, 756 "version": "0" 757 }, 758 "Writers": { 759 "mod_policy": "Admins", 760 "policy": { 761 "type": 3, 762 "value": { 763 "rule": "ANY", 764 "sub_policy": "Writers" 765 } 766 }, 767 "version": "0" 768 } 769 }, 770 "values": { 771 "Endpoints": { 772 "mod_policy": "Admins", 773 "value": { 774 "addresses": [ 775 "localhost:123" 776 ] 777 }, 778 "version": "0" 779 }, 780 "MSP": { 781 "mod_policy": "Admins", 782 "value": { 783 "config": { 784 "admins": [ 785 "%[5]s" 786 ], 787 "crypto_config": { 788 "identity_identifier_hash_function": "SHA256", 789 "signature_hash_family": "SHA3" 790 }, 791 "fabric_node_ous": { 792 "admin_ou_identifier": { 793 "certificate": "%[5]s", 794 "organizational_unit_identifier": "OUID" 795 }, 796 "client_ou_identifier": { 797 "certificate": "%[5]s", 798 "organizational_unit_identifier": "OUID" 799 }, 800 "enable": false, 801 "orderer_ou_identifier": { 802 "certificate": "%[5]s", 803 "organizational_unit_identifier": "OUID" 804 }, 805 "peer_ou_identifier": { 806 "certificate": "%[5]s", 807 "organizational_unit_identifier": "OUID" 808 } 809 }, 810 "intermediate_certs": [ 811 "%[5]s" 812 ], 813 "name": "MSPID", 814 "organizational_unit_identifiers": [ 815 { 816 "certificate": "%[5]s", 817 "organizational_unit_identifier": "OUID" 818 } 819 ], 820 "revocation_list": [ 821 "%[6]s" 822 ], 823 "root_certs": [ 824 "%[5]s" 825 ], 826 "signing_identity": null, 827 "tls_intermediate_certs": [ 828 "%[5]s" 829 ], 830 "tls_root_certs": [ 831 "%[5]s" 832 ] 833 }, 834 "type": 0 835 }, 836 "version": "0" 837 } 838 }, 839 "version": "0" 840 } 841 }, 842 "mod_policy": "Admins", 843 "policies": { 844 "Admins": { 845 "mod_policy": "Admins", 846 "policy": { 847 "type": 3, 848 "value": { 849 "rule": "MAJORITY", 850 "sub_policy": "Admins" 851 } 852 }, 853 "version": "0" 854 }, 855 "BlockValidation": { 856 "mod_policy": "Admins", 857 "policy": { 858 "type": 3, 859 "value": { 860 "rule": "ANY", 861 "sub_policy": "Writers" 862 } 863 }, 864 "version": "0" 865 }, 866 "Readers": { 867 "mod_policy": "Admins", 868 "policy": { 869 "type": 3, 870 "value": { 871 "rule": "ANY", 872 "sub_policy": "Readers" 873 } 874 }, 875 "version": "0" 876 }, 877 "Writers": { 878 "mod_policy": "Admins", 879 "policy": { 880 "type": 3, 881 "value": { 882 "rule": "ANY", 883 "sub_policy": "Writers" 884 } 885 }, 886 "version": "0" 887 } 888 }, 889 "values": { 890 "BatchSize": { 891 "mod_policy": "Admins", 892 "value": { 893 "absolute_max_bytes": 100, 894 "max_message_count": 100, 895 "preferred_max_bytes": 100 896 }, 897 "version": "0" 898 }, 899 "BatchTimeout": { 900 "mod_policy": "Admins", 901 "value": { 902 "timeout": "0s" 903 }, 904 "version": "0" 905 }, 906 "Capabilities": { 907 "mod_policy": "Admins", 908 "value": { 909 "capabilities": { 910 "V1_3": {} 911 } 912 }, 913 "version": "0" 914 }, 915 "ChannelRestrictions": { 916 "mod_policy": "Admins", 917 "value": null, 918 "version": "0" 919 }, 920 "ConsensusType": { 921 "mod_policy": "Admins", 922 "value": { 923 "metadata": null, 924 "state": "STATE_NORMAL", 925 "type": "solo" 926 }, 927 "version": "0" 928 } 929 }, 930 "version": "0" 931 } 932 }, 933 "mod_policy": "Admins", 934 "policies": { 935 "Admins": { 936 "mod_policy": "Admins", 937 "policy": { 938 "type": 3, 939 "value": { 940 "rule": "MAJORITY", 941 "sub_policy": "Admins" 942 } 943 }, 944 "version": "0" 945 }, 946 "Readers": { 947 "mod_policy": "Admins", 948 "policy": { 949 "type": 3, 950 "value": { 951 "rule": "ANY", 952 "sub_policy": "Readers" 953 } 954 }, 955 "version": "0" 956 }, 957 "Writers": { 958 "mod_policy": "Admins", 959 "policy": { 960 "type": 3, 961 "value": { 962 "rule": "ANY", 963 "sub_policy": "Writers" 964 } 965 }, 966 "version": "0" 967 } 968 }, 969 "values": { 970 "BlockDataHashingStructure": { 971 "mod_policy": "Admins", 972 "value": { 973 "width": 4294967295 974 }, 975 "version": "0" 976 }, 977 "HashingAlgorithm": { 978 "mod_policy": "Admins", 979 "value": { 980 "name": "SHA256" 981 }, 982 "version": "0" 983 }, 984 "Capabilities": { 985 "mod_policy": "Admins", 986 "value": { 987 "capabilities": { 988 "V2_0": {} 989 } 990 }, 991 "version": "0" 992 } 993 }, 994 "version": "0" 995 }, 996 "sequence": "0" 997 }, 998 "last_update": null 999 }, 1000 "header": { 1001 "channel_header": { 1002 "channel_id": "testsystemchannel", 1003 "epoch": "0", 1004 "extension": null, 1005 "timestamp": "2020-04-08T11:59:02Z", 1006 "tls_cert_hash": null, 1007 "tx_id": "1b9fd2206484ebbfc960c772c2638f83474b957c7a83f4607e94c44205a5fc9f", 1008 "type": 1, 1009 "version": 0 1010 }, 1011 "signature_header": { 1012 "creator": null, 1013 "nonce": "9GHTm16kXuzFu8OwUG+Ds3re67UXVPaz" 1014 } 1015 } 1016 }, 1017 "signature": null 1018 } 1019 ] 1020 }, 1021 "header": { 1022 "data_hash": "zYnpX4Xe0k/Wue2m6lEEJwqMzdApznVVUw7n5SLNWmo=", 1023 "number": "0", 1024 "previous_hash": null 1025 }, 1026 "metadata": { 1027 "metadata": [ 1028 "CgIKAA==", 1029 "", 1030 "", 1031 "", 1032 "" 1033 ] 1034 } 1035 } 1036 `, org1CertBase64, org1CrlBase64, org2CertBase64, org2CrlBase64, ordererOrgCertBase64, ordererOrgCrlBase64) 1037 1038 expectedBlock := &cb.Block{} 1039 err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectBlockJSON), expectedBlock) 1040 gt.Expect(err).ToNot(HaveOccurred()) 1041 1042 expectedEnvelope := &cb.Envelope{} 1043 err = proto.Unmarshal(expectedBlock.Data.Data[0], expectedEnvelope) 1044 gt.Expect(err).NotTo(HaveOccurred()) 1045 1046 expectedPayload := &cb.Payload{} 1047 err = proto.Unmarshal(expectedEnvelope.Payload, expectedPayload) 1048 gt.Expect(err).NotTo(HaveOccurred()) 1049 1050 expectedData := &cb.ConfigEnvelope{} 1051 err = proto.Unmarshal(expectedPayload.Data, expectedData) 1052 gt.Expect(err).NotTo(HaveOccurred()) 1053 1054 actualEnvelope := &cb.Envelope{} 1055 err = proto.Unmarshal(block.Data.Data[0], actualEnvelope) 1056 gt.Expect(err).NotTo(HaveOccurred()) 1057 1058 actualPayload := &cb.Payload{} 1059 err = proto.Unmarshal(actualEnvelope.Payload, actualPayload) 1060 gt.Expect(err).NotTo(HaveOccurred()) 1061 1062 actualData := &cb.ConfigEnvelope{} 1063 err = proto.Unmarshal(actualPayload.Data, actualData) 1064 gt.Expect(err).NotTo(HaveOccurred()) 1065 gt.Expect(actualData).To(Equal(expectedData)) 1066 1067 expectedChannelHeader := &cb.ChannelHeader{} 1068 err = proto.Unmarshal(expectedPayload.Header.ChannelHeader, expectedChannelHeader) 1069 gt.Expect(err).NotTo(HaveOccurred()) 1070 1071 actualChannelHeader := &cb.ChannelHeader{} 1072 err = proto.Unmarshal(actualPayload.Header.ChannelHeader, actualChannelHeader) 1073 gt.Expect(err).NotTo(HaveOccurred()) 1074 expectedChannelHeader.Timestamp = actualChannelHeader.Timestamp 1075 expectedChannelHeader.TxId = actualChannelHeader.TxId 1076 1077 gt.Expect(actualChannelHeader).To(Equal(expectedChannelHeader)) 1078 } 1079 1080 func TestNewSystemChannelGenesisBlockFailure(t *testing.T) { 1081 t.Parallel() 1082 1083 tests := []struct { 1084 testName string 1085 profileMod func() Channel 1086 channelID string 1087 err error 1088 }{ 1089 { 1090 testName: "When channel ID is not specified in config", 1091 profileMod: func() Channel { 1092 profile, _, _ := baseSystemChannelProfile(t) 1093 return profile 1094 }, 1095 channelID: "", 1096 err: errors.New("system channel ID is required"), 1097 }, 1098 { 1099 testName: "When creating the default system config template with empty orderer endpoints", 1100 profileMod: func() Channel { 1101 profile, _, _ := baseSystemChannelProfile(t) 1102 profile.Orderer.Organizations[0].OrdererEndpoints = []string{} 1103 return profile 1104 }, 1105 channelID: "testsystemchannel", 1106 err: errors.New("creating system channel group: orderer endpoints are not defined for org OrdererOrg"), 1107 }, 1108 { 1109 testName: "When creating the default config template with empty capabilities", 1110 profileMod: func() Channel { 1111 profile, _, _ := baseSystemChannelProfile(t) 1112 profile.Capabilities = []string{} 1113 return profile 1114 }, 1115 channelID: "testsystemchannel", 1116 err: errors.New("creating system channel group: capabilities is not defined in channel config"), 1117 }, 1118 { 1119 testName: "When creating the default config template without orderer", 1120 profileMod: func() Channel { 1121 profile, _, _ := baseSystemChannelProfile(t) 1122 profile.Orderer = Orderer{} 1123 return profile 1124 }, 1125 channelID: "testsystemchannel", 1126 err: errors.New("creating system channel group: no policies defined"), 1127 }, 1128 } 1129 1130 for _, tt := range tests { 1131 tt := tt 1132 t.Run(tt.testName, func(t *testing.T) { 1133 t.Parallel() 1134 1135 gt := NewGomegaWithT(t) 1136 1137 profile := tt.profileMod() 1138 1139 block, err := NewSystemChannelGenesisBlock(profile, tt.channelID) 1140 gt.Expect(block).To(BeNil()) 1141 gt.Expect(err).To(MatchError(tt.err)) 1142 }) 1143 } 1144 } 1145 1146 func TestNewApplicationChannelGenesisBlock(t *testing.T) { 1147 t.Parallel() 1148 1149 gt := NewGomegaWithT(t) 1150 1151 profile, _, _ := baseApplicationChannelProfile(t) 1152 1153 block, err := NewApplicationChannelGenesisBlock(profile, "testapplicationchannel") 1154 gt.Expect(err).ToNot(HaveOccurred()) 1155 gt.Expect(block).ToNot(BeNil()) 1156 gt.Expect(block.Header.Number).To(Equal(uint64(0))) 1157 1158 org1CertBase64, org1CrlBase64 := certCRLBase64(t, profile.Application.Organizations[0].MSP) 1159 org2CertBase64, org2CrlBase64 := certCRLBase64(t, profile.Application.Organizations[1].MSP) 1160 ordererOrgCertBase64, ordererOrgCrlBase64 := certCRLBase64(t, profile.Orderer.Organizations[0].MSP) 1161 1162 expectBlockJSON := fmt.Sprintf(` 1163 { 1164 "data": { 1165 "data": [ 1166 { 1167 "payload": { 1168 "data": { 1169 "config": { 1170 "channel_group": { 1171 "groups": { 1172 "Application": { 1173 "groups": { 1174 "Org1": { 1175 "groups": {}, 1176 "mod_policy": "Admins", 1177 "policies": { 1178 "Admins": { 1179 "mod_policy": "Admins", 1180 "policy": { 1181 "type": 3, 1182 "value": { 1183 "rule": "MAJORITY", 1184 "sub_policy": "Admins" 1185 } 1186 }, 1187 "version": "0" 1188 }, 1189 "Endorsement": { 1190 "mod_policy": "Admins", 1191 "policy": { 1192 "type": 3, 1193 "value": { 1194 "rule": "MAJORITY", 1195 "sub_policy": "Endorsement" 1196 } 1197 }, 1198 "version": "0" 1199 }, 1200 "LifecycleEndorsement": { 1201 "mod_policy": "Admins", 1202 "policy": { 1203 "type": 3, 1204 "value": { 1205 "rule": "MAJORITY", 1206 "sub_policy": "Endorsement" 1207 } 1208 }, 1209 "version": "0" 1210 }, 1211 "Readers": { 1212 "mod_policy": "Admins", 1213 "policy": { 1214 "type": 3, 1215 "value": { 1216 "rule": "ANY", 1217 "sub_policy": "Readers" 1218 } 1219 }, 1220 "version": "0" 1221 }, 1222 "Writers": { 1223 "mod_policy": "Admins", 1224 "policy": { 1225 "type": 3, 1226 "value": { 1227 "rule": "ANY", 1228 "sub_policy": "Writers" 1229 } 1230 }, 1231 "version": "0" 1232 } 1233 }, 1234 "values": { 1235 "MSP": { 1236 "mod_policy": "Admins", 1237 "value": { 1238 "config": { 1239 "admins": [ 1240 "%[1]s" 1241 ], 1242 "crypto_config": { 1243 "identity_identifier_hash_function": "SHA256", 1244 "signature_hash_family": "SHA3" 1245 }, 1246 "fabric_node_ous": { 1247 "admin_ou_identifier": { 1248 "certificate": "%[1]s", 1249 "organizational_unit_identifier": "OUID" 1250 }, 1251 "client_ou_identifier": { 1252 "certificate": "%[1]s", 1253 "organizational_unit_identifier": "OUID" 1254 }, 1255 "enable": false, 1256 "orderer_ou_identifier": { 1257 "certificate": "%[1]s", 1258 "organizational_unit_identifier": "OUID" 1259 }, 1260 "peer_ou_identifier": { 1261 "certificate": "%[1]s", 1262 "organizational_unit_identifier": "OUID" 1263 } 1264 }, 1265 "intermediate_certs": [ 1266 "%[1]s" 1267 ], 1268 "name": "MSPID", 1269 "organizational_unit_identifiers": [ 1270 { 1271 "certificate": "%[1]s", 1272 "organizational_unit_identifier": "OUID" 1273 } 1274 ], 1275 "revocation_list": [ 1276 "%[2]s" 1277 ], 1278 "root_certs": [ 1279 "%[1]s" 1280 ], 1281 "signing_identity": null, 1282 "tls_intermediate_certs": [ 1283 "%[1]s" 1284 ], 1285 "tls_root_certs": [ 1286 "%[1]s" 1287 ] 1288 }, 1289 "type": 0 1290 }, 1291 "version": "0" 1292 } 1293 }, 1294 "version": "0" 1295 }, 1296 "Org2": { 1297 "groups": {}, 1298 "mod_policy": "Admins", 1299 "policies": { 1300 "Admins": { 1301 "mod_policy": "Admins", 1302 "policy": { 1303 "type": 3, 1304 "value": { 1305 "rule": "MAJORITY", 1306 "sub_policy": "Admins" 1307 } 1308 }, 1309 "version": "0" 1310 }, 1311 "Endorsement": { 1312 "mod_policy": "Admins", 1313 "policy": { 1314 "type": 3, 1315 "value": { 1316 "rule": "MAJORITY", 1317 "sub_policy": "Endorsement" 1318 } 1319 }, 1320 "version": "0" 1321 }, 1322 "LifecycleEndorsement": { 1323 "mod_policy": "Admins", 1324 "policy": { 1325 "type": 3, 1326 "value": { 1327 "rule": "MAJORITY", 1328 "sub_policy": "Endorsement" 1329 } 1330 }, 1331 "version": "0" 1332 }, 1333 "Readers": { 1334 "mod_policy": "Admins", 1335 "policy": { 1336 "type": 3, 1337 "value": { 1338 "rule": "ANY", 1339 "sub_policy": "Readers" 1340 } 1341 }, 1342 "version": "0" 1343 }, 1344 "Writers": { 1345 "mod_policy": "Admins", 1346 "policy": { 1347 "type": 3, 1348 "value": { 1349 "rule": "ANY", 1350 "sub_policy": "Writers" 1351 } 1352 }, 1353 "version": "0" 1354 } 1355 }, 1356 "values": { 1357 "MSP": { 1358 "mod_policy": "Admins", 1359 "value": { 1360 "config": { 1361 "admins": [ 1362 "%[3]s" 1363 ], 1364 "crypto_config": { 1365 "identity_identifier_hash_function": "SHA256", 1366 "signature_hash_family": "SHA3" 1367 }, 1368 "fabric_node_ous": { 1369 "admin_ou_identifier": { 1370 "certificate": "%[3]s", 1371 "organizational_unit_identifier": "OUID" 1372 }, 1373 "client_ou_identifier": { 1374 "certificate": "%[3]s", 1375 "organizational_unit_identifier": "OUID" 1376 }, 1377 "enable": false, 1378 "orderer_ou_identifier": { 1379 "certificate": "%[3]s", 1380 "organizational_unit_identifier": "OUID" 1381 }, 1382 "peer_ou_identifier": { 1383 "certificate": "%[3]s", 1384 "organizational_unit_identifier": "OUID" 1385 } 1386 }, 1387 "intermediate_certs": [ 1388 "%[3]s" 1389 ], 1390 "name": "MSPID", 1391 "organizational_unit_identifiers": [ 1392 { 1393 "certificate": "%[3]s", 1394 "organizational_unit_identifier": "OUID" 1395 } 1396 ], 1397 "revocation_list": [ 1398 "%[4]s" 1399 ], 1400 "root_certs": [ 1401 "%[3]s" 1402 ], 1403 "signing_identity": null, 1404 "tls_intermediate_certs": [ 1405 "%[3]s" 1406 ], 1407 "tls_root_certs": [ 1408 "%[3]s" 1409 ] 1410 }, 1411 "type": 0 1412 }, 1413 "version": "0" 1414 } 1415 }, 1416 "version": "0" 1417 } 1418 }, 1419 "mod_policy": "Admins", 1420 "policies": { 1421 "Admins": { 1422 "mod_policy": "Admins", 1423 "policy": { 1424 "type": 3, 1425 "value": { 1426 "rule": "MAJORITY", 1427 "sub_policy": "Admins" 1428 } 1429 }, 1430 "version": "0" 1431 }, 1432 "Readers": { 1433 "mod_policy": "Admins", 1434 "policy": { 1435 "type": 3, 1436 "value": { 1437 "rule": "ANY", 1438 "sub_policy": "Readers" 1439 } 1440 }, 1441 "version": "0" 1442 }, 1443 "Writers": { 1444 "mod_policy": "Admins", 1445 "policy": { 1446 "type": 3, 1447 "value": { 1448 "rule": "ANY", 1449 "sub_policy": "Writers" 1450 } 1451 }, 1452 "version": "0" 1453 } 1454 }, 1455 "values": { 1456 "ACLs": { 1457 "mod_policy": "Admins", 1458 "value": { 1459 "acls": { 1460 "acl1": { 1461 "policy_ref": "hi" 1462 } 1463 } 1464 }, 1465 "version": "0" 1466 }, 1467 "Capabilities": { 1468 "mod_policy": "Admins", 1469 "value": { 1470 "capabilities": { 1471 "V1_3": {} 1472 } 1473 }, 1474 "version": "0" 1475 } 1476 }, 1477 "version": "0" 1478 }, 1479 "Orderer": { 1480 "groups": { 1481 "OrdererOrg": { 1482 "groups": {}, 1483 "mod_policy": "Admins", 1484 "policies": { 1485 "Admins": { 1486 "mod_policy": "Admins", 1487 "policy": { 1488 "type": 3, 1489 "value": { 1490 "rule": "MAJORITY", 1491 "sub_policy": "Admins" 1492 } 1493 }, 1494 "version": "0" 1495 }, 1496 "Endorsement": { 1497 "mod_policy": "Admins", 1498 "policy": { 1499 "type": 3, 1500 "value": { 1501 "rule": "MAJORITY", 1502 "sub_policy": "Endorsement" 1503 } 1504 }, 1505 "version": "0" 1506 }, 1507 "Readers": { 1508 "mod_policy": "Admins", 1509 "policy": { 1510 "type": 3, 1511 "value": { 1512 "rule": "ANY", 1513 "sub_policy": "Readers" 1514 } 1515 }, 1516 "version": "0" 1517 }, 1518 "Writers": { 1519 "mod_policy": "Admins", 1520 "policy": { 1521 "type": 3, 1522 "value": { 1523 "rule": "ANY", 1524 "sub_policy": "Writers" 1525 } 1526 }, 1527 "version": "0" 1528 } 1529 }, 1530 "values": { 1531 "Endpoints": { 1532 "mod_policy": "Admins", 1533 "value": { 1534 "addresses": [ 1535 "localhost:123" 1536 ] 1537 }, 1538 "version": "0" 1539 }, 1540 "MSP": { 1541 "mod_policy": "Admins", 1542 "value": { 1543 "config": { 1544 "admins": [ 1545 "%[5]s" 1546 ], 1547 "crypto_config": { 1548 "identity_identifier_hash_function": "SHA256", 1549 "signature_hash_family": "SHA3" 1550 }, 1551 "fabric_node_ous": { 1552 "admin_ou_identifier": { 1553 "certificate": "%[5]s", 1554 "organizational_unit_identifier": "OUID" 1555 }, 1556 "client_ou_identifier": { 1557 "certificate": "%[5]s", 1558 "organizational_unit_identifier": "OUID" 1559 }, 1560 "enable": false, 1561 "orderer_ou_identifier": { 1562 "certificate": "%[5]s", 1563 "organizational_unit_identifier": "OUID" 1564 }, 1565 "peer_ou_identifier": { 1566 "certificate": "%[5]s", 1567 "organizational_unit_identifier": "OUID" 1568 } 1569 }, 1570 "intermediate_certs": [ 1571 "%[5]s" 1572 ], 1573 "name": "MSPID", 1574 "organizational_unit_identifiers": [ 1575 { 1576 "certificate": "%[5]s", 1577 "organizational_unit_identifier": "OUID" 1578 } 1579 ], 1580 "revocation_list": [ 1581 "%[6]s" 1582 ], 1583 "root_certs": [ 1584 "%[5]s" 1585 ], 1586 "signing_identity": null, 1587 "tls_intermediate_certs": [ 1588 "%[5]s" 1589 ], 1590 "tls_root_certs": [ 1591 "%[5]s" 1592 ] 1593 }, 1594 "type": 0 1595 }, 1596 "version": "0" 1597 } 1598 }, 1599 "version": "0" 1600 } 1601 }, 1602 "mod_policy": "Admins", 1603 "policies": { 1604 "Admins": { 1605 "mod_policy": "Admins", 1606 "policy": { 1607 "type": 3, 1608 "value": { 1609 "rule": "MAJORITY", 1610 "sub_policy": "Admins" 1611 } 1612 }, 1613 "version": "0" 1614 }, 1615 "BlockValidation": { 1616 "mod_policy": "Admins", 1617 "policy": { 1618 "type": 3, 1619 "value": { 1620 "rule": "ANY", 1621 "sub_policy": "Writers" 1622 } 1623 }, 1624 "version": "0" 1625 }, 1626 "Readers": { 1627 "mod_policy": "Admins", 1628 "policy": { 1629 "type": 3, 1630 "value": { 1631 "rule": "ANY", 1632 "sub_policy": "Readers" 1633 } 1634 }, 1635 "version": "0" 1636 }, 1637 "Writers": { 1638 "mod_policy": "Admins", 1639 "policy": { 1640 "type": 3, 1641 "value": { 1642 "rule": "ANY", 1643 "sub_policy": "Writers" 1644 } 1645 }, 1646 "version": "0" 1647 } 1648 }, 1649 "values": { 1650 "BatchSize": { 1651 "mod_policy": "Admins", 1652 "value": { 1653 "absolute_max_bytes": 100, 1654 "max_message_count": 100, 1655 "preferred_max_bytes": 100 1656 }, 1657 "version": "0" 1658 }, 1659 "BatchTimeout": { 1660 "mod_policy": "Admins", 1661 "value": { 1662 "timeout": "0s" 1663 }, 1664 "version": "0" 1665 }, 1666 "Capabilities": { 1667 "mod_policy": "Admins", 1668 "value": { 1669 "capabilities": { 1670 "V1_3": {} 1671 } 1672 }, 1673 "version": "0" 1674 }, 1675 "ChannelRestrictions": { 1676 "mod_policy": "Admins", 1677 "value": null, 1678 "version": "0" 1679 }, 1680 "ConsensusType": { 1681 "mod_policy": "Admins", 1682 "value": { 1683 "metadata": null, 1684 "state": "STATE_NORMAL", 1685 "type": "solo" 1686 }, 1687 "version": "0" 1688 } 1689 }, 1690 "version": "0" 1691 } 1692 }, 1693 "mod_policy": "Admins", 1694 "policies": { 1695 "Admins": { 1696 "mod_policy": "Admins", 1697 "policy": { 1698 "type": 3, 1699 "value": { 1700 "rule": "MAJORITY", 1701 "sub_policy": "Admins" 1702 } 1703 }, 1704 "version": "0" 1705 }, 1706 "Readers": { 1707 "mod_policy": "Admins", 1708 "policy": { 1709 "type": 3, 1710 "value": { 1711 "rule": "ANY", 1712 "sub_policy": "Readers" 1713 } 1714 }, 1715 "version": "0" 1716 }, 1717 "Writers": { 1718 "mod_policy": "Admins", 1719 "policy": { 1720 "type": 3, 1721 "value": { 1722 "rule": "ANY", 1723 "sub_policy": "Writers" 1724 } 1725 }, 1726 "version": "0" 1727 } 1728 }, 1729 "values": { 1730 "BlockDataHashingStructure": { 1731 "mod_policy": "Admins", 1732 "value": { 1733 "width": 4294967295 1734 }, 1735 "version": "0" 1736 }, 1737 "Capabilities": { 1738 "mod_policy": "Admins", 1739 "value": { 1740 "capabilities": { 1741 "V2_0": {} 1742 } 1743 }, 1744 "version": "0" 1745 }, 1746 "HashingAlgorithm": { 1747 "mod_policy": "Admins", 1748 "value": { 1749 "name": "SHA256" 1750 }, 1751 "version": "0" 1752 } 1753 }, 1754 "version": "0" 1755 }, 1756 "sequence": "0" 1757 }, 1758 "last_update": null 1759 }, 1760 "header": { 1761 "channel_header": { 1762 "channel_id": "testapplicationchannel", 1763 "epoch": "0", 1764 "extension": null, 1765 "timestamp": "2020-06-25T17:39:55Z", 1766 "tls_cert_hash": null, 1767 "tx_id": "93fcf9cd1e2524021f6ea592801a8b15d5262d54b350c7fe8b6b760a062b7390", 1768 "type": 1, 1769 "version": 0 1770 }, 1771 "signature_header": { 1772 "creator": null, 1773 "nonce": "yXFTP7Wz7bAtIMpzFB+WaLe45fYIXjl8" 1774 } 1775 } 1776 }, 1777 "signature": null 1778 } 1779 ] 1780 }, 1781 "header": { 1782 "data_hash": "2FX2z5r8jRx6Jt5QKHt6Ch/eU0ay1bZPrncOL1Q7pIE=", 1783 "number": "0", 1784 "previous_hash": null 1785 }, 1786 "metadata": { 1787 "metadata": [ 1788 "CgIKAA==", 1789 "", 1790 "", 1791 "", 1792 "" 1793 ] 1794 } 1795 } 1796 `, org1CertBase64, org1CrlBase64, org2CertBase64, org2CrlBase64, ordererOrgCertBase64, ordererOrgCrlBase64) 1797 1798 expectedBlock := &cb.Block{} 1799 err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectBlockJSON), expectedBlock) 1800 gt.Expect(err).ToNot(HaveOccurred()) 1801 1802 expectedEnvelope := &cb.Envelope{} 1803 err = proto.Unmarshal(expectedBlock.Data.Data[0], expectedEnvelope) 1804 gt.Expect(err).NotTo(HaveOccurred()) 1805 1806 expectedPayload := &cb.Payload{} 1807 err = proto.Unmarshal(expectedEnvelope.Payload, expectedPayload) 1808 gt.Expect(err).NotTo(HaveOccurred()) 1809 1810 expectedData := &cb.ConfigEnvelope{} 1811 err = proto.Unmarshal(expectedPayload.Data, expectedData) 1812 gt.Expect(err).NotTo(HaveOccurred()) 1813 1814 actualEnvelope := &cb.Envelope{} 1815 err = proto.Unmarshal(block.Data.Data[0], actualEnvelope) 1816 gt.Expect(err).NotTo(HaveOccurred()) 1817 1818 actualPayload := &cb.Payload{} 1819 err = proto.Unmarshal(actualEnvelope.Payload, actualPayload) 1820 gt.Expect(err).NotTo(HaveOccurred()) 1821 1822 actualData := &cb.ConfigEnvelope{} 1823 err = proto.Unmarshal(actualPayload.Data, actualData) 1824 gt.Expect(err).NotTo(HaveOccurred()) 1825 gt.Expect(actualData).To(Equal(expectedData)) 1826 1827 expectedChannelHeader := &cb.ChannelHeader{} 1828 err = proto.Unmarshal(expectedPayload.Header.ChannelHeader, expectedChannelHeader) 1829 gt.Expect(err).NotTo(HaveOccurred()) 1830 1831 actualChannelHeader := &cb.ChannelHeader{} 1832 err = proto.Unmarshal(actualPayload.Header.ChannelHeader, actualChannelHeader) 1833 gt.Expect(err).NotTo(HaveOccurred()) 1834 expectedChannelHeader.Timestamp = actualChannelHeader.Timestamp 1835 expectedChannelHeader.TxId = actualChannelHeader.TxId 1836 1837 gt.Expect(actualChannelHeader).To(Equal(expectedChannelHeader)) 1838 } 1839 1840 func TestNewApplicationChannelGenesisBlockFailure(t *testing.T) { 1841 t.Parallel() 1842 1843 tests := []struct { 1844 testName string 1845 profileMod func() Channel 1846 channelID string 1847 err error 1848 }{ 1849 { 1850 testName: "When channel ID is not specified in config", 1851 profileMod: func() Channel { 1852 profile, _, _ := baseApplicationChannelProfile(t) 1853 return profile 1854 }, 1855 channelID: "", 1856 err: errors.New("application channel ID is required"), 1857 }, 1858 { 1859 testName: "When creating the default application config template with empty orderer endpoints", 1860 profileMod: func() Channel { 1861 profile, _, _ := baseApplicationChannelProfile(t) 1862 profile.Orderer.Organizations[0].OrdererEndpoints = []string{} 1863 return profile 1864 }, 1865 channelID: "testapplicationchannel", 1866 err: errors.New("creating application channel group: orderer endpoints are not defined for org OrdererOrg"), 1867 }, 1868 { 1869 testName: "When creating the default config template with empty capabilities", 1870 profileMod: func() Channel { 1871 profile, _, _ := baseApplicationChannelProfile(t) 1872 profile.Capabilities = []string{} 1873 return profile 1874 }, 1875 channelID: "testapplicationchannel", 1876 err: errors.New("creating application channel group: capabilities is not defined in channel config"), 1877 }, 1878 { 1879 testName: "When creating the default config template without application", 1880 profileMod: func() Channel { 1881 profile, _, _ := baseApplicationChannelProfile(t) 1882 profile.Application = Application{} 1883 return profile 1884 }, 1885 channelID: "testapplicationchannel", 1886 err: errors.New("creating application channel group: no policies defined"), 1887 }, 1888 } 1889 1890 for _, tt := range tests { 1891 tt := tt 1892 t.Run(tt.testName, func(t *testing.T) { 1893 t.Parallel() 1894 1895 gt := NewGomegaWithT(t) 1896 1897 profile := tt.profileMod() 1898 1899 block, err := NewApplicationChannelGenesisBlock(profile, tt.channelID) 1900 gt.Expect(block).To(BeNil()) 1901 gt.Expect(err).To(MatchError(tt.err)) 1902 }) 1903 } 1904 } 1905 1906 func TestNewEnvelopeFailures(t *testing.T) { 1907 t.Parallel() 1908 1909 tests := []struct { 1910 spec string 1911 marshaledUpdate []byte 1912 expectedErr string 1913 }{ 1914 { 1915 spec: "when the marshaled config update isn't a config update", 1916 marshaledUpdate: []byte("not-a-config-update"), 1917 expectedErr: "unmarshaling config update: proto: can't skip unknown wire type 6", 1918 }, 1919 } 1920 1921 for _, tc := range tests { 1922 tc := tc 1923 t.Run(tc.spec, func(t *testing.T) { 1924 t.Parallel() 1925 gt := NewGomegaWithT(t) 1926 1927 env, err := NewEnvelope(tc.marshaledUpdate) 1928 gt.Expect(err).To(MatchError(tc.expectedErr)) 1929 gt.Expect(env).To(BeNil()) 1930 }) 1931 } 1932 } 1933 1934 func TestComputeMarshaledUpdate(t *testing.T) { 1935 t.Parallel() 1936 gt := NewGomegaWithT(t) 1937 1938 value1Name := "foo" 1939 value2Name := "bar" 1940 original := &cb.Config{ 1941 ChannelGroup: &cb.ConfigGroup{ 1942 Version: 7, 1943 Values: map[string]*cb.ConfigValue{ 1944 value1Name: { 1945 Version: 3, 1946 Value: []byte("value1value"), 1947 }, 1948 value2Name: { 1949 Version: 6, 1950 Value: []byte("value2value"), 1951 }, 1952 }, 1953 }, 1954 } 1955 updated := &cb.Config{ 1956 ChannelGroup: &cb.ConfigGroup{ 1957 Values: map[string]*cb.ConfigValue{ 1958 value1Name: original.ChannelGroup.Values[value1Name], 1959 value2Name: { 1960 Value: []byte("updatedValued2Value"), 1961 }, 1962 }, 1963 }, 1964 } 1965 1966 c := ConfigTx{ 1967 original: original, 1968 updated: updated, 1969 } 1970 1971 channelID := "testChannel" 1972 1973 expectedReadSet := newConfigGroup() 1974 expectedReadSet.Version = 7 1975 1976 expectedWriteSet := newConfigGroup() 1977 expectedWriteSet.Version = 7 1978 expectedWriteSet.Values = map[string]*cb.ConfigValue{ 1979 value2Name: { 1980 Version: 7, 1981 Value: []byte("updatedValued2Value"), 1982 }, 1983 } 1984 1985 expectedConfig := cb.ConfigUpdate{ 1986 ChannelId: channelID, 1987 ReadSet: expectedReadSet, 1988 WriteSet: expectedWriteSet, 1989 } 1990 1991 marshaledUpdate, err := c.ComputeMarshaledUpdate(channelID) 1992 gt.Expect(err).NotTo(HaveOccurred()) 1993 configUpdate := &cb.ConfigUpdate{} 1994 err = proto.Unmarshal(marshaledUpdate, configUpdate) 1995 gt.Expect(err).NotTo(HaveOccurred()) 1996 gt.Expect(proto.Equal(configUpdate, &expectedConfig)).To(BeTrue()) 1997 } 1998 1999 func TestComputeUpdateFailures(t *testing.T) { 2000 t.Parallel() 2001 2002 original := &cb.Config{} 2003 updated := &cb.Config{} 2004 2005 c := ConfigTx{ 2006 original: original, 2007 updated: updated, 2008 } 2009 2010 for _, test := range []struct { 2011 name string 2012 channelID string 2013 expectedErr string 2014 }{ 2015 { 2016 name: "When channel ID is not specified", 2017 channelID: "", 2018 expectedErr: "channel ID is required", 2019 }, 2020 { 2021 name: "When failing to compute update", 2022 channelID: "testChannel", 2023 expectedErr: "failed to compute update: no channel group included for original config", 2024 }, 2025 } { 2026 test := test 2027 t.Run(test.name, func(t *testing.T) { 2028 t.Parallel() 2029 gt := NewGomegaWithT(t) 2030 marshaledUpdate, err := c.ComputeMarshaledUpdate(test.channelID) 2031 gt.Expect(err).To(MatchError(test.expectedErr)) 2032 gt.Expect(marshaledUpdate).To(BeNil()) 2033 }) 2034 } 2035 } 2036 2037 func TestChannelConfiguration(t *testing.T) { 2038 t.Parallel() 2039 2040 baseApplication, _ := baseApplication(t) 2041 baseConsortiums, _ := baseConsortiums(t) 2042 baseOrderer, _ := baseSoloOrderer(t) 2043 policies := standardPolicies() 2044 2045 tests := []struct { 2046 name string 2047 configMod func(gt *GomegaWithT) *cb.Config 2048 expectedChannel Channel 2049 }{ 2050 { 2051 name: "retrieve application channel", 2052 configMod: func(gt *GomegaWithT) *cb.Config { 2053 channelGroup := newConfigGroup() 2054 2055 applicationGroup, err := newApplicationGroup(baseApplication) 2056 gt.Expect(err).NotTo(HaveOccurred()) 2057 for _, org := range baseApplication.Organizations { 2058 orgGroup, err := newOrgConfigGroup(org) 2059 gt.Expect(err).NotTo(HaveOccurred()) 2060 applicationGroup.Groups[org.Name] = orgGroup 2061 } 2062 channelGroup.Groups[ApplicationGroupKey] = applicationGroup 2063 err = setPolicies(channelGroup, standardPolicies()) 2064 gt.Expect(err).NotTo(HaveOccurred()) 2065 2066 return &cb.Config{ 2067 ChannelGroup: channelGroup, 2068 } 2069 }, 2070 expectedChannel: Channel{ 2071 Application: baseApplication, 2072 Policies: standardPolicies(), 2073 }, 2074 }, 2075 { 2076 name: "retrieve system channel", 2077 configMod: func(gt *GomegaWithT) *cb.Config { 2078 channel := Channel{ 2079 Consortiums: baseConsortiums, 2080 Orderer: baseOrderer, 2081 Capabilities: []string{"V2_0"}, 2082 Policies: policies, 2083 Consortium: "testconsortium", 2084 ModPolicy: AdminsPolicyKey, 2085 } 2086 channelGroup, err := newSystemChannelGroup(channel) 2087 gt.Expect(err).NotTo(HaveOccurred()) 2088 2089 return &cb.Config{ 2090 ChannelGroup: channelGroup, 2091 } 2092 }, 2093 expectedChannel: Channel{ 2094 Consortiums: baseConsortiums, 2095 Orderer: baseOrderer, 2096 Capabilities: []string{"V2_0"}, 2097 Policies: policies, 2098 }, 2099 }, 2100 } 2101 2102 for _, tt := range tests { 2103 tt := tt 2104 t.Run(tt.name, func(t *testing.T) { 2105 t.Parallel() 2106 gt := NewGomegaWithT(t) 2107 2108 config := tt.configMod(gt) 2109 c := New(config) 2110 2111 channel, err := c.Channel().Configuration() 2112 gt.Expect(err).NotTo(HaveOccurred()) 2113 gt.Expect(channel.Consortium).To(Equal(tt.expectedChannel.Consortium)) 2114 gt.Expect(channel.Application.Organizations).To(ContainElements(tt.expectedChannel.Application.Organizations)) 2115 gt.Expect(channel.Application.Capabilities).To(Equal(tt.expectedChannel.Application.Capabilities)) 2116 gt.Expect(channel.Application.Policies).To(Equal(tt.expectedChannel.Application.Policies)) 2117 gt.Expect(channel.Application.ACLs).To(Equal(tt.expectedChannel.Application.ACLs)) 2118 gt.Expect(channel.Orderer).To(Equal(tt.expectedChannel.Orderer)) 2119 gt.Expect(len(channel.Consortiums)).To(Equal(len(tt.expectedChannel.Consortiums))) 2120 gt.Expect(channel.Capabilities).To(Equal(tt.expectedChannel.Capabilities)) 2121 gt.Expect(channel.Policies).To(Equal(tt.expectedChannel.Policies)) 2122 }) 2123 } 2124 } 2125 2126 func baseProfile(t *testing.T) Channel { 2127 application, _ := baseApplication(t) 2128 return Channel{ 2129 Consortium: "SampleConsortium", 2130 Application: application, 2131 Capabilities: []string{"V2_0"}, 2132 } 2133 } 2134 2135 func baseSystemChannelProfile(t *testing.T) (Channel, []*ecdsa.PrivateKey, *ecdsa.PrivateKey) { 2136 consortiums, consortiumsPrivKey := baseConsortiums(t) 2137 orderer, ordererPrivKeys := baseSoloOrderer(t) 2138 return Channel{ 2139 Consortiums: consortiums, 2140 Orderer: orderer, 2141 Capabilities: []string{"V2_0"}, 2142 Policies: standardPolicies(), 2143 }, consortiumsPrivKey, ordererPrivKeys[0] 2144 } 2145 2146 func baseApplicationChannelProfile(t *testing.T) (Channel, []*ecdsa.PrivateKey, *ecdsa.PrivateKey) { 2147 application, applicationPrivKey := baseApplication(t) 2148 orderer, ordererPrivKeys := baseSoloOrderer(t) 2149 return Channel{ 2150 Application: application, 2151 Orderer: orderer, 2152 Capabilities: []string{"V2_0"}, 2153 Policies: standardPolicies(), 2154 ModPolicy: AdminsPolicyKey, 2155 }, applicationPrivKey, ordererPrivKeys[0] 2156 } 2157 2158 func standardPolicies() map[string]Policy { 2159 return map[string]Policy{ 2160 ReadersPolicyKey: { 2161 Type: ImplicitMetaPolicyType, 2162 Rule: "ANY Readers", 2163 ModPolicy: AdminsPolicyKey, 2164 }, 2165 WritersPolicyKey: { 2166 Type: ImplicitMetaPolicyType, 2167 Rule: "ANY Writers", 2168 ModPolicy: AdminsPolicyKey, 2169 }, 2170 AdminsPolicyKey: { 2171 Type: ImplicitMetaPolicyType, 2172 Rule: "MAJORITY Admins", 2173 ModPolicy: AdminsPolicyKey, 2174 }, 2175 } 2176 } 2177 2178 func orgStandardPolicies() map[string]Policy { 2179 policies := standardPolicies() 2180 2181 policies[EndorsementPolicyKey] = Policy{ 2182 Type: ImplicitMetaPolicyType, 2183 Rule: "MAJORITY Endorsement", 2184 ModPolicy: AdminsPolicyKey, 2185 } 2186 2187 return policies 2188 } 2189 2190 func applicationOrgStandardPolicies() map[string]Policy { 2191 policies := orgStandardPolicies() 2192 2193 policies[LifecycleEndorsementPolicyKey] = Policy{ 2194 Type: ImplicitMetaPolicyType, 2195 Rule: "MAJORITY Endorsement", 2196 ModPolicy: AdminsPolicyKey, 2197 } 2198 2199 return policies 2200 } 2201 2202 func ordererStandardPolicies() map[string]Policy { 2203 policies := standardPolicies() 2204 2205 policies[BlockValidationPolicyKey] = Policy{ 2206 Type: ImplicitMetaPolicyType, 2207 Rule: "ANY Writers", 2208 ModPolicy: AdminsPolicyKey, 2209 } 2210 2211 return policies 2212 } 2213 2214 // baseApplicationChannelGroup creates a channel config group 2215 // that only contains an Application group. 2216 func baseApplicationChannelGroup(t *testing.T) (*cb.ConfigGroup, []*ecdsa.PrivateKey, error) { 2217 channelGroup := newConfigGroup() 2218 2219 application, privKeys := baseApplication(t) 2220 applicationGroup, err := newApplicationGroup(application) 2221 if err != nil { 2222 return nil, nil, err 2223 } 2224 2225 for _, org := range application.Organizations { 2226 orgGroup, err := newOrgConfigGroup(org) 2227 if err != nil { 2228 return nil, nil, err 2229 } 2230 applicationGroup.Groups[org.Name] = orgGroup 2231 } 2232 2233 channelGroup.Groups[ApplicationGroupKey] = applicationGroup 2234 2235 return channelGroup, privKeys, nil 2236 }