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  }