github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/orderer_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  	"encoding/base64"
    12  	"fmt"
    13  	"github.com/hellobchain/newcryptosm/ecdsa"
    14  	"github.com/hellobchain/newcryptosm/x509"
    15  	"github.com/hellobchain/third_party/hyperledger/fabric-config/configtx/orderer"
    16  	"github.com/hellobchain/third_party/hyperledger/fabric-config/protolator"
    17  	"github.com/hellobchain/third_party/hyperledger/fabric-config/protolator/protoext/ordererext"
    18  	"math/big"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	cb "github.com/hyperledger/fabric-protos-go/common"
    24  	ob "github.com/hyperledger/fabric-protos-go/orderer"
    25  	. "github.com/onsi/gomega"
    26  )
    27  
    28  func TestNewOrdererGroup(t *testing.T) {
    29  	t.Parallel()
    30  
    31  	tests := []struct {
    32  		ordererType           string
    33  		numOrdererGroupValues int
    34  		expectedConfigJSONGen func(Orderer) string
    35  	}{
    36  		{
    37  			ordererType:           orderer.ConsensusTypeSolo,
    38  			numOrdererGroupValues: 5,
    39  			expectedConfigJSONGen: func(o Orderer) string {
    40  				certBase64, crlBase64 := certCRLBase64(t, o.Organizations[0].MSP)
    41  				return fmt.Sprintf(`{
    42  	"groups": {
    43  		"OrdererOrg": {
    44  			"groups": {},
    45  			"mod_policy": "Admins",
    46  			"policies": {
    47  				"Admins": {
    48  					"mod_policy": "Admins",
    49  					"policy": {
    50  						"type": 3,
    51  						"value": {
    52  							"rule": "MAJORITY",
    53  							"sub_policy": "Admins"
    54  						}
    55  					},
    56  					"version": "0"
    57  				},
    58  				"Endorsement": {
    59  					"mod_policy": "Admins",
    60  					"policy": {
    61  						"type": 3,
    62  						"value": {
    63  							"rule": "MAJORITY",
    64  							"sub_policy": "Endorsement"
    65  						}
    66  					},
    67  					"version": "0"
    68  				},
    69  				"Readers": {
    70  					"mod_policy": "Admins",
    71  					"policy": {
    72  						"type": 3,
    73  						"value": {
    74  							"rule": "ANY",
    75  							"sub_policy": "Readers"
    76  						}
    77  					},
    78  					"version": "0"
    79  				},
    80  				"Writers": {
    81  					"mod_policy": "Admins",
    82  					"policy": {
    83  						"type": 3,
    84  						"value": {
    85  							"rule": "ANY",
    86  							"sub_policy": "Writers"
    87  						}
    88  					},
    89  					"version": "0"
    90  				}
    91  			},
    92  			"values": {
    93  				"Endpoints": {
    94  					"mod_policy": "Admins",
    95  					"value": {
    96  						"addresses": [
    97  							"localhost:123"
    98  						]
    99  					},
   100  					"version": "0"
   101  				},
   102  				"MSP": {
   103  					"mod_policy": "Admins",
   104  					"value": {
   105  						"config": {
   106  							"admins": [
   107  								"%[1]s"
   108  							],
   109  							"crypto_config": {
   110  								"identity_identifier_hash_function": "SHA256",
   111  								"signature_hash_family": "SHA3"
   112  							},
   113  							"fabric_node_ous": {
   114  								"admin_ou_identifier": {
   115  									"certificate": "%[1]s",
   116  									"organizational_unit_identifier": "OUID"
   117  								},
   118  								"client_ou_identifier": {
   119  									"certificate": "%[1]s",
   120  									"organizational_unit_identifier": "OUID"
   121  								},
   122  								"enable": false,
   123  								"orderer_ou_identifier": {
   124  									"certificate": "%[1]s",
   125  									"organizational_unit_identifier": "OUID"
   126  								},
   127  								"peer_ou_identifier": {
   128  									"certificate": "%[1]s",
   129  									"organizational_unit_identifier": "OUID"
   130  								}
   131  							},
   132  							"intermediate_certs": [
   133  								"%[1]s"
   134  							],
   135  							"name": "MSPID",
   136  							"organizational_unit_identifiers": [
   137  								{
   138  									"certificate": "%[1]s",
   139  									"organizational_unit_identifier": "OUID"
   140  								}
   141  							],
   142  							"revocation_list": [
   143  								"%[2]s"
   144  							],
   145  							"root_certs": [
   146  								"%[1]s"
   147  							],
   148  							"signing_identity": null,
   149  							"tls_intermediate_certs": [
   150  								"%[1]s"
   151  							],
   152  							"tls_root_certs": [
   153  								"%[1]s"
   154  							]
   155  						},
   156  						"type": 0
   157  					},
   158  					"version": "0"
   159  				}
   160  			},
   161  			"version": "0"
   162  		}
   163  	},
   164  	"mod_policy": "Admins",
   165  	"policies": {
   166  		"Admins": {
   167  			"mod_policy": "Admins",
   168  			"policy": {
   169  				"type": 3,
   170  				"value": {
   171  					"rule": "MAJORITY",
   172  					"sub_policy": "Admins"
   173  				}
   174  			},
   175  			"version": "0"
   176  		},
   177  		"BlockValidation": {
   178  			"mod_policy": "Admins",
   179  			"policy": {
   180  				"type": 3,
   181  				"value": {
   182  					"rule": "ANY",
   183  					"sub_policy": "Writers"
   184  				}
   185  			},
   186  			"version": "0"
   187  		},
   188  		"Readers": {
   189  			"mod_policy": "Admins",
   190  			"policy": {
   191  				"type": 3,
   192  				"value": {
   193  					"rule": "ANY",
   194  					"sub_policy": "Readers"
   195  				}
   196  			},
   197  			"version": "0"
   198  		},
   199  		"Writers": {
   200  			"mod_policy": "Admins",
   201  			"policy": {
   202  				"type": 3,
   203  				"value": {
   204  					"rule": "ANY",
   205  					"sub_policy": "Writers"
   206  				}
   207  			},
   208  			"version": "0"
   209  		}
   210  	},
   211  	"values": {
   212  		"BatchSize": {
   213  			"mod_policy": "Admins",
   214  			"value": {
   215  				"absolute_max_bytes": 100,
   216  				"max_message_count": 100,
   217  				"preferred_max_bytes": 100
   218  			},
   219  			"version": "0"
   220  		},
   221  		"BatchTimeout": {
   222  			"mod_policy": "Admins",
   223  			"value": {
   224  				"timeout": "0s"
   225  			},
   226  			"version": "0"
   227  		},
   228  		"Capabilities": {
   229  			"mod_policy": "Admins",
   230  			"value": {
   231  				"capabilities": {
   232  					"V1_3": {}
   233  				}
   234  			},
   235  			"version": "0"
   236  		},
   237  		"ChannelRestrictions": {
   238  			"mod_policy": "Admins",
   239  			"value": {
   240  				"max_count": "0"
   241  			},
   242  			"version": "0"
   243  		},
   244  		"ConsensusType": {
   245  			"mod_policy": "Admins",
   246  			"value": {
   247  				"metadata": null,
   248  				"state": "STATE_NORMAL",
   249  				"type": "solo"
   250  			},
   251  			"version": "0"
   252  		}
   253  	},
   254  	"version": "0"
   255  }
   256  `, certBase64, crlBase64)
   257  			},
   258  		},
   259  		{
   260  			ordererType:           orderer.ConsensusTypeEtcdRaft,
   261  			numOrdererGroupValues: 5,
   262  			expectedConfigJSONGen: func(o Orderer) string {
   263  				certBase64, crlBase64 := certCRLBase64(t, o.Organizations[0].MSP)
   264  				etcdRaftCert := o.EtcdRaft.Consenters[0].ClientTLSCert
   265  				etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
   266  				return fmt.Sprintf(`{
   267  	"groups": {
   268  		"OrdererOrg": {
   269  			"groups": {},
   270  			"mod_policy": "Admins",
   271  			"policies": {
   272  				"Admins": {
   273  					"mod_policy": "Admins",
   274  					"policy": {
   275  						"type": 3,
   276  						"value": {
   277  							"rule": "MAJORITY",
   278  							"sub_policy": "Admins"
   279  						}
   280  					},
   281  					"version": "0"
   282  				},
   283  				"Endorsement": {
   284  					"mod_policy": "Admins",
   285  					"policy": {
   286  						"type": 3,
   287  						"value": {
   288  							"rule": "MAJORITY",
   289  							"sub_policy": "Endorsement"
   290  						}
   291  					},
   292  					"version": "0"
   293  				},
   294  				"Readers": {
   295  					"mod_policy": "Admins",
   296  					"policy": {
   297  						"type": 3,
   298  						"value": {
   299  							"rule": "ANY",
   300  							"sub_policy": "Readers"
   301  						}
   302  					},
   303  					"version": "0"
   304  				},
   305  				"Writers": {
   306  					"mod_policy": "Admins",
   307  					"policy": {
   308  						"type": 3,
   309  						"value": {
   310  							"rule": "ANY",
   311  							"sub_policy": "Writers"
   312  						}
   313  					},
   314  					"version": "0"
   315  				}
   316  			},
   317  			"values": {
   318  				"Endpoints": {
   319  					"mod_policy": "Admins",
   320  					"value": {
   321  						"addresses": [
   322  							"localhost:123"
   323  						]
   324  					},
   325  					"version": "0"
   326  				},
   327  				"MSP": {
   328  					"mod_policy": "Admins",
   329  					"value": {
   330  						"config": {
   331  							"admins": [
   332  								"%[1]s"
   333  							],
   334  							"crypto_config": {
   335  								"identity_identifier_hash_function": "SHA256",
   336  								"signature_hash_family": "SHA3"
   337  							},
   338  							"fabric_node_ous": {
   339  								"admin_ou_identifier": {
   340  									"certificate": "%[1]s",
   341  									"organizational_unit_identifier": "OUID"
   342  								},
   343  								"client_ou_identifier": {
   344  									"certificate": "%[1]s",
   345  									"organizational_unit_identifier": "OUID"
   346  								},
   347  								"enable": false,
   348  								"orderer_ou_identifier": {
   349  									"certificate": "%[1]s",
   350  									"organizational_unit_identifier": "OUID"
   351  								},
   352  								"peer_ou_identifier": {
   353  									"certificate": "%[1]s",
   354  									"organizational_unit_identifier": "OUID"
   355  								}
   356  							},
   357  							"intermediate_certs": [
   358  								"%[1]s"
   359  							],
   360  							"name": "MSPID",
   361  							"organizational_unit_identifiers": [
   362  								{
   363  									"certificate": "%[1]s",
   364  									"organizational_unit_identifier": "OUID"
   365  								}
   366  							],
   367  							"revocation_list": [
   368  								"%[2]s"
   369  							],
   370  							"root_certs": [
   371  								"%[1]s"
   372  							],
   373  							"signing_identity": null,
   374  							"tls_intermediate_certs": [
   375  								"%[1]s"
   376  							],
   377  							"tls_root_certs": [
   378  								"%[1]s"
   379  							]
   380  						},
   381  						"type": 0
   382  					},
   383  					"version": "0"
   384  				}
   385  			},
   386  			"version": "0"
   387  		}
   388  	},
   389  	"mod_policy": "Admins",
   390  	"policies": {
   391  		"Admins": {
   392  			"mod_policy": "Admins",
   393  			"policy": {
   394  				"type": 3,
   395  				"value": {
   396  					"rule": "MAJORITY",
   397  					"sub_policy": "Admins"
   398  				}
   399  			},
   400  			"version": "0"
   401  		},
   402  		"BlockValidation": {
   403  			"mod_policy": "Admins",
   404  			"policy": {
   405  				"type": 3,
   406  				"value": {
   407  					"rule": "ANY",
   408  					"sub_policy": "Writers"
   409  				}
   410  			},
   411  			"version": "0"
   412  		},
   413  		"Readers": {
   414  			"mod_policy": "Admins",
   415  			"policy": {
   416  				"type": 3,
   417  				"value": {
   418  					"rule": "ANY",
   419  					"sub_policy": "Readers"
   420  				}
   421  			},
   422  			"version": "0"
   423  		},
   424  		"Writers": {
   425  			"mod_policy": "Admins",
   426  			"policy": {
   427  				"type": 3,
   428  				"value": {
   429  					"rule": "ANY",
   430  					"sub_policy": "Writers"
   431  				}
   432  			},
   433  			"version": "0"
   434  		}
   435  	},
   436  	"values": {
   437  		"BatchSize": {
   438  			"mod_policy": "Admins",
   439  			"value": {
   440  				"absolute_max_bytes": 100,
   441  				"max_message_count": 100,
   442  				"preferred_max_bytes": 100
   443  			},
   444  			"version": "0"
   445  		},
   446  		"BatchTimeout": {
   447  			"mod_policy": "Admins",
   448  			"value": {
   449  				"timeout": "0s"
   450  			},
   451  			"version": "0"
   452  		},
   453  		"Capabilities": {
   454  			"mod_policy": "Admins",
   455  			"value": {
   456  				"capabilities": {
   457  					"V1_3": {}
   458  				}
   459  			},
   460  			"version": "0"
   461  		},
   462  		"ChannelRestrictions": {
   463  			"mod_policy": "Admins",
   464  			"value": {
   465  				"max_count": "0"
   466  			},
   467  			"version": "0"
   468  		},
   469  		"ConsensusType": {
   470  			"mod_policy": "Admins",
   471  			"value": {
   472  				"metadata": {
   473  					"consenters": [
   474  						{
   475  							"client_tls_cert": "%[3]s",
   476  							"host": "node-1.example.com",
   477  							"port": 7050,
   478  							"server_tls_cert": "%[3]s"
   479  						},
   480  						{
   481  							"client_tls_cert": "%[3]s",
   482  							"host": "node-2.example.com",
   483  							"port": 7050,
   484  							"server_tls_cert": "%[3]s"
   485  						},
   486  						{
   487  							"client_tls_cert": "%[3]s",
   488  							"host": "node-3.example.com",
   489  							"port": 7050,
   490  							"server_tls_cert": "%[3]s"
   491  						}
   492  					],
   493  					"options": {
   494  						"election_tick": 0,
   495  						"heartbeat_tick": 0,
   496  						"max_inflight_blocks": 0,
   497  						"snapshot_interval_size": 0,
   498  						"tick_interval": ""
   499  					}
   500  				},
   501  				"state": "STATE_NORMAL",
   502  				"type": "etcdraft"
   503  			},
   504  			"version": "0"
   505  		}
   506  	},
   507  	"version": "0"
   508  }
   509  `, certBase64, crlBase64, etcdRaftCertBase64)
   510  			},
   511  		},
   512  		{
   513  			ordererType:           orderer.ConsensusTypeKafka,
   514  			numOrdererGroupValues: 6,
   515  			expectedConfigJSONGen: func(o Orderer) string {
   516  				certBase64, crlBase64 := certCRLBase64(t, o.Organizations[0].MSP)
   517  				return fmt.Sprintf(`{
   518  	"groups": {
   519  		"OrdererOrg": {
   520  			"groups": {},
   521  			"mod_policy": "Admins",
   522  			"policies": {
   523  				"Admins": {
   524  					"mod_policy": "Admins",
   525  					"policy": {
   526  						"type": 3,
   527  						"value": {
   528  							"rule": "MAJORITY",
   529  							"sub_policy": "Admins"
   530  						}
   531  					},
   532  					"version": "0"
   533  				},
   534  				"Endorsement": {
   535  					"mod_policy": "Admins",
   536  					"policy": {
   537  						"type": 3,
   538  						"value": {
   539  							"rule": "MAJORITY",
   540  							"sub_policy": "Endorsement"
   541  						}
   542  					},
   543  					"version": "0"
   544  				},
   545  				"Readers": {
   546  					"mod_policy": "Admins",
   547  					"policy": {
   548  						"type": 3,
   549  						"value": {
   550  							"rule": "ANY",
   551  							"sub_policy": "Readers"
   552  						}
   553  					},
   554  					"version": "0"
   555  				},
   556  				"Writers": {
   557  					"mod_policy": "Admins",
   558  					"policy": {
   559  						"type": 3,
   560  						"value": {
   561  							"rule": "ANY",
   562  							"sub_policy": "Writers"
   563  						}
   564  					},
   565  					"version": "0"
   566  				}
   567  			},
   568  			"values": {
   569  				"Endpoints": {
   570  					"mod_policy": "Admins",
   571  					"value": {
   572  						"addresses": [
   573  							"localhost:123"
   574  						]
   575  					},
   576  					"version": "0"
   577  				},
   578  				"MSP": {
   579  					"mod_policy": "Admins",
   580  					"value": {
   581  						"config": {
   582  							"admins": [
   583  								"%[1]s"
   584  							],
   585  							"crypto_config": {
   586  								"identity_identifier_hash_function": "SHA256",
   587  								"signature_hash_family": "SHA3"
   588  							},
   589  							"fabric_node_ous": {
   590  								"admin_ou_identifier": {
   591  									"certificate": "%[1]s",
   592  									"organizational_unit_identifier": "OUID"
   593  								},
   594  								"client_ou_identifier": {
   595  									"certificate": "%[1]s",
   596  									"organizational_unit_identifier": "OUID"
   597  								},
   598  								"enable": false,
   599  								"orderer_ou_identifier": {
   600  									"certificate": "%[1]s",
   601  									"organizational_unit_identifier": "OUID"
   602  								},
   603  								"peer_ou_identifier": {
   604  									"certificate": "%[1]s",
   605  									"organizational_unit_identifier": "OUID"
   606  								}
   607  							},
   608  							"intermediate_certs": [
   609  								"%[1]s"
   610  							],
   611  							"name": "MSPID",
   612  							"organizational_unit_identifiers": [
   613  								{
   614  									"certificate": "%[1]s",
   615  									"organizational_unit_identifier": "OUID"
   616  								}
   617  							],
   618  							"revocation_list": [
   619  								"%[2]s"
   620  							],
   621  							"root_certs": [
   622  								"%[1]s"
   623  							],
   624  							"signing_identity": null,
   625  							"tls_intermediate_certs": [
   626  								"%[1]s"
   627  							],
   628  							"tls_root_certs": [
   629  								"%[1]s"
   630  							]
   631  						},
   632  						"type": 0
   633  					},
   634  					"version": "0"
   635  				}
   636  			},
   637  			"version": "0"
   638  		}
   639  	},
   640  	"mod_policy": "Admins",
   641  	"policies": {
   642  		"Admins": {
   643  			"mod_policy": "Admins",
   644  			"policy": {
   645  				"type": 3,
   646  				"value": {
   647  					"rule": "MAJORITY",
   648  					"sub_policy": "Admins"
   649  				}
   650  			},
   651  			"version": "0"
   652  		},
   653  		"BlockValidation": {
   654  			"mod_policy": "Admins",
   655  			"policy": {
   656  				"type": 3,
   657  				"value": {
   658  					"rule": "ANY",
   659  					"sub_policy": "Writers"
   660  				}
   661  			},
   662  			"version": "0"
   663  		},
   664  		"Readers": {
   665  			"mod_policy": "Admins",
   666  			"policy": {
   667  				"type": 3,
   668  				"value": {
   669  					"rule": "ANY",
   670  					"sub_policy": "Readers"
   671  				}
   672  			},
   673  			"version": "0"
   674  		},
   675  		"Writers": {
   676  			"mod_policy": "Admins",
   677  			"policy": {
   678  				"type": 3,
   679  				"value": {
   680  					"rule": "ANY",
   681  					"sub_policy": "Writers"
   682  				}
   683  			},
   684  			"version": "0"
   685  		}
   686  	},
   687  	"values": {
   688  		"BatchSize": {
   689  			"mod_policy": "Admins",
   690  			"value": {
   691  				"absolute_max_bytes": 100,
   692  				"max_message_count": 100,
   693  				"preferred_max_bytes": 100
   694  			},
   695  			"version": "0"
   696  		},
   697  		"BatchTimeout": {
   698  			"mod_policy": "Admins",
   699  			"value": {
   700  				"timeout": "0s"
   701  			},
   702  			"version": "0"
   703  		},
   704  		"Capabilities": {
   705  			"mod_policy": "Admins",
   706  			"value": {
   707  				"capabilities": {
   708  					"V1_3": {}
   709  				}
   710  			},
   711  			"version": "0"
   712  		},
   713  		"ChannelRestrictions": {
   714  			"mod_policy": "Admins",
   715  			"value": {
   716  				"max_count": "0"
   717  			},
   718  			"version": "0"
   719  		},
   720  		"ConsensusType": {
   721  			"mod_policy": "Admins",
   722  			"value": {
   723  				"metadata": null,
   724  				"state": "STATE_NORMAL",
   725  				"type": "kafka"
   726  			},
   727  			"version": "0"
   728  		},
   729  		"KafkaBrokers": {
   730  			"mod_policy": "Admins",
   731  			"value": {
   732  				"brokers": [
   733  					"broker1",
   734  					"broker2"
   735  				]
   736  			},
   737  			"version": "0"
   738  		}
   739  	},
   740  	"version": "0"
   741  }
   742  `, certBase64, crlBase64)
   743  			},
   744  		},
   745  	}
   746  
   747  	for _, tt := range tests {
   748  		tt := tt
   749  		t.Run(tt.ordererType, func(t *testing.T) {
   750  			t.Parallel()
   751  
   752  			gt := NewGomegaWithT(t)
   753  
   754  			ordererConf, _ := baseOrdererOfType(t, tt.ordererType)
   755  
   756  			ordererGroup, err := newOrdererGroup(ordererConf)
   757  			gt.Expect(err).NotTo(HaveOccurred())
   758  			expectedConfigJSON := tt.expectedConfigJSONGen(ordererConf)
   759  
   760  			buf := bytes.Buffer{}
   761  			err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: ordererGroup})
   762  			gt.Expect(err).NotTo(HaveOccurred())
   763  			gt.Expect(buf.String()).To(Equal(expectedConfigJSON))
   764  		})
   765  	}
   766  }
   767  
   768  func TestNewOrdererGroupFailure(t *testing.T) {
   769  	t.Parallel()
   770  
   771  	tests := []struct {
   772  		testName   string
   773  		ordererMod func(*Orderer)
   774  		err        string
   775  	}{
   776  		{
   777  			testName: "When orderer group policy is empty",
   778  			ordererMod: func(o *Orderer) {
   779  				o.Policies = nil
   780  			},
   781  			err: "no policies defined",
   782  		},
   783  		{
   784  			testName: "When orderer type is unknown",
   785  			ordererMod: func(o *Orderer) {
   786  				o.OrdererType = "ConsensusTypeGreen"
   787  			},
   788  			err: "unknown orderer type 'ConsensusTypeGreen'",
   789  		},
   790  		{
   791  			testName: "When adding policies to orderer org group",
   792  			ordererMod: func(o *Orderer) {
   793  				o.Organizations[0].Policies = nil
   794  			},
   795  			err: "org group 'OrdererOrg': no policies defined",
   796  		},
   797  		{
   798  			testName: "When missing consenters in EtcdRaft for consensus type etcdraft",
   799  			ordererMod: func(o *Orderer) {
   800  				o.OrdererType = orderer.ConsensusTypeEtcdRaft
   801  				o.EtcdRaft = orderer.EtcdRaft{
   802  					Consenters: nil,
   803  				}
   804  			},
   805  			err: "marshaling etcdraft metadata for orderer type 'etcdraft': consenters are required",
   806  		},
   807  		{
   808  			testName: "When missing a client tls cert in EtcdRaft for consensus type etcdraft",
   809  			ordererMod: func(o *Orderer) {
   810  				o.OrdererType = orderer.ConsensusTypeEtcdRaft
   811  				o.EtcdRaft = orderer.EtcdRaft{
   812  					Consenters: []orderer.Consenter{
   813  						{
   814  							Address: orderer.EtcdAddress{
   815  								Host: "host1",
   816  								Port: 123,
   817  							},
   818  							ClientTLSCert: nil,
   819  						},
   820  					},
   821  				}
   822  			},
   823  			err: "marshaling etcdraft metadata for orderer type 'etcdraft': client tls cert for consenter host1:123 is required",
   824  		},
   825  		{
   826  			testName: "When missing a server tls cert in EtcdRaft for consensus type etcdraft",
   827  			ordererMod: func(o *Orderer) {
   828  				o.OrdererType = orderer.ConsensusTypeEtcdRaft
   829  				o.EtcdRaft = orderer.EtcdRaft{
   830  					Consenters: []orderer.Consenter{
   831  						{
   832  							Address: orderer.EtcdAddress{
   833  								Host: "host1",
   834  								Port: 123,
   835  							},
   836  							ClientTLSCert: &x509.Certificate{},
   837  							ServerTLSCert: nil,
   838  						},
   839  					},
   840  				}
   841  			},
   842  			err: "marshaling etcdraft metadata for orderer type 'etcdraft': server tls cert for consenter host1:123 is required",
   843  		},
   844  		{
   845  			testName: "When consensus state is invalid",
   846  			ordererMod: func(o *Orderer) {
   847  				o.State = "invalid state"
   848  			},
   849  			err: "unknown consensus state 'invalid state'",
   850  		},
   851  		{
   852  			testName: "When consensus state is invalid",
   853  			ordererMod: func(o *Orderer) {
   854  				o.State = "invalid state"
   855  			},
   856  			err: "unknown consensus state 'invalid state'",
   857  		},
   858  	}
   859  
   860  	for _, tt := range tests {
   861  		tt := tt // capture range variable
   862  		t.Run(tt.testName, func(t *testing.T) {
   863  			t.Parallel()
   864  
   865  			gt := NewGomegaWithT(t)
   866  
   867  			ordererConf, _ := baseSoloOrderer(t)
   868  			tt.ordererMod(&ordererConf)
   869  
   870  			ordererGroup, err := newOrdererGroup(ordererConf)
   871  			gt.Expect(err).To(MatchError(tt.err))
   872  			gt.Expect(ordererGroup).To(BeNil())
   873  		})
   874  	}
   875  }
   876  
   877  func TestSetOrdererConfiguration(t *testing.T) {
   878  	t.Parallel()
   879  
   880  	gt := NewGomegaWithT(t)
   881  
   882  	baseOrdererConf, _ := baseSoloOrderer(t)
   883  	certBase64, crlBase64 := certCRLBase64(t, baseOrdererConf.Organizations[0].MSP)
   884  
   885  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
   886  	gt.Expect(err).NotTo(HaveOccurred())
   887  
   888  	imp, err := implicitMetaFromString(baseOrdererConf.Policies[AdminsPolicyKey].Rule)
   889  	gt.Expect(err).NotTo(HaveOccurred())
   890  
   891  	originalAdminsPolicy, err := proto.Marshal(imp)
   892  	gt.Expect(err).NotTo(HaveOccurred())
   893  
   894  	config := &cb.Config{
   895  		ChannelGroup: &cb.ConfigGroup{
   896  			Groups: map[string]*cb.ConfigGroup{
   897  				OrdererGroupKey: ordererGroup,
   898  			},
   899  			Values: map[string]*cb.ConfigValue{},
   900  			Policies: map[string]*cb.ConfigPolicy{
   901  				AdminsPolicyKey: {
   902  					Policy: &cb.Policy{
   903  						Type:  int32(cb.Policy_IMPLICIT_META),
   904  						Value: originalAdminsPolicy,
   905  					},
   906  					ModPolicy: AdminsPolicyKey,
   907  				},
   908  			},
   909  		},
   910  	}
   911  
   912  	updatedOrdererConf := baseOrdererConf
   913  
   914  	// Modify MaxMessageCount and ConesnsusType to etcdraft
   915  	updatedOrdererConf.BatchSize.MaxMessageCount = 10000
   916  	updatedOrdererConf.OrdererType = orderer.ConsensusTypeEtcdRaft
   917  	updatedOrdererConf.EtcdRaft = orderer.EtcdRaft{
   918  		Consenters: []orderer.Consenter{
   919  			{
   920  				Address: orderer.EtcdAddress{
   921  					Host: "host1",
   922  					Port: 123,
   923  				},
   924  				ClientTLSCert: &x509.Certificate{},
   925  				ServerTLSCert: &x509.Certificate{},
   926  			},
   927  		},
   928  		Options: orderer.EtcdRaftOptions{},
   929  	}
   930  
   931  	c := New(config)
   932  
   933  	err = c.Orderer().SetConfiguration(updatedOrdererConf)
   934  	gt.Expect(err).NotTo(HaveOccurred())
   935  
   936  	expectedConfigJSON := fmt.Sprintf(`
   937  {
   938  	"channel_group": {
   939  		"groups": {
   940  			"Orderer": {
   941  				"groups": {
   942  					"OrdererOrg": {
   943  						"groups": {},
   944  						"mod_policy": "Admins",
   945  						"policies": {
   946  							"Admins": {
   947  								"mod_policy": "Admins",
   948  									"policy": {
   949  										"type": 3,
   950  										"value": {
   951  											"rule": "MAJORITY",
   952  											"sub_policy": "Admins"
   953  											}
   954  									},
   955  								"version": "0"
   956  							},
   957  							"Endorsement": {
   958  								"mod_policy": "Admins",
   959  								"policy": {
   960  									"type": 3,
   961  									"value": {
   962  										"rule": "MAJORITY",
   963  										"sub_policy": "Endorsement"
   964  									}
   965  								},
   966  								"version": "0"
   967  							},
   968  							"Readers": {
   969  								"mod_policy": "Admins",
   970  								"policy": {
   971  									"type": 3,
   972  									"value": {
   973  										"rule": "ANY",
   974  										"sub_policy": "Readers"
   975  									}
   976  								},
   977  								"version": "0"
   978  							},
   979  							"Writers": {
   980  								"mod_policy": "Admins",
   981  								"policy": {
   982  									"type": 3,
   983  									"value": {
   984  										"rule": "ANY",
   985  										"sub_policy": "Writers"
   986  									}
   987  								},
   988  								"version": "0"
   989  							}
   990  						},
   991  						"values": {
   992  							"Endpoints": {
   993  								"mod_policy": "Admins",
   994  								"value": {
   995  									"addresses": [
   996  									"localhost:123"
   997  								]
   998  								},
   999  								"version": "0"
  1000  							},
  1001  							"MSP": {
  1002  								"mod_policy": "Admins",
  1003  								"value": {
  1004  									"config": {
  1005  										"admins": [
  1006  											"%[1]s"
  1007  										],
  1008  										"crypto_config": {
  1009  											"identity_identifier_hash_function": "SHA256",
  1010  											"signature_hash_family": "SHA3"
  1011  										},
  1012  										"fabric_node_ous": {
  1013  											"admin_ou_identifier": {
  1014  												"certificate": "%[1]s",
  1015  												"organizational_unit_identifier": "OUID"
  1016  											},
  1017  											"client_ou_identifier": {
  1018  												"certificate": "%[1]s",
  1019  												"organizational_unit_identifier": "OUID"
  1020  											},
  1021  											"enable": false,
  1022  											"orderer_ou_identifier": {
  1023  												"certificate": "%[1]s",
  1024  												"organizational_unit_identifier": "OUID"
  1025  											},
  1026  											"peer_ou_identifier": {
  1027  												"certificate": "%[1]s",
  1028  												"organizational_unit_identifier": "OUID"
  1029  											}
  1030  										},
  1031  										"intermediate_certs": [
  1032  											"%[1]s"
  1033  										],
  1034  										"name": "MSPID",
  1035  										"organizational_unit_identifiers": [
  1036  											{
  1037  												"certificate": "%[1]s",
  1038  												"organizational_unit_identifier": "OUID"
  1039  											}
  1040  										],
  1041  										"revocation_list": [
  1042  											"%[2]s"
  1043  										],
  1044  										"root_certs": [
  1045  											"%[1]s"
  1046  										],
  1047  										"signing_identity": null,
  1048  										"tls_intermediate_certs": [
  1049  											"%[1]s"
  1050  										],
  1051  										"tls_root_certs": [
  1052  											"%[1]s"
  1053  										]
  1054  									},
  1055  									"type": 0
  1056  								},
  1057  								"version": "0"
  1058  							}
  1059  						},
  1060  						"version": "0"
  1061  					}
  1062  				},
  1063  				"mod_policy": "Admins",
  1064  				"policies": {
  1065  					"Admins": {
  1066  						"mod_policy": "Admins",
  1067  						"policy": {
  1068  							"type": 3,
  1069  							"value": {
  1070  							"rule": "MAJORITY",
  1071  							"sub_policy": "Admins"
  1072  							}
  1073  						},
  1074  						"version": "0"
  1075  					},
  1076  					"BlockValidation": {
  1077  						"mod_policy": "Admins",
  1078  						"policy": {
  1079  							"type": 3,
  1080  							"value": {
  1081  							"rule": "ANY",
  1082  							"sub_policy": "Writers"
  1083  							}
  1084  						},
  1085  						"version": "0"
  1086  					},
  1087  					"Readers": {
  1088  						"mod_policy": "Admins",
  1089  						"policy": {
  1090  							"type": 3,
  1091  							"value": {
  1092  							"rule": "ANY",
  1093  							"sub_policy": "Readers"
  1094  							}
  1095  						},
  1096  						"version": "0"
  1097  					},
  1098  					"Writers": {
  1099  						"mod_policy": "Admins",
  1100  						"policy": {
  1101  							"type": 3,
  1102  							"value": {
  1103  							"rule": "ANY",
  1104  							"sub_policy": "Writers"
  1105  							}
  1106  						},
  1107  						"version": "0"
  1108  					}
  1109  				},
  1110  				"values": {
  1111  					"BatchSize": {
  1112  						"mod_policy": "Admins",
  1113  						"value": {
  1114  							"absolute_max_bytes": 100,
  1115  							"max_message_count": 10000,
  1116  							"preferred_max_bytes": 100
  1117  						},
  1118  						"version": "0"
  1119  					},
  1120  					"BatchTimeout": {
  1121  						"mod_policy": "Admins",
  1122  						"value": {
  1123  							"timeout": "0s"
  1124  						},
  1125  						"version": "0"
  1126  					},
  1127  					"Capabilities": {
  1128  						"mod_policy": "Admins",
  1129  						"value": {
  1130  							"capabilities": {
  1131  							"V1_3": {}
  1132  							}
  1133  						},
  1134  						"version": "0"
  1135  					},
  1136  					"ChannelRestrictions": {
  1137  						"mod_policy": "Admins",
  1138  						"value": {
  1139  							"max_count": "0"
  1140  						},
  1141  						"version": "0"
  1142  					},
  1143  					"ConsensusType": {
  1144  						"mod_policy": "Admins",
  1145  						"value": {
  1146  							"metadata": {
  1147  							"consenters": [
  1148  							{
  1149  							"client_tls_cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
  1150  							"host": "host1",
  1151  							"port": 123,
  1152  							"server_tls_cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
  1153  							}
  1154  							],
  1155  							"options": {
  1156  							"election_tick": 0,
  1157  							"heartbeat_tick": 0,
  1158  							"max_inflight_blocks": 0,
  1159  							"snapshot_interval_size": 0,
  1160  							"tick_interval": ""
  1161  							}
  1162  							},
  1163  							"state": "STATE_NORMAL",
  1164  							"type": "etcdraft"
  1165  						},
  1166  						"version": "0"
  1167  					}
  1168  				},
  1169  				"version": "0"
  1170  			}
  1171  		},
  1172  		"mod_policy": "",
  1173  		"policies": {
  1174  			"Admins": {
  1175  				"mod_policy": "Admins",
  1176  				"policy": {
  1177  					"type": 3,
  1178  					"value": {
  1179  						"rule": "MAJORITY",
  1180  						"sub_policy": "Admins"
  1181  					}
  1182  				},
  1183  				"version": "0"
  1184  			}
  1185  		},
  1186  		"values": {},
  1187  		"version": "0"
  1188  	},
  1189  	"sequence": "0"
  1190  }
  1191  `, certBase64, crlBase64)
  1192  
  1193  	buf := &bytes.Buffer{}
  1194  	err = protolator.DeepMarshalJSON(buf, c.updated)
  1195  	gt.Expect(err).NotTo(HaveOccurred())
  1196  
  1197  	gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON))
  1198  }
  1199  
  1200  func TestOrdererConfiguration(t *testing.T) {
  1201  	t.Parallel()
  1202  
  1203  	tests := []struct {
  1204  		ordererType string
  1205  	}{
  1206  		{
  1207  			ordererType: orderer.ConsensusTypeSolo,
  1208  		},
  1209  		{
  1210  			ordererType: orderer.ConsensusTypeKafka,
  1211  		},
  1212  		{
  1213  			ordererType: orderer.ConsensusTypeEtcdRaft,
  1214  		},
  1215  	}
  1216  
  1217  	for _, tt := range tests {
  1218  		tt := tt // capture range variable
  1219  		t.Run(tt.ordererType, func(t *testing.T) {
  1220  			t.Parallel()
  1221  
  1222  			gt := NewGomegaWithT(t)
  1223  
  1224  			baseOrdererConf, _ := baseOrdererOfType(t, tt.ordererType)
  1225  
  1226  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  1227  			gt.Expect(err).NotTo(HaveOccurred())
  1228  
  1229  			config := &cb.Config{
  1230  				ChannelGroup: &cb.ConfigGroup{
  1231  					Groups: map[string]*cb.ConfigGroup{
  1232  						OrdererGroupKey: ordererGroup,
  1233  					},
  1234  					Values: map[string]*cb.ConfigValue{},
  1235  				},
  1236  			}
  1237  
  1238  			c := New(config)
  1239  
  1240  			ordererConf, err := c.Orderer().Configuration()
  1241  			gt.Expect(err).NotTo(HaveOccurred())
  1242  			gt.Expect(ordererConf).To(Equal(baseOrdererConf))
  1243  		})
  1244  	}
  1245  }
  1246  
  1247  func TestOrdererConfigurationNoOrdererEndpoints(t *testing.T) {
  1248  	t.Parallel()
  1249  
  1250  	gt := NewGomegaWithT(t)
  1251  
  1252  	baseOrdererConf, _ := baseOrdererOfType(t, orderer.ConsensusTypeSolo)
  1253  
  1254  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  1255  	gt.Expect(err).NotTo(HaveOccurred())
  1256  
  1257  	config := &cb.Config{
  1258  		ChannelGroup: &cb.ConfigGroup{
  1259  			Groups: map[string]*cb.ConfigGroup{
  1260  				OrdererGroupKey: ordererGroup,
  1261  			},
  1262  			Values: map[string]*cb.ConfigValue{},
  1263  		},
  1264  	}
  1265  
  1266  	delete(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Values, EndpointsKey)
  1267  
  1268  	c := New(config)
  1269  
  1270  	ordererConf, err := c.Orderer().Configuration()
  1271  	gt.Expect(err).NotTo(HaveOccurred())
  1272  	baseOrdererConf.Organizations[0].OrdererEndpoints = nil
  1273  	gt.Expect(ordererConf).To(Equal(baseOrdererConf))
  1274  }
  1275  
  1276  func TestOrdererConfigurationFailure(t *testing.T) {
  1277  	t.Parallel()
  1278  
  1279  	tests := []struct {
  1280  		testName    string
  1281  		ordererType string
  1282  		configMod   func(*cb.Config, *GomegaWithT)
  1283  		expectedErr string
  1284  	}{
  1285  		{
  1286  			testName:    "When the config contains an unknown consensus type",
  1287  			ordererType: orderer.ConsensusTypeSolo,
  1288  			configMod: func(config *cb.Config, gt *GomegaWithT) {
  1289  				err := setValue(config.ChannelGroup.Groups[OrdererGroupKey], consensusTypeValue("badtype", nil, 0), AdminsPolicyKey)
  1290  				gt.Expect(err).NotTo(HaveOccurred())
  1291  			},
  1292  			expectedErr: "config contains unknown consensus type 'badtype'",
  1293  		},
  1294  		{
  1295  			testName:    "Missing Kafka brokers for kafka orderer",
  1296  			ordererType: orderer.ConsensusTypeKafka,
  1297  			configMod: func(config *cb.Config, gt *GomegaWithT) {
  1298  				delete(config.ChannelGroup.Groups[OrdererGroupKey].Values, orderer.KafkaBrokersKey)
  1299  			},
  1300  			expectedErr: "unable to find kafka brokers for kafka orderer",
  1301  		},
  1302  		{
  1303  			testName:    "Failed unmarshaling etcd raft metadata",
  1304  			ordererType: orderer.ConsensusTypeEtcdRaft,
  1305  			configMod: func(config *cb.Config, gt *GomegaWithT) {
  1306  				err := setValue(config.ChannelGroup.Groups[OrdererGroupKey], consensusTypeValue(orderer.ConsensusTypeEtcdRaft, nil, 0), AdminsPolicyKey)
  1307  				gt.Expect(err).NotTo(HaveOccurred())
  1308  			},
  1309  			expectedErr: "unmarshaling etcd raft metadata: missing etcdraft metadata options in config",
  1310  		},
  1311  		{
  1312  			testName:    "Invalid batch timeout",
  1313  			ordererType: orderer.ConsensusTypeSolo,
  1314  			configMod: func(config *cb.Config, gt *GomegaWithT) {
  1315  				err := setValue(config.ChannelGroup.Groups[OrdererGroupKey], batchTimeoutValue("invalidtime"), AdminsPolicyKey)
  1316  				gt.Expect(err).NotTo(HaveOccurred())
  1317  			},
  1318  			expectedErr: "batch timeout configuration 'invalidtime' is not a duration string",
  1319  		},
  1320  	}
  1321  
  1322  	for _, tt := range tests {
  1323  		tt := tt
  1324  		t.Run(tt.testName, func(t *testing.T) {
  1325  			t.Parallel()
  1326  
  1327  			gt := NewGomegaWithT(t)
  1328  
  1329  			baseOrdererConfig, _ := baseOrdererOfType(t, tt.ordererType)
  1330  			ordererGroup, err := newOrdererGroup(baseOrdererConfig)
  1331  			gt.Expect(err).NotTo(HaveOccurred())
  1332  
  1333  			config := &cb.Config{
  1334  				ChannelGroup: &cb.ConfigGroup{
  1335  					Groups: map[string]*cb.ConfigGroup{
  1336  						OrdererGroupKey: ordererGroup,
  1337  					},
  1338  					Values: map[string]*cb.ConfigValue{},
  1339  				},
  1340  			}
  1341  
  1342  			if tt.configMod != nil {
  1343  				tt.configMod(config, gt)
  1344  			}
  1345  
  1346  			c := New(config)
  1347  
  1348  			_, err = c.Orderer().Configuration()
  1349  			gt.Expect(err).To(MatchError(tt.expectedErr))
  1350  		})
  1351  	}
  1352  }
  1353  
  1354  func TestSetOrdererOrg(t *testing.T) {
  1355  	t.Parallel()
  1356  
  1357  	gt := NewGomegaWithT(t)
  1358  
  1359  	orderer, _ := baseSoloOrderer(t)
  1360  	ordererGroup, err := newOrdererGroup(orderer)
  1361  	gt.Expect(err).NotTo(HaveOccurred())
  1362  
  1363  	config := &cb.Config{
  1364  		ChannelGroup: &cb.ConfigGroup{
  1365  			Groups: map[string]*cb.ConfigGroup{
  1366  				OrdererGroupKey: ordererGroup,
  1367  			},
  1368  		},
  1369  	}
  1370  
  1371  	c := New(config)
  1372  
  1373  	msp, _ := baseMSP(t)
  1374  	org := Organization{
  1375  		Name:     "OrdererOrg2",
  1376  		Policies: orgStandardPolicies(),
  1377  		OrdererEndpoints: []string{
  1378  			"localhost:123",
  1379  		},
  1380  		MSP: msp,
  1381  	}
  1382  	certBase64, crlBase64 := certCRLBase64(t, org.MSP)
  1383  
  1384  	expectedConfigJSON := fmt.Sprintf(`
  1385  {
  1386  	"groups": {},
  1387  	"mod_policy": "Admins",
  1388  	"policies": {
  1389  		"Admins": {
  1390  			"mod_policy": "Admins",
  1391  			"policy": {
  1392  				"type": 3,
  1393  				"value": {
  1394  					"rule": "MAJORITY",
  1395  					"sub_policy": "Admins"
  1396  				}
  1397  			},
  1398  			"version": "0"
  1399  		},
  1400  		"Endorsement": {
  1401  			"mod_policy": "Admins",
  1402  			"policy": {
  1403  				"type": 3,
  1404  				"value": {
  1405  					"rule": "MAJORITY",
  1406  					"sub_policy": "Endorsement"
  1407  				}
  1408  			},
  1409  			"version": "0"
  1410  		},
  1411  		"Readers": {
  1412  			"mod_policy": "Admins",
  1413  			"policy": {
  1414  				"type": 3,
  1415  				"value": {
  1416  					"rule": "ANY",
  1417  					"sub_policy": "Readers"
  1418  				}
  1419  			},
  1420  			"version": "0"
  1421  		},
  1422  		"Writers": {
  1423  			"mod_policy": "Admins",
  1424  			"policy": {
  1425  				"type": 3,
  1426  				"value": {
  1427  					"rule": "ANY",
  1428  					"sub_policy": "Writers"
  1429  				}
  1430  			},
  1431  			"version": "0"
  1432  		}
  1433  	},
  1434  	"values": {
  1435  		"Endpoints": {
  1436  			"mod_policy": "Admins",
  1437  			"value": {
  1438  				"addresses": [
  1439  					"localhost:123"
  1440  				]
  1441  			},
  1442  			"version": "0"
  1443  		},
  1444  		"MSP": {
  1445  			"mod_policy": "Admins",
  1446  			"value": {
  1447  				"config": {
  1448  					"admins": [
  1449  						"%[1]s"
  1450  					],
  1451  					"crypto_config": {
  1452  						"identity_identifier_hash_function": "SHA256",
  1453  						"signature_hash_family": "SHA3"
  1454  					},
  1455  					"fabric_node_ous": {
  1456  						"admin_ou_identifier": {
  1457  							"certificate": "%[1]s",
  1458  							"organizational_unit_identifier": "OUID"
  1459  						},
  1460  						"client_ou_identifier": {
  1461  							"certificate": "%[1]s",
  1462  							"organizational_unit_identifier": "OUID"
  1463  						},
  1464  						"enable": false,
  1465  						"orderer_ou_identifier": {
  1466  							"certificate": "%[1]s",
  1467  							"organizational_unit_identifier": "OUID"
  1468  						},
  1469  						"peer_ou_identifier": {
  1470  							"certificate": "%[1]s",
  1471  							"organizational_unit_identifier": "OUID"
  1472  						}
  1473  					},
  1474  					"intermediate_certs": [
  1475  						"%[1]s"
  1476  					],
  1477  					"name": "MSPID",
  1478  					"organizational_unit_identifiers": [
  1479  						{
  1480  							"certificate": "%[1]s",
  1481  							"organizational_unit_identifier": "OUID"
  1482  						}
  1483  					],
  1484  					"revocation_list": [
  1485  						"%[2]s"
  1486  					],
  1487  					"root_certs": [
  1488  						"%[1]s"
  1489  					],
  1490  					"signing_identity": null,
  1491  					"tls_intermediate_certs": [
  1492  						"%[1]s"
  1493  					],
  1494  					"tls_root_certs": [
  1495  						"%[1]s"
  1496  					]
  1497  				},
  1498  				"type": 0
  1499  			},
  1500  			"version": "0"
  1501  		}
  1502  	},
  1503  	"version": "0"
  1504  }
  1505  `, certBase64, crlBase64)
  1506  
  1507  	err = c.Orderer().SetOrganization(org)
  1508  	gt.Expect(err).NotTo(HaveOccurred())
  1509  
  1510  	actualOrdererConfigGroup := c.Orderer().Organization("OrdererOrg2").orgGroup
  1511  	buf := bytes.Buffer{}
  1512  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererOrgGroup{ConfigGroup: actualOrdererConfigGroup})
  1513  	gt.Expect(err).NotTo(HaveOccurred())
  1514  	gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON))
  1515  }
  1516  
  1517  func TestSetOrdererOrgFailures(t *testing.T) {
  1518  	t.Parallel()
  1519  
  1520  	gt := NewGomegaWithT(t)
  1521  
  1522  	orderer, _ := baseSoloOrderer(t)
  1523  	ordererGroup, err := newOrdererGroup(orderer)
  1524  	gt.Expect(err).NotTo(HaveOccurred())
  1525  
  1526  	config := &cb.Config{
  1527  		ChannelGroup: &cb.ConfigGroup{
  1528  			Groups: map[string]*cb.ConfigGroup{
  1529  				OrdererGroupKey: ordererGroup,
  1530  			},
  1531  		},
  1532  	}
  1533  
  1534  	c := New(config)
  1535  
  1536  	org := Organization{
  1537  		Name: "OrdererOrg2",
  1538  	}
  1539  
  1540  	err = c.Orderer().SetOrganization(org)
  1541  	gt.Expect(err).To(MatchError("failed to create orderer org OrdererOrg2: no policies defined"))
  1542  }
  1543  
  1544  func TestSetOrdererEndpoint(t *testing.T) {
  1545  	t.Parallel()
  1546  
  1547  	gt := NewGomegaWithT(t)
  1548  
  1549  	config := &cb.Config{
  1550  		ChannelGroup: &cb.ConfigGroup{
  1551  			Groups: map[string]*cb.ConfigGroup{
  1552  				OrdererGroupKey: {
  1553  					Version: 0,
  1554  					Groups: map[string]*cb.ConfigGroup{
  1555  						"Orderer1Org": {
  1556  							Groups: map[string]*cb.ConfigGroup{},
  1557  							Values: map[string]*cb.ConfigValue{
  1558  								EndpointsKey: {
  1559  									ModPolicy: AdminsPolicyKey,
  1560  									Value: marshalOrPanic(&cb.OrdererAddresses{
  1561  										Addresses: []string{"127.0.0.1:8050"},
  1562  									}),
  1563  								},
  1564  							},
  1565  							Policies: map[string]*cb.ConfigPolicy{},
  1566  						},
  1567  					},
  1568  					Values:   map[string]*cb.ConfigValue{},
  1569  					Policies: map[string]*cb.ConfigPolicy{},
  1570  				},
  1571  			},
  1572  			Values:   map[string]*cb.ConfigValue{},
  1573  			Policies: map[string]*cb.ConfigPolicy{},
  1574  		},
  1575  		Sequence: 0,
  1576  	}
  1577  
  1578  	c := New(config)
  1579  
  1580  	expectedUpdatedConfigJSON := `
  1581  {
  1582  	"channel_group": {
  1583  		"groups": {
  1584  			"Orderer": {
  1585  				"groups": {
  1586                      "Orderer1Org": {
  1587  						"groups": {},
  1588  						"mod_policy": "",
  1589  						"policies": {},
  1590  						"values": {
  1591  							"Endpoints": {
  1592  								"mod_policy": "Admins",
  1593  								"value": {
  1594  									"addresses": [
  1595  										"127.0.0.1:8050",
  1596  										"127.0.0.1:9050"
  1597  									]
  1598  								},
  1599  								"version": "0"
  1600  							}
  1601  						},
  1602  						"version": "0"
  1603  					}
  1604  				},
  1605                  "mod_policy": "",
  1606  		        "policies": {},
  1607  		        "values": {},
  1608  				"version": "0"
  1609  			}
  1610  		},
  1611  		"mod_policy": "",
  1612  		"policies": {},
  1613  		"values": {},
  1614  		"version": "0"
  1615  	},
  1616  	"sequence": "0"
  1617  }
  1618  	`
  1619  	expectedUpdatedConfig := &cb.Config{}
  1620  	err := protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedUpdatedConfigJSON), expectedUpdatedConfig)
  1621  	gt.Expect(err).ToNot(HaveOccurred())
  1622  
  1623  	newOrderer1OrgEndpoint := Address{Host: "127.0.0.1", Port: 9050}
  1624  	err = c.Orderer().Organization("Orderer1Org").SetEndpoint(newOrderer1OrgEndpoint)
  1625  	gt.Expect(err).NotTo(HaveOccurred())
  1626  
  1627  	gt.Expect(proto.Equal(c.updated, expectedUpdatedConfig)).To(BeTrue())
  1628  }
  1629  
  1630  func TestRemoveOrdererEndpoint(t *testing.T) {
  1631  	t.Parallel()
  1632  
  1633  	gt := NewGomegaWithT(t)
  1634  
  1635  	config := &cb.Config{
  1636  		ChannelGroup: &cb.ConfigGroup{
  1637  			Groups: map[string]*cb.ConfigGroup{
  1638  				OrdererGroupKey: {
  1639  					Version: 0,
  1640  					Groups: map[string]*cb.ConfigGroup{
  1641  						"OrdererOrg": {
  1642  							Groups: map[string]*cb.ConfigGroup{},
  1643  							Values: map[string]*cb.ConfigValue{
  1644  								EndpointsKey: {
  1645  									ModPolicy: AdminsPolicyKey,
  1646  									Value: marshalOrPanic(&cb.OrdererAddresses{
  1647  										Addresses: []string{
  1648  											"127.0.0.1:7050",
  1649  											"127.0.0.1:8050",
  1650  										},
  1651  									}),
  1652  								},
  1653  							},
  1654  							Policies: map[string]*cb.ConfigPolicy{},
  1655  						},
  1656  					},
  1657  					Values:   map[string]*cb.ConfigValue{},
  1658  					Policies: map[string]*cb.ConfigPolicy{},
  1659  				},
  1660  			},
  1661  			Values:   map[string]*cb.ConfigValue{},
  1662  			Policies: map[string]*cb.ConfigPolicy{},
  1663  		},
  1664  		Sequence: 0,
  1665  	}
  1666  
  1667  	c := New(config)
  1668  
  1669  	expectedUpdatedConfigJSON := `
  1670  {
  1671  	"channel_group": {
  1672  		"groups": {
  1673  			"Orderer": {
  1674  				"groups": {
  1675  					"OrdererOrg": {
  1676  						"groups": {},
  1677  						"mod_policy": "",
  1678  						"policies": {},
  1679  						"values": {
  1680  							"Endpoints": {
  1681  								"mod_policy": "Admins",
  1682  								"value": {
  1683  									"addresses": [
  1684  										"127.0.0.1:7050"
  1685  									]
  1686  								},
  1687  								"version": "0"
  1688  							}
  1689  						},
  1690  						"version": "0"
  1691  					}
  1692  				},
  1693  				"mod_policy": "",
  1694  				"policies": {},
  1695  				"values": {},
  1696  				"version": "0"
  1697  			}
  1698  		},
  1699  		"mod_policy": "",
  1700  		"policies": {},
  1701  		"values": {},
  1702  		"version": "0"
  1703  	},
  1704  	"sequence": "0"
  1705  }
  1706  `
  1707  
  1708  	expectedUpdatedConfig := &cb.Config{}
  1709  	err := protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedUpdatedConfigJSON), expectedUpdatedConfig)
  1710  	gt.Expect(err).ToNot(HaveOccurred())
  1711  
  1712  	removedEndpoint := Address{Host: "127.0.0.1", Port: 8050}
  1713  	err = c.Orderer().Organization("OrdererOrg").RemoveEndpoint(removedEndpoint)
  1714  	gt.Expect(err).NotTo(HaveOccurred())
  1715  
  1716  	gt.Expect(proto.Equal(c.updated, expectedUpdatedConfig)).To(BeTrue())
  1717  }
  1718  
  1719  func TestRemoveOrdererEndpointFailure(t *testing.T) {
  1720  	t.Parallel()
  1721  
  1722  	gt := NewGomegaWithT(t)
  1723  
  1724  	config := &cb.Config{
  1725  		ChannelGroup: &cb.ConfigGroup{
  1726  			Groups: map[string]*cb.ConfigGroup{
  1727  				OrdererGroupKey: {
  1728  					Version: 0,
  1729  					Groups: map[string]*cb.ConfigGroup{
  1730  						"OrdererOrg": {
  1731  							Groups: map[string]*cb.ConfigGroup{},
  1732  							Values: map[string]*cb.ConfigValue{
  1733  								EndpointsKey: {
  1734  									ModPolicy: AdminsPolicyKey,
  1735  									Value:     []byte("fire time"),
  1736  								},
  1737  							},
  1738  							Policies: map[string]*cb.ConfigPolicy{},
  1739  						},
  1740  					},
  1741  					Values:   map[string]*cb.ConfigValue{},
  1742  					Policies: map[string]*cb.ConfigPolicy{},
  1743  				},
  1744  			},
  1745  			Values:   map[string]*cb.ConfigValue{},
  1746  			Policies: map[string]*cb.ConfigPolicy{},
  1747  		},
  1748  		Sequence: 0,
  1749  	}
  1750  
  1751  	c := New(config)
  1752  
  1753  	err := c.Orderer().Organization("OrdererOrg").RemoveEndpoint(Address{Host: "127.0.0.1", Port: 8050})
  1754  	gt.Expect(err).To(MatchError("failed unmarshaling endpoints for orderer org OrdererOrg: proto: can't skip unknown wire type 6"))
  1755  }
  1756  
  1757  func TestGetOrdererOrg(t *testing.T) {
  1758  	t.Parallel()
  1759  	gt := NewGomegaWithT(t)
  1760  
  1761  	ordererChannelGroup, _, err := baseOrdererChannelGroup(t, orderer.ConsensusTypeSolo)
  1762  	gt.Expect(err).NotTo(HaveOccurred())
  1763  
  1764  	config := &cb.Config{
  1765  		ChannelGroup: ordererChannelGroup,
  1766  	}
  1767  
  1768  	ordererOrgGroup := getOrdererOrg(config, "OrdererOrg")
  1769  	gt.Expect(ordererOrgGroup).To(Equal(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"]))
  1770  }
  1771  
  1772  func TestOrdererCapabilities(t *testing.T) {
  1773  	t.Parallel()
  1774  
  1775  	gt := NewGomegaWithT(t)
  1776  
  1777  	baseOrdererConf, _ := baseSoloOrderer(t)
  1778  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  1779  	gt.Expect(err).NotTo(HaveOccurred())
  1780  
  1781  	config := &cb.Config{
  1782  		ChannelGroup: &cb.ConfigGroup{
  1783  			Groups: map[string]*cb.ConfigGroup{
  1784  				OrdererGroupKey: ordererGroup,
  1785  			},
  1786  		},
  1787  	}
  1788  
  1789  	c := New(config)
  1790  
  1791  	ordererCapabilities, err := c.Orderer().Capabilities()
  1792  	gt.Expect(err).NotTo(HaveOccurred())
  1793  	gt.Expect(ordererCapabilities).To(Equal(baseOrdererConf.Capabilities))
  1794  
  1795  	// Delete the capabilities key and assert retrieval to return nil
  1796  	delete(c.Orderer().ordererGroup.Values, CapabilitiesKey)
  1797  	ordererCapabilities, err = c.Orderer().Capabilities()
  1798  	gt.Expect(err).NotTo(HaveOccurred())
  1799  	gt.Expect(ordererCapabilities).To(BeNil())
  1800  }
  1801  
  1802  func TestAddOrdererCapability(t *testing.T) {
  1803  	t.Parallel()
  1804  
  1805  	gt := NewGomegaWithT(t)
  1806  
  1807  	baseOrdererConf, _ := baseSoloOrderer(t)
  1808  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  1809  	gt.Expect(err).NotTo(HaveOccurred())
  1810  
  1811  	config := &cb.Config{
  1812  		ChannelGroup: &cb.ConfigGroup{
  1813  			Groups: map[string]*cb.ConfigGroup{
  1814  				OrdererGroupKey: ordererGroup,
  1815  			},
  1816  		},
  1817  	}
  1818  
  1819  	c := New(config)
  1820  
  1821  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  1822  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  1823  
  1824  	expectedConfigGroupJSON := fmt.Sprintf(`{
  1825  	"groups": {
  1826  		"OrdererOrg": {
  1827  			"groups": {},
  1828  			"mod_policy": "Admins",
  1829  			"policies": {
  1830  				"Admins": {
  1831  					"mod_policy": "Admins",
  1832  					"policy": {
  1833  						"type": 3,
  1834  						"value": {
  1835  							"rule": "MAJORITY",
  1836  							"sub_policy": "Admins"
  1837  						}
  1838  					},
  1839  					"version": "0"
  1840  				},
  1841  				"Endorsement": {
  1842  					"mod_policy": "Admins",
  1843  					"policy": {
  1844  						"type": 3,
  1845  						"value": {
  1846  							"rule": "MAJORITY",
  1847  							"sub_policy": "Endorsement"
  1848  						}
  1849  					},
  1850  					"version": "0"
  1851  				},
  1852  				"Readers": {
  1853  					"mod_policy": "Admins",
  1854  					"policy": {
  1855  						"type": 3,
  1856  						"value": {
  1857  							"rule": "ANY",
  1858  							"sub_policy": "Readers"
  1859  						}
  1860  					},
  1861  					"version": "0"
  1862  				},
  1863  				"Writers": {
  1864  					"mod_policy": "Admins",
  1865  					"policy": {
  1866  						"type": 3,
  1867  						"value": {
  1868  							"rule": "ANY",
  1869  							"sub_policy": "Writers"
  1870  						}
  1871  					},
  1872  					"version": "0"
  1873  				}
  1874  			},
  1875  			"values": {
  1876  				"Endpoints": {
  1877  					"mod_policy": "Admins",
  1878  					"value": {
  1879  						"addresses": [
  1880  							"localhost:123"
  1881  						]
  1882  					},
  1883  					"version": "0"
  1884  				},
  1885  				"MSP": {
  1886  					"mod_policy": "Admins",
  1887  					"value": {
  1888  						"config": {
  1889  							"admins": [
  1890  								"%[1]s"
  1891  							],
  1892  							"crypto_config": {
  1893  								"identity_identifier_hash_function": "SHA256",
  1894  								"signature_hash_family": "SHA3"
  1895  							},
  1896  							"fabric_node_ous": {
  1897  								"admin_ou_identifier": {
  1898  									"certificate": "%[1]s",
  1899  									"organizational_unit_identifier": "OUID"
  1900  								},
  1901  								"client_ou_identifier": {
  1902  									"certificate": "%[1]s",
  1903  									"organizational_unit_identifier": "OUID"
  1904  								},
  1905  								"enable": false,
  1906  								"orderer_ou_identifier": {
  1907  									"certificate": "%[1]s",
  1908  									"organizational_unit_identifier": "OUID"
  1909  								},
  1910  								"peer_ou_identifier": {
  1911  									"certificate": "%[1]s",
  1912  									"organizational_unit_identifier": "OUID"
  1913  								}
  1914  							},
  1915  							"intermediate_certs": [
  1916  								"%[1]s"
  1917  							],
  1918  							"name": "MSPID",
  1919  							"organizational_unit_identifiers": [
  1920  								{
  1921  									"certificate": "%[1]s",
  1922  									"organizational_unit_identifier": "OUID"
  1923  								}
  1924  							],
  1925  							"revocation_list": [
  1926  								"%[2]s"
  1927  							],
  1928  							"root_certs": [
  1929  								"%[1]s"
  1930  							],
  1931  							"signing_identity": null,
  1932  							"tls_intermediate_certs": [
  1933  								"%[1]s"
  1934  							],
  1935  							"tls_root_certs": [
  1936  								"%[1]s"
  1937  							]
  1938  						},
  1939  						"type": 0
  1940  					},
  1941  					"version": "0"
  1942  				}
  1943  			},
  1944  			"version": "0"
  1945  		}
  1946  	},
  1947  	"mod_policy": "Admins",
  1948  	"policies": {
  1949  		"Admins": {
  1950  			"mod_policy": "Admins",
  1951  			"policy": {
  1952  				"type": 3,
  1953  				"value": {
  1954  					"rule": "MAJORITY",
  1955  					"sub_policy": "Admins"
  1956  				}
  1957  			},
  1958  			"version": "0"
  1959  		},
  1960  		"BlockValidation": {
  1961  			"mod_policy": "Admins",
  1962  			"policy": {
  1963  				"type": 3,
  1964  				"value": {
  1965  					"rule": "ANY",
  1966  					"sub_policy": "Writers"
  1967  				}
  1968  			},
  1969  			"version": "0"
  1970  		},
  1971  		"Readers": {
  1972  			"mod_policy": "Admins",
  1973  			"policy": {
  1974  				"type": 3,
  1975  				"value": {
  1976  					"rule": "ANY",
  1977  					"sub_policy": "Readers"
  1978  				}
  1979  			},
  1980  			"version": "0"
  1981  		},
  1982  		"Writers": {
  1983  			"mod_policy": "Admins",
  1984  			"policy": {
  1985  				"type": 3,
  1986  				"value": {
  1987  					"rule": "ANY",
  1988  					"sub_policy": "Writers"
  1989  				}
  1990  			},
  1991  			"version": "0"
  1992  		}
  1993  	},
  1994  	"values": {
  1995  		"BatchSize": {
  1996  			"mod_policy": "Admins",
  1997  			"value": {
  1998  				"absolute_max_bytes": 100,
  1999  				"max_message_count": 100,
  2000  				"preferred_max_bytes": 100
  2001  			},
  2002  			"version": "0"
  2003  		},
  2004  		"BatchTimeout": {
  2005  			"mod_policy": "Admins",
  2006  			"value": {
  2007  				"timeout": "0s"
  2008  			},
  2009  			"version": "0"
  2010  		},
  2011  		"Capabilities": {
  2012  			"mod_policy": "Admins",
  2013  			"value": {
  2014  				"capabilities": {
  2015  					"V1_3": {},
  2016  					"V3_0": {}
  2017  				}
  2018  			},
  2019  			"version": "0"
  2020  		},
  2021  		"ChannelRestrictions": {
  2022  			"mod_policy": "Admins",
  2023  			"value": null,
  2024  			"version": "0"
  2025  		},
  2026  		"ConsensusType": {
  2027  			"mod_policy": "Admins",
  2028  			"value": {
  2029  				"metadata": null,
  2030  				"state": "STATE_NORMAL",
  2031  				"type": "solo"
  2032  			},
  2033  			"version": "0"
  2034  		}
  2035  	},
  2036  	"version": "0"
  2037  }
  2038  `, orgCertBase64, orgCRLBase64)
  2039  
  2040  	capability := "V3_0"
  2041  	err = c.Orderer().AddCapability(capability)
  2042  	gt.Expect(err).NotTo(HaveOccurred())
  2043  
  2044  	buf := bytes.Buffer{}
  2045  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  2046  	gt.Expect(err).NotTo(HaveOccurred())
  2047  
  2048  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  2049  }
  2050  
  2051  func TestAddConsenter(t *testing.T) {
  2052  	t.Parallel()
  2053  
  2054  	tests := []struct {
  2055  		testName    string
  2056  		baseOrderer func(o Orderer) Orderer
  2057  	}{
  2058  		{
  2059  			testName: "when adding a fourth consenter",
  2060  			baseOrderer: func(o Orderer) Orderer {
  2061  				return o
  2062  			},
  2063  		},
  2064  		{
  2065  			testName: "when adding an existing consenter",
  2066  			baseOrderer: func(o Orderer) Orderer {
  2067  				consenter4 := o.EtcdRaft.Consenters[0]
  2068  				consenter4.Address.Host = "node-4.example.com"
  2069  				o.EtcdRaft.Consenters = append(o.EtcdRaft.Consenters, consenter4)
  2070  				return o
  2071  			},
  2072  		},
  2073  	}
  2074  
  2075  	for _, tt := range tests {
  2076  		tt := tt
  2077  		t.Run(tt.testName, func(t *testing.T) {
  2078  			t.Parallel()
  2079  			gt := NewGomegaWithT(t)
  2080  
  2081  			baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  2082  			baseOrdererConf = tt.baseOrderer(baseOrdererConf)
  2083  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  2084  			gt.Expect(err).NotTo(HaveOccurred())
  2085  
  2086  			config := &cb.Config{
  2087  				ChannelGroup: &cb.ConfigGroup{
  2088  					Groups: map[string]*cb.ConfigGroup{
  2089  						OrdererGroupKey: ordererGroup,
  2090  					},
  2091  				},
  2092  			}
  2093  
  2094  			c := New(config)
  2095  
  2096  			ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  2097  			orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  2098  			etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  2099  
  2100  			etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  2101  			expectedConfigGroupJSON := fmt.Sprintf(`{
  2102  	"groups": {
  2103  		"OrdererOrg": {
  2104  			"groups": {},
  2105  			"mod_policy": "Admins",
  2106  			"policies": {
  2107  				"Admins": {
  2108  					"mod_policy": "Admins",
  2109  					"policy": {
  2110  						"type": 3,
  2111  						"value": {
  2112  							"rule": "MAJORITY",
  2113  							"sub_policy": "Admins"
  2114  						}
  2115  					},
  2116  					"version": "0"
  2117  				},
  2118  				"Endorsement": {
  2119  					"mod_policy": "Admins",
  2120  					"policy": {
  2121  						"type": 3,
  2122  						"value": {
  2123  							"rule": "MAJORITY",
  2124  							"sub_policy": "Endorsement"
  2125  						}
  2126  					},
  2127  					"version": "0"
  2128  				},
  2129  				"Readers": {
  2130  					"mod_policy": "Admins",
  2131  					"policy": {
  2132  						"type": 3,
  2133  						"value": {
  2134  							"rule": "ANY",
  2135  							"sub_policy": "Readers"
  2136  						}
  2137  					},
  2138  					"version": "0"
  2139  				},
  2140  				"Writers": {
  2141  					"mod_policy": "Admins",
  2142  					"policy": {
  2143  						"type": 3,
  2144  						"value": {
  2145  							"rule": "ANY",
  2146  							"sub_policy": "Writers"
  2147  						}
  2148  					},
  2149  					"version": "0"
  2150  				}
  2151  			},
  2152  			"values": {
  2153  				"Endpoints": {
  2154  					"mod_policy": "Admins",
  2155  					"value": {
  2156  						"addresses": [
  2157  							"localhost:123"
  2158  						]
  2159  					},
  2160  					"version": "0"
  2161  				},
  2162  				"MSP": {
  2163  					"mod_policy": "Admins",
  2164  					"value": {
  2165  						"config": {
  2166  							"admins": [
  2167  								"%[1]s"
  2168  							],
  2169  							"crypto_config": {
  2170  								"identity_identifier_hash_function": "SHA256",
  2171  								"signature_hash_family": "SHA3"
  2172  							},
  2173  							"fabric_node_ous": {
  2174  								"admin_ou_identifier": {
  2175  									"certificate": "%[1]s",
  2176  									"organizational_unit_identifier": "OUID"
  2177  								},
  2178  								"client_ou_identifier": {
  2179  									"certificate": "%[1]s",
  2180  									"organizational_unit_identifier": "OUID"
  2181  								},
  2182  								"enable": false,
  2183  								"orderer_ou_identifier": {
  2184  									"certificate": "%[1]s",
  2185  									"organizational_unit_identifier": "OUID"
  2186  								},
  2187  								"peer_ou_identifier": {
  2188  									"certificate": "%[1]s",
  2189  									"organizational_unit_identifier": "OUID"
  2190  								}
  2191  							},
  2192  							"intermediate_certs": [
  2193  								"%[1]s"
  2194  							],
  2195  							"name": "MSPID",
  2196  							"organizational_unit_identifiers": [
  2197  								{
  2198  									"certificate": "%[1]s",
  2199  									"organizational_unit_identifier": "OUID"
  2200  								}
  2201  							],
  2202  							"revocation_list": [
  2203  								"%[2]s"
  2204  							],
  2205  							"root_certs": [
  2206  								"%[1]s"
  2207  							],
  2208  							"signing_identity": null,
  2209  							"tls_intermediate_certs": [
  2210  								"%[1]s"
  2211  							],
  2212  							"tls_root_certs": [
  2213  								"%[1]s"
  2214  							]
  2215  						},
  2216  						"type": 0
  2217  					},
  2218  					"version": "0"
  2219  				}
  2220  			},
  2221  			"version": "0"
  2222  		}
  2223  	},
  2224  	"mod_policy": "Admins",
  2225  	"policies": {
  2226  		"Admins": {
  2227  			"mod_policy": "Admins",
  2228  			"policy": {
  2229  				"type": 3,
  2230  				"value": {
  2231  					"rule": "MAJORITY",
  2232  					"sub_policy": "Admins"
  2233  				}
  2234  			},
  2235  			"version": "0"
  2236  		},
  2237  		"BlockValidation": {
  2238  			"mod_policy": "Admins",
  2239  			"policy": {
  2240  				"type": 3,
  2241  				"value": {
  2242  					"rule": "ANY",
  2243  					"sub_policy": "Writers"
  2244  				}
  2245  			},
  2246  			"version": "0"
  2247  		},
  2248  		"Readers": {
  2249  			"mod_policy": "Admins",
  2250  			"policy": {
  2251  				"type": 3,
  2252  				"value": {
  2253  					"rule": "ANY",
  2254  					"sub_policy": "Readers"
  2255  				}
  2256  			},
  2257  			"version": "0"
  2258  		},
  2259  		"Writers": {
  2260  			"mod_policy": "Admins",
  2261  			"policy": {
  2262  				"type": 3,
  2263  				"value": {
  2264  					"rule": "ANY",
  2265  					"sub_policy": "Writers"
  2266  				}
  2267  			},
  2268  			"version": "0"
  2269  		}
  2270  	},
  2271  	"values": {
  2272  		"BatchSize": {
  2273  			"mod_policy": "Admins",
  2274  			"value": {
  2275  				"absolute_max_bytes": 100,
  2276  				"max_message_count": 100,
  2277  				"preferred_max_bytes": 100
  2278  			},
  2279  			"version": "0"
  2280  		},
  2281  		"BatchTimeout": {
  2282  			"mod_policy": "Admins",
  2283  			"value": {
  2284  				"timeout": "0s"
  2285  			},
  2286  			"version": "0"
  2287  		},
  2288  		"Capabilities": {
  2289  			"mod_policy": "Admins",
  2290  			"value": {
  2291  				"capabilities": {
  2292  					"V1_3": {}
  2293  				}
  2294  			},
  2295  			"version": "0"
  2296  		},
  2297  		"ChannelRestrictions": {
  2298  			"mod_policy": "Admins",
  2299  			"value": null,
  2300  			"version": "0"
  2301  		},
  2302  		"ConsensusType": {
  2303  			"mod_policy": "Admins",
  2304  			"value": {
  2305  				"metadata": {
  2306  					"consenters": [
  2307  						{
  2308  							"client_tls_cert": "%[3]s",
  2309  							"host": "node-1.example.com",
  2310  							"port": 7050,
  2311  							"server_tls_cert": "%[3]s"
  2312  						},
  2313  						{
  2314  							"client_tls_cert": "%[3]s",
  2315  							"host": "node-2.example.com",
  2316  							"port": 7050,
  2317  							"server_tls_cert": "%[3]s"
  2318  						},
  2319  						{
  2320  							"client_tls_cert": "%[3]s",
  2321  							"host": "node-3.example.com",
  2322  							"port": 7050,
  2323  							"server_tls_cert": "%[3]s"
  2324  						},
  2325  						{
  2326  							"client_tls_cert": "%[3]s",
  2327  							"host": "node-4.example.com",
  2328  							"port": 7050,
  2329  							"server_tls_cert": "%[3]s"
  2330  						}
  2331  					],
  2332  					"options": {
  2333  						"election_tick": 0,
  2334  						"heartbeat_tick": 0,
  2335  						"max_inflight_blocks": 0,
  2336  						"snapshot_interval_size": 0,
  2337  						"tick_interval": ""
  2338  					}
  2339  				},
  2340  				"state": "STATE_NORMAL",
  2341  				"type": "etcdraft"
  2342  			},
  2343  			"version": "0"
  2344  		}
  2345  	},
  2346  	"version": "0"
  2347  }
  2348  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  2349  
  2350  			consenter := orderer.Consenter{
  2351  				Address: orderer.EtcdAddress{
  2352  					Host: "node-4.example.com",
  2353  					Port: 7050,
  2354  				},
  2355  				ClientTLSCert: etcdRaftCert,
  2356  				ServerTLSCert: etcdRaftCert,
  2357  			}
  2358  
  2359  			err = c.Orderer().AddConsenter(consenter)
  2360  			gt.Expect(err).NotTo(HaveOccurred())
  2361  
  2362  			buf := bytes.Buffer{}
  2363  			err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  2364  			gt.Expect(err).NotTo(HaveOccurred())
  2365  
  2366  			gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  2367  		})
  2368  	}
  2369  }
  2370  
  2371  func TestAddConsenterFailures(t *testing.T) {
  2372  	t.Parallel()
  2373  
  2374  	tests := []struct {
  2375  		testName     string
  2376  		orderer      func(o Orderer) Orderer
  2377  		ordererGroup func(og *cb.ConfigGroup, ord Orderer)
  2378  		consenter    func(c orderer.Consenter) orderer.Consenter
  2379  		expectedErr  string
  2380  	}{
  2381  		{
  2382  			testName: "when retrieving orderer configuration fails",
  2383  			orderer: func(o Orderer) Orderer {
  2384  				return o
  2385  			},
  2386  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2387  				_ = setValue(og, consensusTypeValue("foobar", []byte{}, 1), AdminsPolicyKey)
  2388  			},
  2389  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2390  				return c
  2391  			},
  2392  			expectedErr: "config contains unknown consensus type 'foobar'",
  2393  		},
  2394  		{
  2395  			testName: "when consensus type is not etcdraft",
  2396  			orderer: func(o Orderer) Orderer {
  2397  				o.OrdererType = orderer.ConsensusTypeSolo
  2398  				return o
  2399  			},
  2400  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2401  			},
  2402  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2403  				return c
  2404  			},
  2405  			expectedErr: "consensus type solo is not etcdraft",
  2406  		},
  2407  		{
  2408  			testName: "when marshaling metadata fails",
  2409  			orderer: func(o Orderer) Orderer {
  2410  				return o
  2411  			},
  2412  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2413  			},
  2414  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2415  				c.ClientTLSCert = nil
  2416  				return c
  2417  			},
  2418  			expectedErr: "marshaling etcdraft metadata: client tls cert for consenter node-4.example.com:7050 is required",
  2419  		},
  2420  		{
  2421  			testName: "when the consensus state is invalid",
  2422  			orderer: func(o Orderer) Orderer {
  2423  				return o
  2424  			},
  2425  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2426  				ord.State = "bababa"
  2427  				met, _ := marshalEtcdRaftMetadata(ord.EtcdRaft)
  2428  				_ = setValue(og, consensusTypeValue(ord.OrdererType, met, 3), AdminsPolicyKey)
  2429  			},
  2430  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2431  				return c
  2432  			},
  2433  			expectedErr: "unknown consensus state ''",
  2434  		},
  2435  	}
  2436  
  2437  	for _, tt := range tests {
  2438  		tt := tt
  2439  		t.Run(tt.testName, func(t *testing.T) {
  2440  			t.Parallel()
  2441  
  2442  			gt := NewGomegaWithT(t)
  2443  
  2444  			baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  2445  			ord := tt.orderer(baseOrdererConf)
  2446  
  2447  			ordererGroup, err := newOrdererGroup(ord)
  2448  			gt.Expect(err).NotTo(HaveOccurred())
  2449  			tt.ordererGroup(ordererGroup, ord)
  2450  
  2451  			etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  2452  
  2453  			consenter := orderer.Consenter{
  2454  				Address: orderer.EtcdAddress{
  2455  					Host: "node-4.example.com",
  2456  					Port: 7050,
  2457  				},
  2458  				ClientTLSCert: etcdRaftCert,
  2459  				ServerTLSCert: etcdRaftCert,
  2460  			}
  2461  
  2462  			config := &cb.Config{
  2463  				ChannelGroup: &cb.ConfigGroup{
  2464  					Groups: map[string]*cb.ConfigGroup{
  2465  						OrdererGroupKey: ordererGroup,
  2466  					},
  2467  				},
  2468  			}
  2469  
  2470  			c := New(config)
  2471  
  2472  			err = c.Orderer().AddConsenter(tt.consenter(consenter))
  2473  			gt.Expect(err).To(MatchError(tt.expectedErr))
  2474  		})
  2475  	}
  2476  }
  2477  
  2478  func TestRemoveConsenter(t *testing.T) {
  2479  	t.Parallel()
  2480  
  2481  	gt := NewGomegaWithT(t)
  2482  
  2483  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  2484  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  2485  	gt.Expect(err).NotTo(HaveOccurred())
  2486  
  2487  	config := &cb.Config{
  2488  		ChannelGroup: &cb.ConfigGroup{
  2489  			Groups: map[string]*cb.ConfigGroup{
  2490  				OrdererGroupKey: ordererGroup,
  2491  			},
  2492  		},
  2493  	}
  2494  
  2495  	c := New(config)
  2496  
  2497  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  2498  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  2499  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  2500  
  2501  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  2502  	expectedConfigGroupJSON := fmt.Sprintf(`{
  2503  	"groups": {
  2504  		"OrdererOrg": {
  2505  			"groups": {},
  2506  			"mod_policy": "Admins",
  2507  			"policies": {
  2508  				"Admins": {
  2509  					"mod_policy": "Admins",
  2510  					"policy": {
  2511  						"type": 3,
  2512  						"value": {
  2513  							"rule": "MAJORITY",
  2514  							"sub_policy": "Admins"
  2515  						}
  2516  					},
  2517  					"version": "0"
  2518  				},
  2519  				"Endorsement": {
  2520  					"mod_policy": "Admins",
  2521  					"policy": {
  2522  						"type": 3,
  2523  						"value": {
  2524  							"rule": "MAJORITY",
  2525  							"sub_policy": "Endorsement"
  2526  						}
  2527  					},
  2528  					"version": "0"
  2529  				},
  2530  				"Readers": {
  2531  					"mod_policy": "Admins",
  2532  					"policy": {
  2533  						"type": 3,
  2534  						"value": {
  2535  							"rule": "ANY",
  2536  							"sub_policy": "Readers"
  2537  						}
  2538  					},
  2539  					"version": "0"
  2540  				},
  2541  				"Writers": {
  2542  					"mod_policy": "Admins",
  2543  					"policy": {
  2544  						"type": 3,
  2545  						"value": {
  2546  							"rule": "ANY",
  2547  							"sub_policy": "Writers"
  2548  						}
  2549  					},
  2550  					"version": "0"
  2551  				}
  2552  			},
  2553  			"values": {
  2554  				"Endpoints": {
  2555  					"mod_policy": "Admins",
  2556  					"value": {
  2557  						"addresses": [
  2558  							"localhost:123"
  2559  						]
  2560  					},
  2561  					"version": "0"
  2562  				},
  2563  				"MSP": {
  2564  					"mod_policy": "Admins",
  2565  					"value": {
  2566  						"config": {
  2567  							"admins": [
  2568  								"%[1]s"
  2569  							],
  2570  							"crypto_config": {
  2571  								"identity_identifier_hash_function": "SHA256",
  2572  								"signature_hash_family": "SHA3"
  2573  							},
  2574  							"fabric_node_ous": {
  2575  								"admin_ou_identifier": {
  2576  									"certificate": "%[1]s",
  2577  									"organizational_unit_identifier": "OUID"
  2578  								},
  2579  								"client_ou_identifier": {
  2580  									"certificate": "%[1]s",
  2581  									"organizational_unit_identifier": "OUID"
  2582  								},
  2583  								"enable": false,
  2584  								"orderer_ou_identifier": {
  2585  									"certificate": "%[1]s",
  2586  									"organizational_unit_identifier": "OUID"
  2587  								},
  2588  								"peer_ou_identifier": {
  2589  									"certificate": "%[1]s",
  2590  									"organizational_unit_identifier": "OUID"
  2591  								}
  2592  							},
  2593  							"intermediate_certs": [
  2594  								"%[1]s"
  2595  							],
  2596  							"name": "MSPID",
  2597  							"organizational_unit_identifiers": [
  2598  								{
  2599  									"certificate": "%[1]s",
  2600  									"organizational_unit_identifier": "OUID"
  2601  								}
  2602  							],
  2603  							"revocation_list": [
  2604  								"%[2]s"
  2605  							],
  2606  							"root_certs": [
  2607  								"%[1]s"
  2608  							],
  2609  							"signing_identity": null,
  2610  							"tls_intermediate_certs": [
  2611  								"%[1]s"
  2612  							],
  2613  							"tls_root_certs": [
  2614  								"%[1]s"
  2615  							]
  2616  						},
  2617  						"type": 0
  2618  					},
  2619  					"version": "0"
  2620  				}
  2621  			},
  2622  			"version": "0"
  2623  		}
  2624  	},
  2625  	"mod_policy": "Admins",
  2626  	"policies": {
  2627  		"Admins": {
  2628  			"mod_policy": "Admins",
  2629  			"policy": {
  2630  				"type": 3,
  2631  				"value": {
  2632  					"rule": "MAJORITY",
  2633  					"sub_policy": "Admins"
  2634  				}
  2635  			},
  2636  			"version": "0"
  2637  		},
  2638  		"BlockValidation": {
  2639  			"mod_policy": "Admins",
  2640  			"policy": {
  2641  				"type": 3,
  2642  				"value": {
  2643  					"rule": "ANY",
  2644  					"sub_policy": "Writers"
  2645  				}
  2646  			},
  2647  			"version": "0"
  2648  		},
  2649  		"Readers": {
  2650  			"mod_policy": "Admins",
  2651  			"policy": {
  2652  				"type": 3,
  2653  				"value": {
  2654  					"rule": "ANY",
  2655  					"sub_policy": "Readers"
  2656  				}
  2657  			},
  2658  			"version": "0"
  2659  		},
  2660  		"Writers": {
  2661  			"mod_policy": "Admins",
  2662  			"policy": {
  2663  				"type": 3,
  2664  				"value": {
  2665  					"rule": "ANY",
  2666  					"sub_policy": "Writers"
  2667  				}
  2668  			},
  2669  			"version": "0"
  2670  		}
  2671  	},
  2672  	"values": {
  2673  		"BatchSize": {
  2674  			"mod_policy": "Admins",
  2675  			"value": {
  2676  				"absolute_max_bytes": 100,
  2677  				"max_message_count": 100,
  2678  				"preferred_max_bytes": 100
  2679  			},
  2680  			"version": "0"
  2681  		},
  2682  		"BatchTimeout": {
  2683  			"mod_policy": "Admins",
  2684  			"value": {
  2685  				"timeout": "0s"
  2686  			},
  2687  			"version": "0"
  2688  		},
  2689  		"Capabilities": {
  2690  			"mod_policy": "Admins",
  2691  			"value": {
  2692  				"capabilities": {
  2693  					"V1_3": {}
  2694  				}
  2695  			},
  2696  			"version": "0"
  2697  		},
  2698  		"ChannelRestrictions": {
  2699  			"mod_policy": "Admins",
  2700  			"value": null,
  2701  			"version": "0"
  2702  		},
  2703  		"ConsensusType": {
  2704  			"mod_policy": "Admins",
  2705  			"value": {
  2706  				"metadata": {
  2707  					"consenters": [
  2708  						{
  2709  							"client_tls_cert": "%[3]s",
  2710  							"host": "node-2.example.com",
  2711  							"port": 7050,
  2712  							"server_tls_cert": "%[3]s"
  2713  						},
  2714  						{
  2715  							"client_tls_cert": "%[3]s",
  2716  							"host": "node-3.example.com",
  2717  							"port": 7050,
  2718  							"server_tls_cert": "%[3]s"
  2719  						}
  2720  					],
  2721  					"options": {
  2722  						"election_tick": 0,
  2723  						"heartbeat_tick": 0,
  2724  						"max_inflight_blocks": 0,
  2725  						"snapshot_interval_size": 0,
  2726  						"tick_interval": ""
  2727  					}
  2728  				},
  2729  				"state": "STATE_NORMAL",
  2730  				"type": "etcdraft"
  2731  			},
  2732  			"version": "0"
  2733  		}
  2734  	},
  2735  	"version": "0"
  2736  }
  2737  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  2738  
  2739  	consenter := orderer.Consenter{
  2740  		Address: orderer.EtcdAddress{
  2741  			Host: "node-1.example.com",
  2742  			Port: 7050,
  2743  		},
  2744  		ClientTLSCert: etcdRaftCert,
  2745  		ServerTLSCert: etcdRaftCert,
  2746  	}
  2747  
  2748  	err = c.Orderer().RemoveConsenter(consenter)
  2749  	gt.Expect(err).NotTo(HaveOccurred())
  2750  
  2751  	buf := bytes.Buffer{}
  2752  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  2753  	gt.Expect(err).NotTo(HaveOccurred())
  2754  
  2755  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  2756  }
  2757  
  2758  func TestRemoveConsenterFailures(t *testing.T) {
  2759  	t.Parallel()
  2760  
  2761  	tests := []struct {
  2762  		testName     string
  2763  		orderer      func(o Orderer) Orderer
  2764  		ordererGroup func(og *cb.ConfigGroup, ord Orderer)
  2765  		consenter    func(c orderer.Consenter) orderer.Consenter
  2766  		expectedErr  string
  2767  	}{
  2768  		{
  2769  			testName: "when retrieving orderer configuration fails",
  2770  			orderer: func(o Orderer) Orderer {
  2771  				return o
  2772  			},
  2773  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2774  				_ = setValue(og, consensusTypeValue("foobar", []byte{}, 1), AdminsPolicyKey)
  2775  			},
  2776  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2777  				return c
  2778  			},
  2779  			expectedErr: "config contains unknown consensus type 'foobar'",
  2780  		},
  2781  		{
  2782  			testName: "when consensus type is not etcdraft",
  2783  			orderer: func(o Orderer) Orderer {
  2784  				o.OrdererType = orderer.ConsensusTypeSolo
  2785  				return o
  2786  			},
  2787  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2788  			},
  2789  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2790  				return c
  2791  			},
  2792  			expectedErr: "consensus type solo is not etcdraft",
  2793  		},
  2794  		{
  2795  			testName: "when the consensus state is invalid",
  2796  			orderer: func(o Orderer) Orderer {
  2797  				return o
  2798  			},
  2799  			ordererGroup: func(og *cb.ConfigGroup, ord Orderer) {
  2800  				ord.State = "bababa"
  2801  				met, _ := marshalEtcdRaftMetadata(ord.EtcdRaft)
  2802  				_ = setValue(og, consensusTypeValue(ord.OrdererType, met, 3), AdminsPolicyKey)
  2803  			},
  2804  			consenter: func(c orderer.Consenter) orderer.Consenter {
  2805  				return c
  2806  			},
  2807  			expectedErr: "unknown consensus state ''",
  2808  		},
  2809  	}
  2810  
  2811  	for _, tt := range tests {
  2812  		tt := tt
  2813  		t.Run(tt.testName, func(t *testing.T) {
  2814  			t.Parallel()
  2815  
  2816  			gt := NewGomegaWithT(t)
  2817  
  2818  			baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  2819  			ord := tt.orderer(baseOrdererConf)
  2820  
  2821  			ordererGroup, err := newOrdererGroup(ord)
  2822  			gt.Expect(err).NotTo(HaveOccurred())
  2823  			tt.ordererGroup(ordererGroup, ord)
  2824  
  2825  			etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  2826  
  2827  			consenter := orderer.Consenter{
  2828  				Address: orderer.EtcdAddress{
  2829  					Host: "node-4.example.com",
  2830  					Port: 7050,
  2831  				},
  2832  				ClientTLSCert: etcdRaftCert,
  2833  				ServerTLSCert: etcdRaftCert,
  2834  			}
  2835  
  2836  			config := &cb.Config{
  2837  				ChannelGroup: &cb.ConfigGroup{
  2838  					Groups: map[string]*cb.ConfigGroup{
  2839  						OrdererGroupKey: ordererGroup,
  2840  					},
  2841  				},
  2842  			}
  2843  
  2844  			c := New(config)
  2845  
  2846  			err = c.Orderer().RemoveConsenter(tt.consenter(consenter))
  2847  			gt.Expect(err).To(MatchError(tt.expectedErr))
  2848  		})
  2849  	}
  2850  }
  2851  
  2852  func TestAddOrdererCapabilityFailures(t *testing.T) {
  2853  	t.Parallel()
  2854  
  2855  	tests := []struct {
  2856  		testName     string
  2857  		capability   string
  2858  		ordererGroup func(og *cb.ConfigGroup)
  2859  		expectedErr  string
  2860  	}{
  2861  		{
  2862  			testName:   "when retrieving existing capabilities",
  2863  			capability: "V1_3",
  2864  			ordererGroup: func(og *cb.ConfigGroup) {
  2865  				og.Values = map[string]*cb.ConfigValue{
  2866  					CapabilitiesKey: {
  2867  						Value: []byte("foobar"),
  2868  					},
  2869  				}
  2870  			},
  2871  			expectedErr: "retrieving orderer capabilities: unmarshaling capabilities: proto: can't skip unknown wire type 6",
  2872  		},
  2873  	}
  2874  
  2875  	for _, tt := range tests {
  2876  		tt := tt
  2877  		t.Run(tt.testName, func(t *testing.T) {
  2878  			t.Parallel()
  2879  
  2880  			gt := NewGomegaWithT(t)
  2881  
  2882  			baseOrdererConf, _ := baseSoloOrderer(t)
  2883  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  2884  			gt.Expect(err).NotTo(HaveOccurred())
  2885  			tt.ordererGroup(ordererGroup)
  2886  
  2887  			config := &cb.Config{
  2888  				ChannelGroup: &cb.ConfigGroup{
  2889  					Groups: map[string]*cb.ConfigGroup{
  2890  						OrdererGroupKey: ordererGroup,
  2891  					},
  2892  				},
  2893  			}
  2894  
  2895  			c := New(config)
  2896  
  2897  			err = c.Orderer().AddCapability(tt.capability)
  2898  			gt.Expect(err).To(MatchError(tt.expectedErr))
  2899  		})
  2900  	}
  2901  }
  2902  
  2903  func TestRemoveOrdererCapability(t *testing.T) {
  2904  	t.Parallel()
  2905  
  2906  	gt := NewGomegaWithT(t)
  2907  
  2908  	baseOrdererConf, _ := baseSoloOrderer(t)
  2909  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  2910  	gt.Expect(err).NotTo(HaveOccurred())
  2911  
  2912  	config := &cb.Config{
  2913  		ChannelGroup: &cb.ConfigGroup{
  2914  			Groups: map[string]*cb.ConfigGroup{
  2915  				OrdererGroupKey: ordererGroup,
  2916  			},
  2917  		},
  2918  	}
  2919  
  2920  	c := New(config)
  2921  
  2922  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  2923  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  2924  
  2925  	expectedConfigGroupJSON := fmt.Sprintf(`{
  2926  	"groups": {
  2927  		"OrdererOrg": {
  2928  			"groups": {},
  2929  			"mod_policy": "Admins",
  2930  			"policies": {
  2931  				"Admins": {
  2932  					"mod_policy": "Admins",
  2933  					"policy": {
  2934  						"type": 3,
  2935  						"value": {
  2936  							"rule": "MAJORITY",
  2937  							"sub_policy": "Admins"
  2938  						}
  2939  					},
  2940  					"version": "0"
  2941  				},
  2942  				"Endorsement": {
  2943  					"mod_policy": "Admins",
  2944  					"policy": {
  2945  						"type": 3,
  2946  						"value": {
  2947  							"rule": "MAJORITY",
  2948  							"sub_policy": "Endorsement"
  2949  						}
  2950  					},
  2951  					"version": "0"
  2952  				},
  2953  				"Readers": {
  2954  					"mod_policy": "Admins",
  2955  					"policy": {
  2956  						"type": 3,
  2957  						"value": {
  2958  							"rule": "ANY",
  2959  							"sub_policy": "Readers"
  2960  						}
  2961  					},
  2962  					"version": "0"
  2963  				},
  2964  				"Writers": {
  2965  					"mod_policy": "Admins",
  2966  					"policy": {
  2967  						"type": 3,
  2968  						"value": {
  2969  							"rule": "ANY",
  2970  							"sub_policy": "Writers"
  2971  						}
  2972  					},
  2973  					"version": "0"
  2974  				}
  2975  			},
  2976  			"values": {
  2977  				"Endpoints": {
  2978  					"mod_policy": "Admins",
  2979  					"value": {
  2980  						"addresses": [
  2981  							"localhost:123"
  2982  						]
  2983  					},
  2984  					"version": "0"
  2985  				},
  2986  				"MSP": {
  2987  					"mod_policy": "Admins",
  2988  					"value": {
  2989  						"config": {
  2990  							"admins": [
  2991  								"%[1]s"
  2992  							],
  2993  							"crypto_config": {
  2994  								"identity_identifier_hash_function": "SHA256",
  2995  								"signature_hash_family": "SHA3"
  2996  							},
  2997  							"fabric_node_ous": {
  2998  								"admin_ou_identifier": {
  2999  									"certificate": "%[1]s",
  3000  									"organizational_unit_identifier": "OUID"
  3001  								},
  3002  								"client_ou_identifier": {
  3003  									"certificate": "%[1]s",
  3004  									"organizational_unit_identifier": "OUID"
  3005  								},
  3006  								"enable": false,
  3007  								"orderer_ou_identifier": {
  3008  									"certificate": "%[1]s",
  3009  									"organizational_unit_identifier": "OUID"
  3010  								},
  3011  								"peer_ou_identifier": {
  3012  									"certificate": "%[1]s",
  3013  									"organizational_unit_identifier": "OUID"
  3014  								}
  3015  							},
  3016  							"intermediate_certs": [
  3017  								"%[1]s"
  3018  							],
  3019  							"name": "MSPID",
  3020  							"organizational_unit_identifiers": [
  3021  								{
  3022  									"certificate": "%[1]s",
  3023  									"organizational_unit_identifier": "OUID"
  3024  								}
  3025  							],
  3026  							"revocation_list": [
  3027  								"%[2]s"
  3028  							],
  3029  							"root_certs": [
  3030  								"%[1]s"
  3031  							],
  3032  							"signing_identity": null,
  3033  							"tls_intermediate_certs": [
  3034  								"%[1]s"
  3035  							],
  3036  							"tls_root_certs": [
  3037  								"%[1]s"
  3038  							]
  3039  						},
  3040  						"type": 0
  3041  					},
  3042  					"version": "0"
  3043  				}
  3044  			},
  3045  			"version": "0"
  3046  		}
  3047  	},
  3048  	"mod_policy": "Admins",
  3049  	"policies": {
  3050  		"Admins": {
  3051  			"mod_policy": "Admins",
  3052  			"policy": {
  3053  				"type": 3,
  3054  				"value": {
  3055  					"rule": "MAJORITY",
  3056  					"sub_policy": "Admins"
  3057  				}
  3058  			},
  3059  			"version": "0"
  3060  		},
  3061  		"BlockValidation": {
  3062  			"mod_policy": "Admins",
  3063  			"policy": {
  3064  				"type": 3,
  3065  				"value": {
  3066  					"rule": "ANY",
  3067  					"sub_policy": "Writers"
  3068  				}
  3069  			},
  3070  			"version": "0"
  3071  		},
  3072  		"Readers": {
  3073  			"mod_policy": "Admins",
  3074  			"policy": {
  3075  				"type": 3,
  3076  				"value": {
  3077  					"rule": "ANY",
  3078  					"sub_policy": "Readers"
  3079  				}
  3080  			},
  3081  			"version": "0"
  3082  		},
  3083  		"Writers": {
  3084  			"mod_policy": "Admins",
  3085  			"policy": {
  3086  				"type": 3,
  3087  				"value": {
  3088  					"rule": "ANY",
  3089  					"sub_policy": "Writers"
  3090  				}
  3091  			},
  3092  			"version": "0"
  3093  		}
  3094  	},
  3095  	"values": {
  3096  		"BatchSize": {
  3097  			"mod_policy": "Admins",
  3098  			"value": {
  3099  				"absolute_max_bytes": 100,
  3100  				"max_message_count": 100,
  3101  				"preferred_max_bytes": 100
  3102  			},
  3103  			"version": "0"
  3104  		},
  3105  		"BatchTimeout": {
  3106  			"mod_policy": "Admins",
  3107  			"value": {
  3108  				"timeout": "0s"
  3109  			},
  3110  			"version": "0"
  3111  		},
  3112  		"Capabilities": {
  3113  			"mod_policy": "Admins",
  3114  			"value": {
  3115  				"capabilities": {}
  3116  			},
  3117  			"version": "0"
  3118  		},
  3119  		"ChannelRestrictions": {
  3120  			"mod_policy": "Admins",
  3121  			"value": null,
  3122  			"version": "0"
  3123  		},
  3124  		"ConsensusType": {
  3125  			"mod_policy": "Admins",
  3126  			"value": {
  3127  				"metadata": null,
  3128  				"state": "STATE_NORMAL",
  3129  				"type": "solo"
  3130  			},
  3131  			"version": "0"
  3132  		}
  3133  	},
  3134  	"version": "0"
  3135  }
  3136  `, orgCertBase64, orgCRLBase64)
  3137  
  3138  	capability := "V1_3"
  3139  	err = c.Orderer().RemoveCapability(capability)
  3140  	gt.Expect(err).NotTo(HaveOccurred())
  3141  
  3142  	buf := bytes.Buffer{}
  3143  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  3144  	gt.Expect(err).NotTo(HaveOccurred())
  3145  
  3146  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  3147  }
  3148  
  3149  func TestRemoveOrdererCapabilityFailures(t *testing.T) {
  3150  	t.Parallel()
  3151  
  3152  	tests := []struct {
  3153  		testName     string
  3154  		capability   string
  3155  		ordererGroup func(og *cb.ConfigGroup)
  3156  		expectedErr  string
  3157  	}{
  3158  		{
  3159  			testName:   "when capability does not exist",
  3160  			capability: "V3_0",
  3161  			ordererGroup: func(og *cb.ConfigGroup) {
  3162  			},
  3163  			expectedErr: "capability not set",
  3164  		},
  3165  		{
  3166  			testName:   "when retrieving existing capabilities",
  3167  			capability: "V3_0",
  3168  			ordererGroup: func(og *cb.ConfigGroup) {
  3169  				og.Values = map[string]*cb.ConfigValue{
  3170  					CapabilitiesKey: {
  3171  						Value: []byte("foobar"),
  3172  					},
  3173  				}
  3174  			},
  3175  			expectedErr: "retrieving orderer capabilities: unmarshaling capabilities: proto: can't skip unknown wire type 6",
  3176  		},
  3177  	}
  3178  
  3179  	for _, tt := range tests {
  3180  		tt := tt
  3181  		t.Run(tt.testName, func(t *testing.T) {
  3182  			t.Parallel()
  3183  
  3184  			gt := NewGomegaWithT(t)
  3185  
  3186  			baseOrdererConf, _ := baseSoloOrderer(t)
  3187  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3188  			gt.Expect(err).NotTo(HaveOccurred())
  3189  			tt.ordererGroup(ordererGroup)
  3190  
  3191  			config := &cb.Config{
  3192  				ChannelGroup: &cb.ConfigGroup{
  3193  					Groups: map[string]*cb.ConfigGroup{
  3194  						OrdererGroupKey: ordererGroup,
  3195  					},
  3196  				},
  3197  			}
  3198  
  3199  			c := New(config)
  3200  
  3201  			err = c.Orderer().RemoveCapability(tt.capability)
  3202  			gt.Expect(err).To(MatchError(tt.expectedErr))
  3203  		})
  3204  	}
  3205  }
  3206  
  3207  func TestOrdererOrg(t *testing.T) {
  3208  	t.Parallel()
  3209  	gt := NewGomegaWithT(t)
  3210  
  3211  	channel, _, _ := baseSystemChannelProfile(t)
  3212  	channelGroup, err := newSystemChannelGroup(channel)
  3213  	gt.Expect(err).NotTo(HaveOccurred())
  3214  
  3215  	config := &cb.Config{
  3216  		ChannelGroup: channelGroup,
  3217  	}
  3218  
  3219  	c := New(config)
  3220  
  3221  	expectedOrg := channel.Orderer.Organizations[0]
  3222  
  3223  	tests := []struct {
  3224  		name        string
  3225  		orgName     string
  3226  		expectedErr string
  3227  	}{
  3228  		{
  3229  			name:        "success",
  3230  			orgName:     "OrdererOrg",
  3231  			expectedErr: "",
  3232  		},
  3233  	}
  3234  
  3235  	for _, tc := range tests {
  3236  		tc := tc
  3237  		t.Run(tc.name, func(t *testing.T) {
  3238  			t.Parallel()
  3239  			gt := NewGomegaWithT(t)
  3240  
  3241  			org, err := c.Orderer().Organization(tc.orgName).Configuration()
  3242  			if tc.expectedErr != "" {
  3243  				gt.Expect(err).To(MatchError(tc.expectedErr))
  3244  				gt.Expect(Organization{}).To(Equal(org))
  3245  			} else {
  3246  				gt.Expect(err).NotTo(HaveOccurred())
  3247  				gt.Expect(expectedOrg).To(Equal(org))
  3248  			}
  3249  		})
  3250  	}
  3251  }
  3252  
  3253  func TestRemoveOrdererOrg(t *testing.T) {
  3254  	t.Parallel()
  3255  	gt := NewGomegaWithT(t)
  3256  
  3257  	channel, _, _ := baseSystemChannelProfile(t)
  3258  	channelGroup, err := newSystemChannelGroup(channel)
  3259  	gt.Expect(err).NotTo(HaveOccurred())
  3260  
  3261  	config := &cb.Config{
  3262  		ChannelGroup: channelGroup,
  3263  	}
  3264  
  3265  	c := New(config)
  3266  
  3267  	c.Orderer().RemoveOrganization("OrdererOrg")
  3268  	gt.Expect(c.Orderer().Organization("OrdererOrg")).To(BeNil())
  3269  }
  3270  
  3271  func TestSetOrdererModPolicy(t *testing.T) {
  3272  	t.Parallel()
  3273  
  3274  	gt := NewGomegaWithT(t)
  3275  
  3276  	baseOrdererConf, _ := baseSoloOrderer(t)
  3277  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3278  	gt.Expect(err).NotTo(HaveOccurred())
  3279  
  3280  	config := &cb.Config{
  3281  		ChannelGroup: &cb.ConfigGroup{
  3282  			Groups: map[string]*cb.ConfigGroup{
  3283  				"Orderer": ordererGroup,
  3284  			},
  3285  		},
  3286  	}
  3287  
  3288  	c := New(config)
  3289  
  3290  	err = c.Orderer().SetModPolicy("TestModPolicy")
  3291  	gt.Expect(err).NotTo(HaveOccurred())
  3292  
  3293  	updatedModPolicy := c.Orderer().ordererGroup.GetModPolicy()
  3294  	gt.Expect(updatedModPolicy).To(Equal("TestModPolicy"))
  3295  }
  3296  
  3297  func TestSetOrdererModPolicyFailures(t *testing.T) {
  3298  	t.Parallel()
  3299  
  3300  	gt := NewGomegaWithT(t)
  3301  
  3302  	baseOrdererConf, _ := baseSoloOrderer(t)
  3303  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3304  	gt.Expect(err).NotTo(HaveOccurred())
  3305  
  3306  	config := &cb.Config{
  3307  		ChannelGroup: &cb.ConfigGroup{
  3308  			Groups: map[string]*cb.ConfigGroup{
  3309  				"Orderer": ordererGroup,
  3310  			},
  3311  		},
  3312  	}
  3313  
  3314  	c := New(config)
  3315  
  3316  	err = c.Orderer().SetModPolicy("")
  3317  	gt.Expect(err).To(MatchError("non empty mod policy is required"))
  3318  }
  3319  
  3320  func TestSetOrdererPolicy(t *testing.T) {
  3321  	t.Parallel()
  3322  
  3323  	gt := NewGomegaWithT(t)
  3324  
  3325  	baseOrdererConf, _ := baseSoloOrderer(t)
  3326  
  3327  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3328  	gt.Expect(err).NotTo(HaveOccurred())
  3329  
  3330  	config := &cb.Config{
  3331  		ChannelGroup: &cb.ConfigGroup{
  3332  			Groups: map[string]*cb.ConfigGroup{
  3333  				"Orderer": ordererGroup,
  3334  			},
  3335  		},
  3336  	}
  3337  
  3338  	c := New(config)
  3339  
  3340  	expectedPolicies := map[string]Policy{
  3341  		ReadersPolicyKey: {
  3342  			Type:      ImplicitMetaPolicyType,
  3343  			Rule:      "ANY Readers",
  3344  			ModPolicy: AdminsPolicyKey,
  3345  		},
  3346  		WritersPolicyKey: {
  3347  			Type:      ImplicitMetaPolicyType,
  3348  			Rule:      "ANY Writers",
  3349  			ModPolicy: AdminsPolicyKey,
  3350  		},
  3351  		AdminsPolicyKey: {
  3352  			Type:      ImplicitMetaPolicyType,
  3353  			Rule:      "MAJORITY Admins",
  3354  			ModPolicy: AdminsPolicyKey,
  3355  		},
  3356  		BlockValidationPolicyKey: {
  3357  			Type:      ImplicitMetaPolicyType,
  3358  			Rule:      "ANY Writers",
  3359  			ModPolicy: AdminsPolicyKey,
  3360  		},
  3361  		"TestPolicy": {
  3362  			Type:      ImplicitMetaPolicyType,
  3363  			Rule:      "ANY Endorsement",
  3364  			ModPolicy: AdminsPolicyKey,
  3365  		},
  3366  	}
  3367  
  3368  	err = c.Orderer().SetPolicy("TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Endorsement"})
  3369  	gt.Expect(err).NotTo(HaveOccurred())
  3370  
  3371  	updatedPolicies, err := c.Orderer().Policies()
  3372  	gt.Expect(err).NotTo(HaveOccurred())
  3373  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  3374  }
  3375  
  3376  func TestSetOrdererPolicyFailures(t *testing.T) {
  3377  	t.Parallel()
  3378  
  3379  	gt := NewGomegaWithT(t)
  3380  
  3381  	baseOrdererConf, _ := baseSoloOrderer(t)
  3382  
  3383  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3384  	gt.Expect(err).NotTo(HaveOccurred())
  3385  
  3386  	config := &cb.Config{
  3387  		ChannelGroup: &cb.ConfigGroup{
  3388  			Groups: map[string]*cb.ConfigGroup{
  3389  				"Orderer": ordererGroup,
  3390  			},
  3391  		},
  3392  	}
  3393  
  3394  	c := New(config)
  3395  
  3396  	err = c.Orderer().SetPolicy("TestPolicy", Policy{})
  3397  	gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: "))
  3398  }
  3399  
  3400  func TestSetOrdererPolicies(t *testing.T) {
  3401  	t.Parallel()
  3402  
  3403  	gt := NewGomegaWithT(t)
  3404  
  3405  	baseOrdererConf, _ := baseSoloOrderer(t)
  3406  	baseOrdererConf.Policies["TestPolicy_Remove"] = baseOrdererConf.Policies[ReadersPolicyKey]
  3407  
  3408  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3409  	gt.Expect(err).NotTo(HaveOccurred())
  3410  
  3411  	config := &cb.Config{
  3412  		ChannelGroup: &cb.ConfigGroup{
  3413  			Groups: map[string]*cb.ConfigGroup{
  3414  				"Orderer": ordererGroup,
  3415  			},
  3416  		},
  3417  	}
  3418  
  3419  	c := New(config)
  3420  
  3421  	newPolices := map[string]Policy{
  3422  		ReadersPolicyKey: {
  3423  			Type:      ImplicitMetaPolicyType,
  3424  			Rule:      "ANY Readers",
  3425  			ModPolicy: AdminsPolicyKey,
  3426  		},
  3427  		WritersPolicyKey: {
  3428  			Type:      ImplicitMetaPolicyType,
  3429  			Rule:      "ANY Writers",
  3430  			ModPolicy: AdminsPolicyKey,
  3431  		},
  3432  		AdminsPolicyKey: {
  3433  			Type:      ImplicitMetaPolicyType,
  3434  			Rule:      "MAJORITY Admins",
  3435  			ModPolicy: AdminsPolicyKey,
  3436  		},
  3437  		BlockValidationPolicyKey: {
  3438  			Type:      ImplicitMetaPolicyType,
  3439  			Rule:      "ANY Writers",
  3440  			ModPolicy: AdminsPolicyKey,
  3441  		},
  3442  		"TestPolicy_Add1": {
  3443  			Type:      ImplicitMetaPolicyType,
  3444  			Rule:      "MAJORITY Endorsement",
  3445  			ModPolicy: AdminsPolicyKey,
  3446  		},
  3447  		"TestPolicy_Add2": {
  3448  			Type:      ImplicitMetaPolicyType,
  3449  			Rule:      "MAJORITY Endorsement",
  3450  			ModPolicy: AdminsPolicyKey,
  3451  		},
  3452  	}
  3453  
  3454  	err = c.Orderer().SetPolicies(newPolices)
  3455  	gt.Expect(err).NotTo(HaveOccurred())
  3456  
  3457  	updatedPolicies, err := c.Orderer().Policies()
  3458  	gt.Expect(err).NotTo(HaveOccurred())
  3459  	gt.Expect(updatedPolicies).To(Equal(newPolices))
  3460  
  3461  	originalPolicies := c.original.ChannelGroup.Groups[OrdererGroupKey].Policies
  3462  	gt.Expect(originalPolicies).To(Equal(ordererGroup.Policies))
  3463  }
  3464  
  3465  func TestSetOrdererPoliciesFailures(t *testing.T) {
  3466  	t.Parallel()
  3467  
  3468  	gt := NewGomegaWithT(t)
  3469  
  3470  	baseOrdererConf, _ := baseSoloOrderer(t)
  3471  
  3472  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3473  	gt.Expect(err).NotTo(HaveOccurred())
  3474  
  3475  	config := &cb.Config{
  3476  		ChannelGroup: &cb.ConfigGroup{
  3477  			Groups: map[string]*cb.ConfigGroup{
  3478  				"Orderer": ordererGroup,
  3479  			},
  3480  		},
  3481  	}
  3482  
  3483  	c := New(config)
  3484  
  3485  	newPolices := map[string]Policy{
  3486  		ReadersPolicyKey: {
  3487  			Type: ImplicitMetaPolicyType,
  3488  			Rule: "ANY Readers",
  3489  		},
  3490  		WritersPolicyKey: {
  3491  			Type: ImplicitMetaPolicyType,
  3492  			Rule: "ANY Writers",
  3493  		},
  3494  		AdminsPolicyKey: {
  3495  			Type: ImplicitMetaPolicyType,
  3496  			Rule: "MAJORITY Admins",
  3497  		},
  3498  		BlockValidationPolicyKey: {
  3499  			Type: ImplicitMetaPolicyType,
  3500  			Rule: "ANY Writers",
  3501  		},
  3502  		"TestPolicy": {},
  3503  	}
  3504  
  3505  	err = c.Orderer().SetPolicies(newPolices)
  3506  	gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: "))
  3507  }
  3508  
  3509  func TestSetOrdererPoliciesWithoutBlockValidationPolicyFailures(t *testing.T) {
  3510  	t.Parallel()
  3511  
  3512  	gt := NewGomegaWithT(t)
  3513  
  3514  	baseOrdererConf, _ := baseSoloOrderer(t)
  3515  
  3516  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3517  	gt.Expect(err).NotTo(HaveOccurred())
  3518  
  3519  	config := &cb.Config{
  3520  		ChannelGroup: &cb.ConfigGroup{
  3521  			Groups: map[string]*cb.ConfigGroup{
  3522  				"Orderer": ordererGroup,
  3523  			},
  3524  		},
  3525  	}
  3526  
  3527  	c := New(config)
  3528  
  3529  	newPolices := map[string]Policy{
  3530  		ReadersPolicyKey: {
  3531  			Type: ImplicitMetaPolicyType,
  3532  			Rule: "ANY Readers",
  3533  		},
  3534  		WritersPolicyKey: {
  3535  			Type: ImplicitMetaPolicyType,
  3536  			Rule: "ANY Writers",
  3537  		},
  3538  		AdminsPolicyKey: {
  3539  			Type: ImplicitMetaPolicyType,
  3540  			Rule: "MAJORITY Admins",
  3541  		},
  3542  	}
  3543  
  3544  	err = c.Orderer().SetPolicies(newPolices)
  3545  	gt.Expect(err).To(MatchError("BlockValidation policy must be defined"))
  3546  }
  3547  
  3548  func TestRemoveOrdererPolicy(t *testing.T) {
  3549  	t.Parallel()
  3550  
  3551  	gt := NewGomegaWithT(t)
  3552  
  3553  	baseOrdererConf, _ := baseSoloOrderer(t)
  3554  	baseOrdererConf.Policies["TestPolicy"] = baseOrdererConf.Policies[AdminsPolicyKey]
  3555  
  3556  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3557  	gt.Expect(err).NotTo(HaveOccurred())
  3558  
  3559  	config := &cb.Config{
  3560  		ChannelGroup: &cb.ConfigGroup{
  3561  			Groups: map[string]*cb.ConfigGroup{
  3562  				"Orderer": ordererGroup,
  3563  			},
  3564  		},
  3565  	}
  3566  
  3567  	c := New(config)
  3568  
  3569  	expectedPolicies := map[string]Policy{
  3570  		ReadersPolicyKey: {
  3571  			Type:      ImplicitMetaPolicyType,
  3572  			Rule:      "ANY Readers",
  3573  			ModPolicy: AdminsPolicyKey,
  3574  		},
  3575  		WritersPolicyKey: {
  3576  			Type:      ImplicitMetaPolicyType,
  3577  			Rule:      "ANY Writers",
  3578  			ModPolicy: AdminsPolicyKey,
  3579  		},
  3580  		AdminsPolicyKey: {
  3581  			Type:      ImplicitMetaPolicyType,
  3582  			Rule:      "MAJORITY Admins",
  3583  			ModPolicy: AdminsPolicyKey,
  3584  		},
  3585  		BlockValidationPolicyKey: {
  3586  			Type:      ImplicitMetaPolicyType,
  3587  			Rule:      "ANY Writers",
  3588  			ModPolicy: AdminsPolicyKey,
  3589  		},
  3590  	}
  3591  
  3592  	err = c.Orderer().RemovePolicy("TestPolicy")
  3593  	gt.Expect(err).NotTo(HaveOccurred())
  3594  
  3595  	updatedPolicies, err := c.Orderer().Policies()
  3596  	gt.Expect(err).NotTo(HaveOccurred())
  3597  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  3598  }
  3599  
  3600  func TestRemoveOrdererPolicyFailures(t *testing.T) {
  3601  	t.Parallel()
  3602  
  3603  	gt := NewGomegaWithT(t)
  3604  
  3605  	baseOrdererConf, _ := baseSoloOrderer(t)
  3606  	baseOrdererConf.Policies["TestPolicy"] = baseOrdererConf.Policies[AdminsPolicyKey]
  3607  
  3608  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3609  	gt.Expect(err).NotTo(HaveOccurred())
  3610  
  3611  	config := &cb.Config{
  3612  		ChannelGroup: &cb.ConfigGroup{
  3613  			Groups: map[string]*cb.ConfigGroup{
  3614  				OrdererGroupKey: ordererGroup,
  3615  			},
  3616  		},
  3617  	}
  3618  
  3619  	c := New(config)
  3620  
  3621  	tests := []struct {
  3622  		testName      string
  3623  		ordererGrpMod func(cb.ConfigGroup) *cb.ConfigGroup
  3624  		policyName    string
  3625  		expectedErr   string
  3626  	}{
  3627  		{
  3628  			testName: "when removing blockvalidation policy",
  3629  			ordererGrpMod: func(og cb.ConfigGroup) *cb.ConfigGroup {
  3630  				return &og
  3631  			},
  3632  			policyName:  BlockValidationPolicyKey,
  3633  			expectedErr: "BlockValidation policy must be defined",
  3634  		},
  3635  	}
  3636  
  3637  	for _, tt := range tests {
  3638  		tt := tt
  3639  		t.Run(tt.testName, func(t *testing.T) {
  3640  			gt := NewGomegaWithT(t)
  3641  
  3642  			ordererGroup := tt.ordererGrpMod(*ordererGroup)
  3643  			if ordererGroup == nil {
  3644  				delete(config.ChannelGroup.Groups, OrdererGroupKey)
  3645  			} else {
  3646  				config.ChannelGroup.Groups[OrdererGroupKey] = ordererGroup
  3647  			}
  3648  
  3649  			err = c.Orderer().RemovePolicy(tt.policyName)
  3650  			gt.Expect(err).To(MatchError(tt.expectedErr))
  3651  		})
  3652  	}
  3653  }
  3654  
  3655  func TestSetOrdererOrgModPolicy(t *testing.T) {
  3656  	t.Parallel()
  3657  
  3658  	gt := NewGomegaWithT(t)
  3659  
  3660  	baseOrdererConf, _ := baseSoloOrderer(t)
  3661  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3662  	gt.Expect(err).NotTo(HaveOccurred())
  3663  
  3664  	config := &cb.Config{
  3665  		ChannelGroup: &cb.ConfigGroup{
  3666  			Groups: map[string]*cb.ConfigGroup{
  3667  				"Orderer": ordererGroup,
  3668  			},
  3669  		},
  3670  	}
  3671  
  3672  	c := New(config)
  3673  
  3674  	ordererOrg := c.Orderer().Organization("OrdererOrg")
  3675  	err = ordererOrg.SetModPolicy("TestModPolicy")
  3676  	gt.Expect(err).NotTo(HaveOccurred())
  3677  
  3678  	updatedModPolicy := ordererOrg.orgGroup.GetModPolicy()
  3679  	gt.Expect(updatedModPolicy).To(Equal("TestModPolicy"))
  3680  }
  3681  
  3682  func TestSetOrdererOrgModPolicyFailures(t *testing.T) {
  3683  	t.Parallel()
  3684  
  3685  	gt := NewGomegaWithT(t)
  3686  
  3687  	baseOrdererConf, _ := baseSoloOrderer(t)
  3688  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3689  	gt.Expect(err).NotTo(HaveOccurred())
  3690  
  3691  	config := &cb.Config{
  3692  		ChannelGroup: &cb.ConfigGroup{
  3693  			Groups: map[string]*cb.ConfigGroup{
  3694  				"Orderer": ordererGroup,
  3695  			},
  3696  		},
  3697  	}
  3698  
  3699  	c := New(config)
  3700  
  3701  	err = c.Orderer().Organization("OrdererOrg").SetModPolicy("")
  3702  	gt.Expect(err).To(MatchError("non empty mod policy is required"))
  3703  }
  3704  
  3705  func TestSetOrdererOrgPolicy(t *testing.T) {
  3706  	t.Parallel()
  3707  
  3708  	gt := NewGomegaWithT(t)
  3709  
  3710  	baseOrdererConf, _ := baseSoloOrderer(t)
  3711  
  3712  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3713  	gt.Expect(err).NotTo(HaveOccurred())
  3714  
  3715  	config := &cb.Config{
  3716  		ChannelGroup: &cb.ConfigGroup{
  3717  			Groups: map[string]*cb.ConfigGroup{
  3718  				"Orderer": ordererGroup,
  3719  			},
  3720  		},
  3721  	}
  3722  
  3723  	c := New(config)
  3724  
  3725  	expectedPolicies := map[string]Policy{
  3726  		ReadersPolicyKey: {
  3727  			Type:      ImplicitMetaPolicyType,
  3728  			Rule:      "ANY Readers",
  3729  			ModPolicy: AdminsPolicyKey,
  3730  		},
  3731  		WritersPolicyKey: {
  3732  			Type:      ImplicitMetaPolicyType,
  3733  			Rule:      "ANY Writers",
  3734  			ModPolicy: AdminsPolicyKey,
  3735  		},
  3736  		AdminsPolicyKey: {
  3737  			Type:      ImplicitMetaPolicyType,
  3738  			Rule:      "MAJORITY Admins",
  3739  			ModPolicy: AdminsPolicyKey,
  3740  		},
  3741  		EndorsementPolicyKey: {
  3742  			Type:      ImplicitMetaPolicyType,
  3743  			Rule:      "MAJORITY Endorsement",
  3744  			ModPolicy: AdminsPolicyKey,
  3745  		},
  3746  		"TestPolicy": {
  3747  			Type:      ImplicitMetaPolicyType,
  3748  			Rule:      "ANY Endorsement",
  3749  			ModPolicy: AdminsPolicyKey,
  3750  		},
  3751  	}
  3752  
  3753  	ordererOrg := c.Orderer().Organization("OrdererOrg")
  3754  	err = ordererOrg.SetPolicy("TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Endorsement"})
  3755  	gt.Expect(err).NotTo(HaveOccurred())
  3756  
  3757  	updatedPolicies, err := ordererOrg.Policies()
  3758  	gt.Expect(err).NotTo(HaveOccurred())
  3759  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  3760  }
  3761  
  3762  func TestSetOrdererOrgPolicyFailures(t *testing.T) {
  3763  	t.Parallel()
  3764  
  3765  	gt := NewGomegaWithT(t)
  3766  
  3767  	baseOrdererConf, _ := baseSoloOrderer(t)
  3768  
  3769  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3770  	gt.Expect(err).NotTo(HaveOccurred())
  3771  
  3772  	config := &cb.Config{
  3773  		ChannelGroup: &cb.ConfigGroup{
  3774  			Groups: map[string]*cb.ConfigGroup{
  3775  				"Orderer": ordererGroup,
  3776  			},
  3777  		},
  3778  	}
  3779  
  3780  	c := New(config)
  3781  
  3782  	err = c.Orderer().Organization("OrdererOrg").SetPolicy("TestPolicy", Policy{})
  3783  	gt.Expect(err).To(MatchError("unknown policy type: "))
  3784  }
  3785  
  3786  func TestSetOrdererOrgPolicies(t *testing.T) {
  3787  	t.Parallel()
  3788  
  3789  	gt := NewGomegaWithT(t)
  3790  
  3791  	baseOrdererConf, _ := baseSoloOrderer(t)
  3792  	baseOrdererConf.Organizations[0].Policies["TestPolicy_Remove"] = baseOrdererConf.Organizations[0].Policies[ReadersPolicyKey]
  3793  
  3794  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3795  	gt.Expect(err).NotTo(HaveOccurred())
  3796  
  3797  	config := &cb.Config{
  3798  		ChannelGroup: &cb.ConfigGroup{
  3799  			Groups: map[string]*cb.ConfigGroup{
  3800  				"Orderer": ordererGroup,
  3801  			},
  3802  		},
  3803  	}
  3804  
  3805  	c := New(config)
  3806  
  3807  	newPolicies := map[string]Policy{
  3808  		ReadersPolicyKey: {
  3809  			Type:      ImplicitMetaPolicyType,
  3810  			Rule:      "ANY Readers",
  3811  			ModPolicy: AdminsPolicyKey,
  3812  		},
  3813  		WritersPolicyKey: {
  3814  			Type:      ImplicitMetaPolicyType,
  3815  			Rule:      "ANY Writers",
  3816  			ModPolicy: AdminsPolicyKey,
  3817  		},
  3818  		AdminsPolicyKey: {
  3819  			Type:      ImplicitMetaPolicyType,
  3820  			Rule:      "MAJORITY Admins",
  3821  			ModPolicy: AdminsPolicyKey,
  3822  		},
  3823  		EndorsementPolicyKey: {
  3824  			Type:      ImplicitMetaPolicyType,
  3825  			Rule:      "MAJORITY Endorsement",
  3826  			ModPolicy: AdminsPolicyKey,
  3827  		},
  3828  		"TestPolicy_Add1": {
  3829  			Type:      ImplicitMetaPolicyType,
  3830  			Rule:      "ANY Endorsement",
  3831  			ModPolicy: AdminsPolicyKey,
  3832  		},
  3833  		"TestPolicy_Add2": {
  3834  			Type:      ImplicitMetaPolicyType,
  3835  			Rule:      "ANY Endorsement",
  3836  			ModPolicy: AdminsPolicyKey,
  3837  		},
  3838  	}
  3839  
  3840  	ordererOrg := c.Orderer().Organization("OrdererOrg")
  3841  	err = ordererOrg.SetPolicies(newPolicies)
  3842  	gt.Expect(err).NotTo(HaveOccurred())
  3843  
  3844  	updatedPolicies, err := ordererOrg.Policies()
  3845  	gt.Expect(err).NotTo(HaveOccurred())
  3846  	gt.Expect(updatedPolicies).To(Equal(newPolicies))
  3847  
  3848  	originalPolicies := c.original.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies
  3849  	gt.Expect(originalPolicies).To(Equal(ordererGroup.Groups["OrdererOrg"].Policies))
  3850  }
  3851  
  3852  func TestSetOrdererOrgPoliciesFailures(t *testing.T) {
  3853  	t.Parallel()
  3854  
  3855  	gt := NewGomegaWithT(t)
  3856  
  3857  	baseOrdererConf, _ := baseSoloOrderer(t)
  3858  
  3859  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3860  	gt.Expect(err).NotTo(HaveOccurred())
  3861  
  3862  	config := &cb.Config{
  3863  		ChannelGroup: &cb.ConfigGroup{
  3864  			Groups: map[string]*cb.ConfigGroup{
  3865  				"Orderer": ordererGroup,
  3866  			},
  3867  		},
  3868  	}
  3869  
  3870  	c := New(config)
  3871  
  3872  	newPolicies := map[string]Policy{
  3873  		ReadersPolicyKey: {
  3874  			Type: ImplicitMetaPolicyType,
  3875  			Rule: "ANY Readers",
  3876  		},
  3877  		WritersPolicyKey: {
  3878  			Type: ImplicitMetaPolicyType,
  3879  			Rule: "ANY Writers",
  3880  		},
  3881  		AdminsPolicyKey: {
  3882  			Type: ImplicitMetaPolicyType,
  3883  			Rule: "MAJORITY Admins",
  3884  		},
  3885  		EndorsementPolicyKey: {
  3886  			Type: ImplicitMetaPolicyType,
  3887  			Rule: "MAJORITY Endorsement",
  3888  		},
  3889  		"TestPolicy": {},
  3890  	}
  3891  
  3892  	err = c.Orderer().Organization("OrdererOrg").SetPolicies(newPolicies)
  3893  	gt.Expect(err).To(MatchError("unknown policy type: "))
  3894  }
  3895  
  3896  func TestRemoveOrdererOrgPolicy(t *testing.T) {
  3897  	t.Parallel()
  3898  
  3899  	gt := NewGomegaWithT(t)
  3900  
  3901  	baseOrdererConf, _ := baseSoloOrderer(t)
  3902  	baseOrdererConf.Organizations[0].Policies["TestPolicy"] = baseOrdererConf.Organizations[0].Policies[AdminsPolicyKey]
  3903  
  3904  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  3905  	gt.Expect(err).NotTo(HaveOccurred())
  3906  
  3907  	config := &cb.Config{
  3908  		ChannelGroup: &cb.ConfigGroup{
  3909  			Groups: map[string]*cb.ConfigGroup{
  3910  				"Orderer": ordererGroup,
  3911  			},
  3912  		},
  3913  	}
  3914  
  3915  	c := New(config)
  3916  
  3917  	expectedPolicies := map[string]Policy{
  3918  		ReadersPolicyKey: {
  3919  			Type:      ImplicitMetaPolicyType,
  3920  			Rule:      "ANY Readers",
  3921  			ModPolicy: AdminsPolicyKey,
  3922  		},
  3923  		WritersPolicyKey: {
  3924  			Type:      ImplicitMetaPolicyType,
  3925  			Rule:      "ANY Writers",
  3926  			ModPolicy: AdminsPolicyKey,
  3927  		},
  3928  		AdminsPolicyKey: {
  3929  			Type:      ImplicitMetaPolicyType,
  3930  			Rule:      "MAJORITY Admins",
  3931  			ModPolicy: AdminsPolicyKey,
  3932  		},
  3933  		EndorsementPolicyKey: {
  3934  			Type:      ImplicitMetaPolicyType,
  3935  			Rule:      "MAJORITY Endorsement",
  3936  			ModPolicy: AdminsPolicyKey,
  3937  		},
  3938  	}
  3939  
  3940  	err = c.Orderer().Organization("OrdererOrg").RemovePolicy("TestPolicy")
  3941  	gt.Expect(err).NotTo(HaveOccurred())
  3942  
  3943  	updatedPolicies, err := c.Orderer().Organization("OrdererOrg").Policies()
  3944  	gt.Expect(err).NotTo(HaveOccurred())
  3945  	gt.Expect(updatedPolicies).To(Equal(expectedPolicies))
  3946  }
  3947  
  3948  func TestOrdererMSP(t *testing.T) {
  3949  	t.Parallel()
  3950  
  3951  	gt := NewGomegaWithT(t)
  3952  
  3953  	soloOrderer, _ := baseSoloOrderer(t)
  3954  	expectedMSP := soloOrderer.Organizations[0].MSP
  3955  
  3956  	ordererGroup, err := newOrdererGroup(soloOrderer)
  3957  	gt.Expect(err).NotTo(HaveOccurred())
  3958  
  3959  	config := &cb.Config{
  3960  		ChannelGroup: &cb.ConfigGroup{
  3961  			Groups: map[string]*cb.ConfigGroup{
  3962  				OrdererGroupKey: ordererGroup,
  3963  			},
  3964  		},
  3965  	}
  3966  
  3967  	c := New(config)
  3968  
  3969  	msp, err := c.Orderer().Organization("OrdererOrg").MSP().Configuration()
  3970  	gt.Expect(err).NotTo(HaveOccurred())
  3971  	gt.Expect(msp).To(Equal(expectedMSP))
  3972  }
  3973  
  3974  func TestUpdateOrdererMSP(t *testing.T) {
  3975  	t.Parallel()
  3976  	gt := NewGomegaWithT(t)
  3977  
  3978  	channelGroup, privKeys, err := baseOrdererChannelGroup(t, orderer.ConsensusTypeSolo)
  3979  	gt.Expect(err).NotTo(HaveOccurred())
  3980  
  3981  	config := &cb.Config{
  3982  		ChannelGroup: channelGroup,
  3983  	}
  3984  	c := New(config)
  3985  
  3986  	ordererMSP, err := c.Orderer().Organization("OrdererOrg").MSP().Configuration()
  3987  	gt.Expect(err).NotTo(HaveOccurred())
  3988  
  3989  	ordererCertBase64, ordererCRLBase64 := certCRLBase64(t, ordererMSP)
  3990  
  3991  	newRootCert, newRootPrivKey := generateCACertAndPrivateKey(t, "anotherca-org1.example.com")
  3992  	newRootCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(newRootCert))
  3993  	ordererMSP.RootCerts = append(ordererMSP.RootCerts, newRootCert)
  3994  
  3995  	newIntermediateCert, _ := generateIntermediateCACertAndPrivateKey(t, "anotherca-org1.example.com", newRootCert, newRootPrivKey)
  3996  	newIntermediateCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(newIntermediateCert))
  3997  	ordererMSP.IntermediateCerts = append(ordererMSP.IntermediateCerts, newIntermediateCert)
  3998  
  3999  	cert := ordererMSP.RootCerts[0]
  4000  	certToRevoke, _ := generateCertAndPrivateKeyFromCACert(t, "org1.example.com", cert, privKeys[0])
  4001  	signingIdentity := &SigningIdentity{
  4002  		Certificate: cert,
  4003  		PrivateKey:  privKeys[0],
  4004  		MSPID:       "MSPID",
  4005  	}
  4006  	newCRL, err := ordererMSP.CreateMSPCRL(signingIdentity, certToRevoke)
  4007  	gt.Expect(err).NotTo(HaveOccurred())
  4008  	pemNewCRL, err := pemEncodeCRL(newCRL)
  4009  	gt.Expect(err).NotTo(HaveOccurred())
  4010  	newCRLBase64 := base64.StdEncoding.EncodeToString(pemNewCRL)
  4011  	ordererMSP.RevocationList = append(ordererMSP.RevocationList, newCRL)
  4012  
  4013  	err = c.Orderer().Organization("OrdererOrg").SetMSP(ordererMSP)
  4014  	gt.Expect(err).NotTo(HaveOccurred())
  4015  
  4016  	expectedConfigJSON := fmt.Sprintf(`
  4017  {
  4018  	"channel_group": {
  4019  		"groups": {
  4020  			"Orderer": {
  4021  				"groups": {
  4022  					"OrdererOrg": {
  4023  						"groups": {},
  4024  						"mod_policy": "Admins",
  4025  						"policies": {
  4026  							"Admins": {
  4027  								"mod_policy": "Admins",
  4028  								"policy": {
  4029  									"type": 3,
  4030  									"value": {
  4031  										"rule": "MAJORITY",
  4032  										"sub_policy": "Admins"
  4033  									}
  4034  								},
  4035  								"version": "0"
  4036  							},
  4037  							"Endorsement": {
  4038  								"mod_policy": "Admins",
  4039  								"policy": {
  4040  									"type": 3,
  4041  									"value": {
  4042  										"rule": "MAJORITY",
  4043  										"sub_policy": "Endorsement"
  4044  									}
  4045  								},
  4046  								"version": "0"
  4047  							},
  4048  							"Readers": {
  4049  								"mod_policy": "Admins",
  4050  								"policy": {
  4051  									"type": 3,
  4052  									"value": {
  4053  										"rule": "ANY",
  4054  										"sub_policy": "Readers"
  4055  									}
  4056  								},
  4057  								"version": "0"
  4058  							},
  4059  							"Writers": {
  4060  								"mod_policy": "Admins",
  4061  								"policy": {
  4062  									"type": 3,
  4063  									"value": {
  4064  										"rule": "ANY",
  4065  										"sub_policy": "Writers"
  4066  									}
  4067  								},
  4068  								"version": "0"
  4069  							}
  4070  						},
  4071  						"values": {
  4072  							"Endpoints": {
  4073  								"mod_policy": "Admins",
  4074  								"value": {
  4075  									"addresses": [
  4076  										"localhost:123"
  4077  									]
  4078  								},
  4079  								"version": "0"
  4080  							},
  4081  							"MSP": {
  4082  								"mod_policy": "Admins",
  4083  								"value": {
  4084  									"config": {
  4085  										"admins": [
  4086  											"%[1]s"
  4087  										],
  4088  										"crypto_config": {
  4089  											"identity_identifier_hash_function": "SHA256",
  4090  											"signature_hash_family": "SHA3"
  4091  										},
  4092  										"fabric_node_ous": {
  4093  											"admin_ou_identifier": {
  4094  												"certificate": "%[1]s",
  4095  												"organizational_unit_identifier": "OUID"
  4096  											},
  4097  											"client_ou_identifier": {
  4098  												"certificate": "%[1]s",
  4099  												"organizational_unit_identifier": "OUID"
  4100  											},
  4101  											"enable": false,
  4102  											"orderer_ou_identifier": {
  4103  												"certificate": "%[1]s",
  4104  												"organizational_unit_identifier": "OUID"
  4105  											},
  4106  											"peer_ou_identifier": {
  4107  												"certificate": "%[1]s",
  4108  												"organizational_unit_identifier": "OUID"
  4109  											}
  4110  										},
  4111  										"intermediate_certs": [
  4112  											"%[1]s",
  4113  											"%[2]s"
  4114  										],
  4115  										"name": "MSPID",
  4116  										"organizational_unit_identifiers": [
  4117  											{
  4118  												"certificate": "%[1]s",
  4119  												"organizational_unit_identifier": "OUID"
  4120  											}
  4121  										],
  4122  										"revocation_list": [
  4123  											"%[3]s",
  4124  											"%[4]s"
  4125  										],
  4126  										"root_certs": [
  4127  											"%[1]s",
  4128  											"%[5]s"
  4129  										],
  4130  										"signing_identity": null,
  4131  										"tls_intermediate_certs": [
  4132  											"%[1]s"
  4133  										],
  4134  										"tls_root_certs": [
  4135  											"%[1]s"
  4136  										]
  4137  									},
  4138  									"type": 0
  4139  								},
  4140  								"version": "0"
  4141  							}
  4142  						},
  4143  						"version": "0"
  4144  					}
  4145  				},
  4146  				"mod_policy": "Admins",
  4147  				"policies": {
  4148  					"Admins": {
  4149  						"mod_policy": "Admins",
  4150  						"policy": {
  4151  							"type": 3,
  4152  							"value": {
  4153  								"rule": "MAJORITY",
  4154  								"sub_policy": "Admins"
  4155  							}
  4156  						},
  4157  						"version": "0"
  4158  					},
  4159  					"BlockValidation": {
  4160  						"mod_policy": "Admins",
  4161  						"policy": {
  4162  							"type": 3,
  4163  							"value": {
  4164  								"rule": "ANY",
  4165  								"sub_policy": "Writers"
  4166  							}
  4167  						},
  4168  						"version": "0"
  4169  					},
  4170  					"Readers": {
  4171  						"mod_policy": "Admins",
  4172  						"policy": {
  4173  							"type": 3,
  4174  							"value": {
  4175  								"rule": "ANY",
  4176  								"sub_policy": "Readers"
  4177  							}
  4178  						},
  4179  						"version": "0"
  4180  					},
  4181  					"Writers": {
  4182  						"mod_policy": "Admins",
  4183  						"policy": {
  4184  							"type": 3,
  4185  							"value": {
  4186  								"rule": "ANY",
  4187  								"sub_policy": "Writers"
  4188  							}
  4189  						},
  4190  						"version": "0"
  4191  					}
  4192  				},
  4193  				"values": {
  4194  					"BatchSize": {
  4195  						"mod_policy": "Admins",
  4196  						"value": {
  4197  							"absolute_max_bytes": 100,
  4198  							"max_message_count": 100,
  4199  							"preferred_max_bytes": 100
  4200  						},
  4201  						"version": "0"
  4202  					},
  4203  					"BatchTimeout": {
  4204  						"mod_policy": "Admins",
  4205  						"value": {
  4206  							"timeout": "0s"
  4207  						},
  4208  						"version": "0"
  4209  					},
  4210  					"Capabilities": {
  4211  						"mod_policy": "Admins",
  4212  						"value": {
  4213  							"capabilities": {
  4214  								"V1_3": {}
  4215  							}
  4216  						},
  4217  						"version": "0"
  4218  					},
  4219  					"ChannelRestrictions": {
  4220  						"mod_policy": "Admins",
  4221  						"value": null,
  4222  						"version": "0"
  4223  					},
  4224  					"ConsensusType": {
  4225  						"mod_policy": "Admins",
  4226  						"value": {
  4227  							"metadata": null,
  4228  							"state": "STATE_NORMAL",
  4229  							"type": "solo"
  4230  						},
  4231  						"version": "0"
  4232  					}
  4233  				},
  4234  				"version": "0"
  4235  			}
  4236  		},
  4237  		"mod_policy": "",
  4238  		"policies": {},
  4239  		"values": {},
  4240  		"version": "0"
  4241  	},
  4242  	"sequence": "0"
  4243  }`, ordererCertBase64, newIntermediateCertBase64, ordererCRLBase64, newCRLBase64, newRootCertBase64)
  4244  
  4245  	buf := bytes.Buffer{}
  4246  	err = protolator.DeepMarshalJSON(&buf, c.updated)
  4247  	gt.Expect(err).NotTo(HaveOccurred())
  4248  
  4249  	gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON))
  4250  }
  4251  
  4252  func TestUpdateOrdererMSPFailure(t *testing.T) {
  4253  	t.Parallel()
  4254  
  4255  	tests := []struct {
  4256  		spec        string
  4257  		mspMod      func(MSP) MSP
  4258  		orgName     string
  4259  		expectedErr string
  4260  	}{
  4261  		{
  4262  			spec: "updating msp name",
  4263  			mspMod: func(msp MSP) MSP {
  4264  				msp.Name = "thiscantbegood"
  4265  				return msp
  4266  			},
  4267  			orgName:     "OrdererOrg",
  4268  			expectedErr: "MSP name cannot be changed",
  4269  		},
  4270  		{
  4271  			spec: "invalid root ca cert keyusage",
  4272  			mspMod: func(msp MSP) MSP {
  4273  				msp.RootCerts = []*x509.Certificate{
  4274  					{
  4275  						SerialNumber: big.NewInt(7),
  4276  						KeyUsage:     x509.KeyUsageKeyAgreement,
  4277  					},
  4278  				}
  4279  				return msp
  4280  			},
  4281  			orgName:     "OrdererOrg",
  4282  			expectedErr: "invalid root cert: KeyUsage must be x509.KeyUsageCertSign. serial number: 7",
  4283  		},
  4284  	}
  4285  
  4286  	for _, tc := range tests {
  4287  		tc := tc
  4288  		t.Run(tc.spec, func(t *testing.T) {
  4289  			t.Parallel()
  4290  			gt := NewGomegaWithT(t)
  4291  
  4292  			channelGroup, _, err := baseOrdererChannelGroup(t, orderer.ConsensusTypeSolo)
  4293  			gt.Expect(err).NotTo(HaveOccurred())
  4294  
  4295  			config := &cb.Config{
  4296  				ChannelGroup: channelGroup,
  4297  			}
  4298  			c := New(config)
  4299  
  4300  			ordererMSP, err := c.Orderer().Organization("OrdererOrg").MSP().Configuration()
  4301  			gt.Expect(err).NotTo(HaveOccurred())
  4302  
  4303  			ordererMSP = tc.mspMod(ordererMSP)
  4304  			err = c.Orderer().Organization(tc.orgName).SetMSP(ordererMSP)
  4305  			gt.Expect(err).To(MatchError(tc.expectedErr))
  4306  		})
  4307  	}
  4308  }
  4309  
  4310  func TestRemoveLegacyKafkaBrokers(t *testing.T) {
  4311  	t.Parallel()
  4312  
  4313  	gt := NewGomegaWithT(t)
  4314  
  4315  	channelGroup, _, err := baseOrdererChannelGroup(t, orderer.ConsensusTypeKafka)
  4316  	gt.Expect(err).NotTo(HaveOccurred())
  4317  
  4318  	config := &cb.Config{
  4319  		ChannelGroup: channelGroup,
  4320  	}
  4321  
  4322  	c := New(config)
  4323  
  4324  	c.Orderer().RemoveLegacyKafkaBrokers()
  4325  
  4326  	expectedConfigValue := map[string]*cb.ConfigValue{
  4327  		orderer.ConsensusTypeKey: {
  4328  			ModPolicy: AdminsPolicyKey,
  4329  			Value: marshalOrPanic(&ob.ConsensusType{
  4330  				Type: orderer.ConsensusTypeKafka,
  4331  			}),
  4332  		},
  4333  		orderer.ChannelRestrictionsKey: {
  4334  			ModPolicy: AdminsPolicyKey,
  4335  		},
  4336  		CapabilitiesKey: {
  4337  			ModPolicy: AdminsPolicyKey,
  4338  			Value: marshalOrPanic(&cb.Capabilities{
  4339  				Capabilities: map[string]*cb.Capability{
  4340  					"V1_3": {},
  4341  				},
  4342  			}),
  4343  		},
  4344  		orderer.BatchTimeoutKey: {
  4345  			ModPolicy: AdminsPolicyKey,
  4346  			Value: marshalOrPanic(&ob.BatchTimeout{
  4347  				Timeout: "0s",
  4348  			}),
  4349  		},
  4350  		orderer.BatchSizeKey: {
  4351  			ModPolicy: AdminsPolicyKey,
  4352  			Value: marshalOrPanic(&ob.BatchSize{
  4353  				MaxMessageCount:   100,
  4354  				AbsoluteMaxBytes:  100,
  4355  				PreferredMaxBytes: 100,
  4356  			}),
  4357  		},
  4358  	}
  4359  
  4360  	gt.Expect(c.Orderer().ordererGroup.Values).To(Equal(expectedConfigValue))
  4361  }
  4362  
  4363  func TestSetBatchSizeValues(t *testing.T) {
  4364  	t.Parallel()
  4365  
  4366  	gt := NewGomegaWithT(t)
  4367  
  4368  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  4369  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4370  	gt.Expect(err).NotTo(HaveOccurred())
  4371  
  4372  	config := &cb.Config{
  4373  		ChannelGroup: &cb.ConfigGroup{
  4374  			Groups: map[string]*cb.ConfigGroup{
  4375  				OrdererGroupKey: ordererGroup,
  4376  			},
  4377  		},
  4378  	}
  4379  
  4380  	c := New(config)
  4381  
  4382  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  4383  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  4384  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  4385  
  4386  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  4387  	expectedConfigGroupJSON := fmt.Sprintf(`{
  4388  	"groups": {
  4389  		"OrdererOrg": {
  4390  			"groups": {},
  4391  			"mod_policy": "Admins",
  4392  			"policies": {
  4393  				"Admins": {
  4394  					"mod_policy": "Admins",
  4395  					"policy": {
  4396  						"type": 3,
  4397  						"value": {
  4398  							"rule": "MAJORITY",
  4399  							"sub_policy": "Admins"
  4400  						}
  4401  					},
  4402  					"version": "0"
  4403  				},
  4404  				"Endorsement": {
  4405  					"mod_policy": "Admins",
  4406  					"policy": {
  4407  						"type": 3,
  4408  						"value": {
  4409  							"rule": "MAJORITY",
  4410  							"sub_policy": "Endorsement"
  4411  						}
  4412  					},
  4413  					"version": "0"
  4414  				},
  4415  				"Readers": {
  4416  					"mod_policy": "Admins",
  4417  					"policy": {
  4418  						"type": 3,
  4419  						"value": {
  4420  							"rule": "ANY",
  4421  							"sub_policy": "Readers"
  4422  						}
  4423  					},
  4424  					"version": "0"
  4425  				},
  4426  				"Writers": {
  4427  					"mod_policy": "Admins",
  4428  					"policy": {
  4429  						"type": 3,
  4430  						"value": {
  4431  							"rule": "ANY",
  4432  							"sub_policy": "Writers"
  4433  						}
  4434  					},
  4435  					"version": "0"
  4436  				}
  4437  			},
  4438  			"values": {
  4439  				"Endpoints": {
  4440  					"mod_policy": "Admins",
  4441  					"value": {
  4442  						"addresses": [
  4443  							"localhost:123"
  4444  						]
  4445  					},
  4446  					"version": "0"
  4447  				},
  4448  				"MSP": {
  4449  					"mod_policy": "Admins",
  4450  					"value": {
  4451  						"config": {
  4452  							"admins": [
  4453  								"%[1]s"
  4454  							],
  4455  							"crypto_config": {
  4456  								"identity_identifier_hash_function": "SHA256",
  4457  								"signature_hash_family": "SHA3"
  4458  							},
  4459  							"fabric_node_ous": {
  4460  								"admin_ou_identifier": {
  4461  									"certificate": "%[1]s",
  4462  									"organizational_unit_identifier": "OUID"
  4463  								},
  4464  								"client_ou_identifier": {
  4465  									"certificate": "%[1]s",
  4466  									"organizational_unit_identifier": "OUID"
  4467  								},
  4468  								"enable": false,
  4469  								"orderer_ou_identifier": {
  4470  									"certificate": "%[1]s",
  4471  									"organizational_unit_identifier": "OUID"
  4472  								},
  4473  								"peer_ou_identifier": {
  4474  									"certificate": "%[1]s",
  4475  									"organizational_unit_identifier": "OUID"
  4476  								}
  4477  							},
  4478  							"intermediate_certs": [
  4479  								"%[1]s"
  4480  							],
  4481  							"name": "MSPID",
  4482  							"organizational_unit_identifiers": [
  4483  								{
  4484  									"certificate": "%[1]s",
  4485  									"organizational_unit_identifier": "OUID"
  4486  								}
  4487  							],
  4488  							"revocation_list": [
  4489  								"%[2]s"
  4490  							],
  4491  							"root_certs": [
  4492  								"%[1]s"
  4493  							],
  4494  							"signing_identity": null,
  4495  							"tls_intermediate_certs": [
  4496  								"%[1]s"
  4497  							],
  4498  							"tls_root_certs": [
  4499  								"%[1]s"
  4500  							]
  4501  						},
  4502  						"type": 0
  4503  					},
  4504  					"version": "0"
  4505  				}
  4506  			},
  4507  			"version": "0"
  4508  		}
  4509  	},
  4510  	"mod_policy": "Admins",
  4511  	"policies": {
  4512  		"Admins": {
  4513  			"mod_policy": "Admins",
  4514  			"policy": {
  4515  				"type": 3,
  4516  				"value": {
  4517  					"rule": "MAJORITY",
  4518  					"sub_policy": "Admins"
  4519  				}
  4520  			},
  4521  			"version": "0"
  4522  		},
  4523  		"BlockValidation": {
  4524  			"mod_policy": "Admins",
  4525  			"policy": {
  4526  				"type": 3,
  4527  				"value": {
  4528  					"rule": "ANY",
  4529  					"sub_policy": "Writers"
  4530  				}
  4531  			},
  4532  			"version": "0"
  4533  		},
  4534  		"Readers": {
  4535  			"mod_policy": "Admins",
  4536  			"policy": {
  4537  				"type": 3,
  4538  				"value": {
  4539  					"rule": "ANY",
  4540  					"sub_policy": "Readers"
  4541  				}
  4542  			},
  4543  			"version": "0"
  4544  		},
  4545  		"Writers": {
  4546  			"mod_policy": "Admins",
  4547  			"policy": {
  4548  				"type": 3,
  4549  				"value": {
  4550  					"rule": "ANY",
  4551  					"sub_policy": "Writers"
  4552  				}
  4553  			},
  4554  			"version": "0"
  4555  		}
  4556  	},
  4557  	"values": {
  4558  		"BatchSize": {
  4559  			"mod_policy": "Admins",
  4560  			"value": {
  4561  				"absolute_max_bytes": 300,
  4562  				"max_message_count": 200,
  4563  				"preferred_max_bytes": 500
  4564  			},
  4565  			"version": "0"
  4566  		},
  4567  		"BatchTimeout": {
  4568  			"mod_policy": "Admins",
  4569  			"value": {
  4570  				"timeout": "0s"
  4571  			},
  4572  			"version": "0"
  4573  		},
  4574  		"Capabilities": {
  4575  			"mod_policy": "Admins",
  4576  			"value": {
  4577  				"capabilities": {
  4578  					"V1_3": {}
  4579  				}
  4580  			},
  4581  			"version": "0"
  4582  		},
  4583  		"ChannelRestrictions": {
  4584  			"mod_policy": "Admins",
  4585  			"value": null,
  4586  			"version": "0"
  4587  		},
  4588  		"ConsensusType": {
  4589  			"mod_policy": "Admins",
  4590  			"value": {
  4591  				"metadata": {
  4592  					"consenters": [
  4593  						{
  4594  							"client_tls_cert": "%[3]s",
  4595  							"host": "node-1.example.com",
  4596  							"port": 7050,
  4597  							"server_tls_cert": "%[3]s"
  4598  						},
  4599  						{
  4600  							"client_tls_cert": "%[3]s",
  4601  							"host": "node-2.example.com",
  4602  							"port": 7050,
  4603  							"server_tls_cert": "%[3]s"
  4604  						},
  4605  						{
  4606  							"client_tls_cert": "%[3]s",
  4607  							"host": "node-3.example.com",
  4608  							"port": 7050,
  4609  							"server_tls_cert": "%[3]s"
  4610  						}
  4611  					],
  4612  					"options": {
  4613  						"election_tick": 0,
  4614  						"heartbeat_tick": 0,
  4615  						"max_inflight_blocks": 0,
  4616  						"snapshot_interval_size": 0,
  4617  						"tick_interval": ""
  4618  					}
  4619  				},
  4620  				"state": "STATE_NORMAL",
  4621  				"type": "etcdraft"
  4622  			},
  4623  			"version": "0"
  4624  		}
  4625  	},
  4626  	"version": "0"
  4627  }
  4628  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  4629  
  4630  	err = c.Orderer().BatchSize().SetMaxMessageCount(200)
  4631  	gt.Expect(err).NotTo(HaveOccurred())
  4632  
  4633  	err = c.Orderer().BatchSize().SetAbsoluteMaxBytes(300)
  4634  	gt.Expect(err).NotTo(HaveOccurred())
  4635  
  4636  	err = c.Orderer().BatchSize().SetPreferredMaxBytes(500)
  4637  	gt.Expect(err).NotTo(HaveOccurred())
  4638  
  4639  	buf := bytes.Buffer{}
  4640  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  4641  	gt.Expect(err).NotTo(HaveOccurred())
  4642  
  4643  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  4644  }
  4645  
  4646  func TestSetMaxMessageCountFailures(t *testing.T) {
  4647  	t.Parallel()
  4648  
  4649  	gt := NewGomegaWithT(t)
  4650  	baseOrdererConf, _ := baseSoloOrderer(t)
  4651  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4652  	gt.Expect(err).NotTo(HaveOccurred())
  4653  
  4654  	ordererGroup.Values[orderer.BatchSizeKey] = &cb.ConfigValue{Value: []byte("{")}
  4655  	config := &cb.Config{
  4656  		ChannelGroup: &cb.ConfigGroup{
  4657  			Groups: map[string]*cb.ConfigGroup{
  4658  				OrdererGroupKey: ordererGroup,
  4659  			},
  4660  		},
  4661  	}
  4662  
  4663  	c := New(config)
  4664  	err = c.Orderer().BatchSize().SetMaxMessageCount(5)
  4665  	gt.Expect(err).To(MatchError("unexpected EOF"))
  4666  }
  4667  
  4668  func TestSetAbsoluteMaxBytesFailures(t *testing.T) {
  4669  	t.Parallel()
  4670  
  4671  	gt := NewGomegaWithT(t)
  4672  
  4673  	baseOrdererConf, _ := baseSoloOrderer(t)
  4674  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4675  	gt.Expect(err).NotTo(HaveOccurred())
  4676  
  4677  	ordererGroup.Values[orderer.BatchSizeKey] = &cb.ConfigValue{Value: []byte("{")}
  4678  	config := &cb.Config{
  4679  		ChannelGroup: &cb.ConfigGroup{
  4680  			Groups: map[string]*cb.ConfigGroup{
  4681  				OrdererGroupKey: ordererGroup,
  4682  			},
  4683  		},
  4684  	}
  4685  
  4686  	c := New(config)
  4687  	err = c.Orderer().BatchSize().SetAbsoluteMaxBytes(5)
  4688  	gt.Expect(err).To(MatchError("unexpected EOF"))
  4689  }
  4690  
  4691  func TestSetPreferredMaxBytesFailures(t *testing.T) {
  4692  	t.Parallel()
  4693  
  4694  	gt := NewGomegaWithT(t)
  4695  
  4696  	baseOrdererConf, _ := baseSoloOrderer(t)
  4697  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4698  	gt.Expect(err).NotTo(HaveOccurred())
  4699  
  4700  	ordererGroup.Values[orderer.BatchSizeKey] = &cb.ConfigValue{Value: []byte("{")}
  4701  	config := &cb.Config{
  4702  		ChannelGroup: &cb.ConfigGroup{
  4703  			Groups: map[string]*cb.ConfigGroup{
  4704  				OrdererGroupKey: ordererGroup,
  4705  			},
  4706  		},
  4707  	}
  4708  
  4709  	c := New(config)
  4710  	err = c.Orderer().BatchSize().SetPreferredMaxBytes(5)
  4711  	gt.Expect(err).To(MatchError("unexpected EOF"))
  4712  }
  4713  
  4714  func TestSetBatchTimeout(t *testing.T) {
  4715  	t.Parallel()
  4716  
  4717  	gt := NewGomegaWithT(t)
  4718  
  4719  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  4720  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4721  	gt.Expect(err).NotTo(HaveOccurred())
  4722  
  4723  	config := &cb.Config{
  4724  		ChannelGroup: &cb.ConfigGroup{
  4725  			Groups: map[string]*cb.ConfigGroup{
  4726  				OrdererGroupKey: ordererGroup,
  4727  			},
  4728  		},
  4729  	}
  4730  
  4731  	c := New(config)
  4732  
  4733  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  4734  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  4735  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  4736  
  4737  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  4738  	expectedConfigGroupJSON := fmt.Sprintf(`{
  4739  	"groups": {
  4740  		"OrdererOrg": {
  4741  			"groups": {},
  4742  			"mod_policy": "Admins",
  4743  			"policies": {
  4744  				"Admins": {
  4745  					"mod_policy": "Admins",
  4746  					"policy": {
  4747  						"type": 3,
  4748  						"value": {
  4749  							"rule": "MAJORITY",
  4750  							"sub_policy": "Admins"
  4751  						}
  4752  					},
  4753  					"version": "0"
  4754  				},
  4755  				"Endorsement": {
  4756  					"mod_policy": "Admins",
  4757  					"policy": {
  4758  						"type": 3,
  4759  						"value": {
  4760  							"rule": "MAJORITY",
  4761  							"sub_policy": "Endorsement"
  4762  						}
  4763  					},
  4764  					"version": "0"
  4765  				},
  4766  				"Readers": {
  4767  					"mod_policy": "Admins",
  4768  					"policy": {
  4769  						"type": 3,
  4770  						"value": {
  4771  							"rule": "ANY",
  4772  							"sub_policy": "Readers"
  4773  						}
  4774  					},
  4775  					"version": "0"
  4776  				},
  4777  				"Writers": {
  4778  					"mod_policy": "Admins",
  4779  					"policy": {
  4780  						"type": 3,
  4781  						"value": {
  4782  							"rule": "ANY",
  4783  							"sub_policy": "Writers"
  4784  						}
  4785  					},
  4786  					"version": "0"
  4787  				}
  4788  			},
  4789  			"values": {
  4790  				"Endpoints": {
  4791  					"mod_policy": "Admins",
  4792  					"value": {
  4793  						"addresses": [
  4794  							"localhost:123"
  4795  						]
  4796  					},
  4797  					"version": "0"
  4798  				},
  4799  				"MSP": {
  4800  					"mod_policy": "Admins",
  4801  					"value": {
  4802  						"config": {
  4803  							"admins": [
  4804  								"%[1]s"
  4805  							],
  4806  							"crypto_config": {
  4807  								"identity_identifier_hash_function": "SHA256",
  4808  								"signature_hash_family": "SHA3"
  4809  							},
  4810  							"fabric_node_ous": {
  4811  								"admin_ou_identifier": {
  4812  									"certificate": "%[1]s",
  4813  									"organizational_unit_identifier": "OUID"
  4814  								},
  4815  								"client_ou_identifier": {
  4816  									"certificate": "%[1]s",
  4817  									"organizational_unit_identifier": "OUID"
  4818  								},
  4819  								"enable": false,
  4820  								"orderer_ou_identifier": {
  4821  									"certificate": "%[1]s",
  4822  									"organizational_unit_identifier": "OUID"
  4823  								},
  4824  								"peer_ou_identifier": {
  4825  									"certificate": "%[1]s",
  4826  									"organizational_unit_identifier": "OUID"
  4827  								}
  4828  							},
  4829  							"intermediate_certs": [
  4830  								"%[1]s"
  4831  							],
  4832  							"name": "MSPID",
  4833  							"organizational_unit_identifiers": [
  4834  								{
  4835  									"certificate": "%[1]s",
  4836  									"organizational_unit_identifier": "OUID"
  4837  								}
  4838  							],
  4839  							"revocation_list": [
  4840  								"%[2]s"
  4841  							],
  4842  							"root_certs": [
  4843  								"%[1]s"
  4844  							],
  4845  							"signing_identity": null,
  4846  							"tls_intermediate_certs": [
  4847  								"%[1]s"
  4848  							],
  4849  							"tls_root_certs": [
  4850  								"%[1]s"
  4851  							]
  4852  						},
  4853  						"type": 0
  4854  					},
  4855  					"version": "0"
  4856  				}
  4857  			},
  4858  			"version": "0"
  4859  		}
  4860  	},
  4861  	"mod_policy": "Admins",
  4862  	"policies": {
  4863  		"Admins": {
  4864  			"mod_policy": "Admins",
  4865  			"policy": {
  4866  				"type": 3,
  4867  				"value": {
  4868  					"rule": "MAJORITY",
  4869  					"sub_policy": "Admins"
  4870  				}
  4871  			},
  4872  			"version": "0"
  4873  		},
  4874  		"BlockValidation": {
  4875  			"mod_policy": "Admins",
  4876  			"policy": {
  4877  				"type": 3,
  4878  				"value": {
  4879  					"rule": "ANY",
  4880  					"sub_policy": "Writers"
  4881  				}
  4882  			},
  4883  			"version": "0"
  4884  		},
  4885  		"Readers": {
  4886  			"mod_policy": "Admins",
  4887  			"policy": {
  4888  				"type": 3,
  4889  				"value": {
  4890  					"rule": "ANY",
  4891  					"sub_policy": "Readers"
  4892  				}
  4893  			},
  4894  			"version": "0"
  4895  		},
  4896  		"Writers": {
  4897  			"mod_policy": "Admins",
  4898  			"policy": {
  4899  				"type": 3,
  4900  				"value": {
  4901  					"rule": "ANY",
  4902  					"sub_policy": "Writers"
  4903  				}
  4904  			},
  4905  			"version": "0"
  4906  		}
  4907  	},
  4908  	"values": {
  4909  		"BatchSize": {
  4910  			"mod_policy": "Admins",
  4911  			"value": {
  4912  				"absolute_max_bytes": 100,
  4913  				"max_message_count": 100,
  4914  				"preferred_max_bytes": 100
  4915  			},
  4916  			"version": "0"
  4917  		},
  4918  		"BatchTimeout": {
  4919  			"mod_policy": "Admins",
  4920  			"value": {
  4921  				"timeout": "20s"
  4922  			},
  4923  			"version": "0"
  4924  		},
  4925  		"Capabilities": {
  4926  			"mod_policy": "Admins",
  4927  			"value": {
  4928  				"capabilities": {
  4929  					"V1_3": {}
  4930  				}
  4931  			},
  4932  			"version": "0"
  4933  		},
  4934  		"ChannelRestrictions": {
  4935  			"mod_policy": "Admins",
  4936  			"value": null,
  4937  			"version": "0"
  4938  		},
  4939  		"ConsensusType": {
  4940  			"mod_policy": "Admins",
  4941  			"value": {
  4942  				"metadata": {
  4943  					"consenters": [
  4944  						{
  4945  							"client_tls_cert": "%[3]s",
  4946  							"host": "node-1.example.com",
  4947  							"port": 7050,
  4948  							"server_tls_cert": "%[3]s"
  4949  						},
  4950  						{
  4951  							"client_tls_cert": "%[3]s",
  4952  							"host": "node-2.example.com",
  4953  							"port": 7050,
  4954  							"server_tls_cert": "%[3]s"
  4955  						},
  4956  						{
  4957  							"client_tls_cert": "%[3]s",
  4958  							"host": "node-3.example.com",
  4959  							"port": 7050,
  4960  							"server_tls_cert": "%[3]s"
  4961  						}
  4962  					],
  4963  					"options": {
  4964  						"election_tick": 0,
  4965  						"heartbeat_tick": 0,
  4966  						"max_inflight_blocks": 0,
  4967  						"snapshot_interval_size": 0,
  4968  						"tick_interval": ""
  4969  					}
  4970  				},
  4971  				"state": "STATE_NORMAL",
  4972  				"type": "etcdraft"
  4973  			},
  4974  			"version": "0"
  4975  		}
  4976  	},
  4977  	"version": "0"
  4978  }
  4979  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  4980  
  4981  	err = c.Orderer().SetBatchTimeout(time.Second * 20)
  4982  	gt.Expect(err).NotTo(HaveOccurred())
  4983  
  4984  	buf := bytes.Buffer{}
  4985  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  4986  	gt.Expect(err).NotTo(HaveOccurred())
  4987  
  4988  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  4989  }
  4990  
  4991  func TestSetMaxChannels(t *testing.T) {
  4992  	t.Parallel()
  4993  
  4994  	gt := NewGomegaWithT(t)
  4995  
  4996  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  4997  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  4998  	gt.Expect(err).NotTo(HaveOccurred())
  4999  
  5000  	config := &cb.Config{
  5001  		ChannelGroup: &cb.ConfigGroup{
  5002  			Groups: map[string]*cb.ConfigGroup{
  5003  				OrdererGroupKey: ordererGroup,
  5004  			},
  5005  		},
  5006  	}
  5007  
  5008  	c := New(config)
  5009  
  5010  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  5011  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  5012  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  5013  
  5014  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  5015  	expectedConfigGroupJSON := fmt.Sprintf(`{
  5016  	"groups": {
  5017  		"OrdererOrg": {
  5018  			"groups": {},
  5019  			"mod_policy": "Admins",
  5020  			"policies": {
  5021  				"Admins": {
  5022  					"mod_policy": "Admins",
  5023  					"policy": {
  5024  						"type": 3,
  5025  						"value": {
  5026  							"rule": "MAJORITY",
  5027  							"sub_policy": "Admins"
  5028  						}
  5029  					},
  5030  					"version": "0"
  5031  				},
  5032  				"Endorsement": {
  5033  					"mod_policy": "Admins",
  5034  					"policy": {
  5035  						"type": 3,
  5036  						"value": {
  5037  							"rule": "MAJORITY",
  5038  							"sub_policy": "Endorsement"
  5039  						}
  5040  					},
  5041  					"version": "0"
  5042  				},
  5043  				"Readers": {
  5044  					"mod_policy": "Admins",
  5045  					"policy": {
  5046  						"type": 3,
  5047  						"value": {
  5048  							"rule": "ANY",
  5049  							"sub_policy": "Readers"
  5050  						}
  5051  					},
  5052  					"version": "0"
  5053  				},
  5054  				"Writers": {
  5055  					"mod_policy": "Admins",
  5056  					"policy": {
  5057  						"type": 3,
  5058  						"value": {
  5059  							"rule": "ANY",
  5060  							"sub_policy": "Writers"
  5061  						}
  5062  					},
  5063  					"version": "0"
  5064  				}
  5065  			},
  5066  			"values": {
  5067  				"Endpoints": {
  5068  					"mod_policy": "Admins",
  5069  					"value": {
  5070  						"addresses": [
  5071  							"localhost:123"
  5072  						]
  5073  					},
  5074  					"version": "0"
  5075  				},
  5076  				"MSP": {
  5077  					"mod_policy": "Admins",
  5078  					"value": {
  5079  						"config": {
  5080  							"admins": [
  5081  								"%[1]s"
  5082  							],
  5083  							"crypto_config": {
  5084  								"identity_identifier_hash_function": "SHA256",
  5085  								"signature_hash_family": "SHA3"
  5086  							},
  5087  							"fabric_node_ous": {
  5088  								"admin_ou_identifier": {
  5089  									"certificate": "%[1]s",
  5090  									"organizational_unit_identifier": "OUID"
  5091  								},
  5092  								"client_ou_identifier": {
  5093  									"certificate": "%[1]s",
  5094  									"organizational_unit_identifier": "OUID"
  5095  								},
  5096  								"enable": false,
  5097  								"orderer_ou_identifier": {
  5098  									"certificate": "%[1]s",
  5099  									"organizational_unit_identifier": "OUID"
  5100  								},
  5101  								"peer_ou_identifier": {
  5102  									"certificate": "%[1]s",
  5103  									"organizational_unit_identifier": "OUID"
  5104  								}
  5105  							},
  5106  							"intermediate_certs": [
  5107  								"%[1]s"
  5108  							],
  5109  							"name": "MSPID",
  5110  							"organizational_unit_identifiers": [
  5111  								{
  5112  									"certificate": "%[1]s",
  5113  									"organizational_unit_identifier": "OUID"
  5114  								}
  5115  							],
  5116  							"revocation_list": [
  5117  								"%[2]s"
  5118  							],
  5119  							"root_certs": [
  5120  								"%[1]s"
  5121  							],
  5122  							"signing_identity": null,
  5123  							"tls_intermediate_certs": [
  5124  								"%[1]s"
  5125  							],
  5126  							"tls_root_certs": [
  5127  								"%[1]s"
  5128  							]
  5129  						},
  5130  						"type": 0
  5131  					},
  5132  					"version": "0"
  5133  				}
  5134  			},
  5135  			"version": "0"
  5136  		}
  5137  	},
  5138  	"mod_policy": "Admins",
  5139  	"policies": {
  5140  		"Admins": {
  5141  			"mod_policy": "Admins",
  5142  			"policy": {
  5143  				"type": 3,
  5144  				"value": {
  5145  					"rule": "MAJORITY",
  5146  					"sub_policy": "Admins"
  5147  				}
  5148  			},
  5149  			"version": "0"
  5150  		},
  5151  		"BlockValidation": {
  5152  			"mod_policy": "Admins",
  5153  			"policy": {
  5154  				"type": 3,
  5155  				"value": {
  5156  					"rule": "ANY",
  5157  					"sub_policy": "Writers"
  5158  				}
  5159  			},
  5160  			"version": "0"
  5161  		},
  5162  		"Readers": {
  5163  			"mod_policy": "Admins",
  5164  			"policy": {
  5165  				"type": 3,
  5166  				"value": {
  5167  					"rule": "ANY",
  5168  					"sub_policy": "Readers"
  5169  				}
  5170  			},
  5171  			"version": "0"
  5172  		},
  5173  		"Writers": {
  5174  			"mod_policy": "Admins",
  5175  			"policy": {
  5176  				"type": 3,
  5177  				"value": {
  5178  					"rule": "ANY",
  5179  					"sub_policy": "Writers"
  5180  				}
  5181  			},
  5182  			"version": "0"
  5183  		}
  5184  	},
  5185  	"values": {
  5186  		"BatchSize": {
  5187  			"mod_policy": "Admins",
  5188  			"value": {
  5189  				"absolute_max_bytes": 100,
  5190  				"max_message_count": 100,
  5191  				"preferred_max_bytes": 100
  5192  			},
  5193  			"version": "0"
  5194  		},
  5195  		"BatchTimeout": {
  5196  			"mod_policy": "Admins",
  5197  			"value": {
  5198  				"timeout": "0s"
  5199  			},
  5200  			"version": "0"
  5201  		},
  5202  		"Capabilities": {
  5203  			"mod_policy": "Admins",
  5204  			"value": {
  5205  				"capabilities": {
  5206  					"V1_3": {}
  5207  				}
  5208  			},
  5209  			"version": "0"
  5210  		},
  5211  		"ChannelRestrictions": {
  5212  			"mod_policy": "Admins",
  5213  			"value": {
  5214  				"max_count": "100"
  5215  			},
  5216  			"version": "0"
  5217  		},
  5218  		"ConsensusType": {
  5219  			"mod_policy": "Admins",
  5220  			"value": {
  5221  				"metadata": {
  5222  					"consenters": [
  5223  						{
  5224  							"client_tls_cert": "%[3]s",
  5225  							"host": "node-1.example.com",
  5226  							"port": 7050,
  5227  							"server_tls_cert": "%[3]s"
  5228  						},
  5229  						{
  5230  							"client_tls_cert": "%[3]s",
  5231  							"host": "node-2.example.com",
  5232  							"port": 7050,
  5233  							"server_tls_cert": "%[3]s"
  5234  						},
  5235  						{
  5236  							"client_tls_cert": "%[3]s",
  5237  							"host": "node-3.example.com",
  5238  							"port": 7050,
  5239  							"server_tls_cert": "%[3]s"
  5240  						}
  5241  					],
  5242  					"options": {
  5243  						"election_tick": 0,
  5244  						"heartbeat_tick": 0,
  5245  						"max_inflight_blocks": 0,
  5246  						"snapshot_interval_size": 0,
  5247  						"tick_interval": ""
  5248  					}
  5249  				},
  5250  				"state": "STATE_NORMAL",
  5251  				"type": "etcdraft"
  5252  			},
  5253  			"version": "0"
  5254  		}
  5255  	},
  5256  	"version": "0"
  5257  }
  5258  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  5259  
  5260  	err = c.Orderer().SetMaxChannels(100)
  5261  	gt.Expect(err).NotTo(HaveOccurred())
  5262  
  5263  	buf := bytes.Buffer{}
  5264  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  5265  	gt.Expect(err).NotTo(HaveOccurred())
  5266  
  5267  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  5268  }
  5269  
  5270  func TestSetConsensusType(t *testing.T) {
  5271  	t.Parallel()
  5272  
  5273  	tests := []struct {
  5274  		testName    string
  5275  		ordererType string
  5276  		expectedErr string
  5277  	}{
  5278  		{testName: "when current consensus type is etcdraft", ordererType: orderer.ConsensusTypeEtcdRaft, expectedErr: "config does not contain value for ChannelRestrictions"},
  5279  	}
  5280  
  5281  	for _, tt := range tests {
  5282  		tt := tt
  5283  		t.Run(tt.testName, func(t *testing.T) {
  5284  			gt := NewGomegaWithT(t)
  5285  
  5286  			var etcdRaftCertBase64 string
  5287  			baseOrdererConf, _ := baseSoloOrderer(t)
  5288  			if tt.ordererType == orderer.ConsensusTypeEtcdRaft {
  5289  				baseOrdererConf, _ = baseEtcdRaftOrderer(t)
  5290  				etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  5291  				etcdRaftCertBase64 = base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  5292  
  5293  			} else if tt.ordererType == orderer.ConsensusTypeKafka {
  5294  				baseOrdererConf, _ = baseKafkaOrderer(t)
  5295  			}
  5296  
  5297  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  5298  			gt.Expect(err).NotTo(HaveOccurred())
  5299  
  5300  			config := &cb.Config{
  5301  				ChannelGroup: &cb.ConfigGroup{
  5302  					Groups: map[string]*cb.ConfigGroup{
  5303  						OrdererGroupKey: ordererGroup,
  5304  					},
  5305  				},
  5306  			}
  5307  
  5308  			c := New(config)
  5309  
  5310  			ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  5311  			orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  5312  			expectedConfigGroupJSON := fmt.Sprintf(`{
  5313  	"groups": {
  5314  		"OrdererOrg": {
  5315  			"groups": {},
  5316  			"mod_policy": "Admins",
  5317  			"policies": {
  5318  				"Admins": {
  5319  					"mod_policy": "Admins",
  5320  					"policy": {
  5321  						"type": 3,
  5322  						"value": {
  5323  							"rule": "MAJORITY",
  5324  							"sub_policy": "Admins"
  5325  						}
  5326  					},
  5327  					"version": "0"
  5328  				},
  5329  				"Endorsement": {
  5330  					"mod_policy": "Admins",
  5331  					"policy": {
  5332  						"type": 3,
  5333  						"value": {
  5334  							"rule": "MAJORITY",
  5335  							"sub_policy": "Endorsement"
  5336  						}
  5337  					},
  5338  					"version": "0"
  5339  				},
  5340  				"Readers": {
  5341  					"mod_policy": "Admins",
  5342  					"policy": {
  5343  						"type": 3,
  5344  						"value": {
  5345  							"rule": "ANY",
  5346  							"sub_policy": "Readers"
  5347  						}
  5348  					},
  5349  					"version": "0"
  5350  				},
  5351  				"Writers": {
  5352  					"mod_policy": "Admins",
  5353  					"policy": {
  5354  						"type": 3,
  5355  						"value": {
  5356  							"rule": "ANY",
  5357  							"sub_policy": "Writers"
  5358  						}
  5359  					},
  5360  					"version": "0"
  5361  				}
  5362  			},
  5363  			"values": {
  5364  				"Endpoints": {
  5365  					"mod_policy": "Admins",
  5366  					"value": {
  5367  						"addresses": [
  5368  							"localhost:123"
  5369  						]
  5370  					},
  5371  					"version": "0"
  5372  				},
  5373  				"MSP": {
  5374  					"mod_policy": "Admins",
  5375  					"value": {
  5376  						"config": {
  5377  							"admins": [
  5378  								"%[1]s"
  5379  							],
  5380  							"crypto_config": {
  5381  								"identity_identifier_hash_function": "SHA256",
  5382  								"signature_hash_family": "SHA3"
  5383  							},
  5384  							"fabric_node_ous": {
  5385  								"admin_ou_identifier": {
  5386  									"certificate": "%[1]s",
  5387  									"organizational_unit_identifier": "OUID"
  5388  								},
  5389  								"client_ou_identifier": {
  5390  									"certificate": "%[1]s",
  5391  									"organizational_unit_identifier": "OUID"
  5392  								},
  5393  								"enable": false,
  5394  								"orderer_ou_identifier": {
  5395  									"certificate": "%[1]s",
  5396  									"organizational_unit_identifier": "OUID"
  5397  								},
  5398  								"peer_ou_identifier": {
  5399  									"certificate": "%[1]s",
  5400  									"organizational_unit_identifier": "OUID"
  5401  								}
  5402  							},
  5403  							"intermediate_certs": [
  5404  								"%[1]s"
  5405  							],
  5406  							"name": "MSPID",
  5407  							"organizational_unit_identifiers": [
  5408  								{
  5409  									"certificate": "%[1]s",
  5410  									"organizational_unit_identifier": "OUID"
  5411  								}
  5412  							],
  5413  							"revocation_list": [
  5414  								"%[2]s"
  5415  							],
  5416  							"root_certs": [
  5417  								"%[1]s"
  5418  							],
  5419  							"signing_identity": null,
  5420  							"tls_intermediate_certs": [
  5421  								"%[1]s"
  5422  							],
  5423  							"tls_root_certs": [
  5424  								"%[1]s"
  5425  							]
  5426  						},
  5427  						"type": 0
  5428  					},
  5429  					"version": "0"
  5430  				}
  5431  			},
  5432  			"version": "0"
  5433  		}
  5434  	},
  5435  	"mod_policy": "Admins",
  5436  	"policies": {
  5437  		"Admins": {
  5438  			"mod_policy": "Admins",
  5439  			"policy": {
  5440  				"type": 3,
  5441  				"value": {
  5442  					"rule": "MAJORITY",
  5443  					"sub_policy": "Admins"
  5444  				}
  5445  			},
  5446  			"version": "0"
  5447  		},
  5448  		"BlockValidation": {
  5449  			"mod_policy": "Admins",
  5450  			"policy": {
  5451  				"type": 3,
  5452  				"value": {
  5453  					"rule": "ANY",
  5454  					"sub_policy": "Writers"
  5455  				}
  5456  			},
  5457  			"version": "0"
  5458  		},
  5459  		"Readers": {
  5460  			"mod_policy": "Admins",
  5461  			"policy": {
  5462  				"type": 3,
  5463  				"value": {
  5464  					"rule": "ANY",
  5465  					"sub_policy": "Readers"
  5466  				}
  5467  			},
  5468  			"version": "0"
  5469  		},
  5470  		"Writers": {
  5471  			"mod_policy": "Admins",
  5472  			"policy": {
  5473  				"type": 3,
  5474  				"value": {
  5475  					"rule": "ANY",
  5476  					"sub_policy": "Writers"
  5477  				}
  5478  			},
  5479  			"version": "0"
  5480  		}
  5481  	},
  5482  	"values": {
  5483  		"BatchSize": {
  5484  			"mod_policy": "Admins",
  5485  			"value": {
  5486  				"absolute_max_bytes": 100,
  5487  				"max_message_count": 100,
  5488  				"preferred_max_bytes": 100
  5489  			},
  5490  			"version": "0"
  5491  		},
  5492  		"BatchTimeout": {
  5493  			"mod_policy": "Admins",
  5494  			"value": {
  5495  				"timeout": "0s"
  5496  			},
  5497  			"version": "0"
  5498  		},
  5499  		"Capabilities": {
  5500  			"mod_policy": "Admins",
  5501  			"value": {
  5502  				"capabilities": {
  5503  					"V1_3": {}
  5504  				}
  5505  			},
  5506  			"version": "0"
  5507  		},
  5508  		"ChannelRestrictions": {
  5509  			"mod_policy": "Admins",
  5510  			"value": null,
  5511  			"version": "0"
  5512  		},
  5513  		"ConsensusType": {
  5514  			"mod_policy": "Admins",
  5515  			"value": {
  5516  				"metadata": {
  5517  					"consenters": [
  5518  						{
  5519  							"client_tls_cert": "%[3]s",
  5520  							"host": "node-1.example.com",
  5521  							"port": 7050,
  5522  							"server_tls_cert": "%[3]s"
  5523  						},
  5524  						{
  5525  							"client_tls_cert": "%[3]s",
  5526  							"host": "node-2.example.com",
  5527  							"port": 7050,
  5528  							"server_tls_cert": "%[3]s"
  5529  						},
  5530  						{
  5531  							"client_tls_cert": "%[3]s",
  5532  							"host": "node-3.example.com",
  5533  							"port": 7050,
  5534  							"server_tls_cert": "%[3]s"
  5535  						}
  5536  					],
  5537  					"options": {
  5538  						"election_tick": 0,
  5539  						"heartbeat_tick": 0,
  5540  						"max_inflight_blocks": 0,
  5541  						"snapshot_interval_size": 0,
  5542  						"tick_interval": ""
  5543  					}
  5544  				},
  5545  				"state": "STATE_NORMAL",
  5546  				"type": "etcdraft"
  5547  			},
  5548  			"version": "0"
  5549  		}
  5550  	},
  5551  	"version": "0"
  5552  }
  5553  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  5554  
  5555  			consensusMetadata := orderer.EtcdRaft{
  5556  				Consenters: baseOrdererConf.EtcdRaft.Consenters,
  5557  			}
  5558  			err = c.Orderer().SetEtcdRaftConsensusType(consensusMetadata, orderer.ConsensusTypeSolo)
  5559  			gt.Expect(err).NotTo(HaveOccurred())
  5560  
  5561  			buf := bytes.Buffer{}
  5562  			err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  5563  			gt.Expect(err).NotTo(HaveOccurred())
  5564  
  5565  			gt.Expect(buf.String()).To(MatchJSON(expectedConfigGroupJSON))
  5566  		})
  5567  	}
  5568  }
  5569  
  5570  func TestSetConsensusTypeFailures(t *testing.T) {
  5571  	t.Parallel()
  5572  
  5573  	tests := []struct {
  5574  		testName    string
  5575  		ordererType string
  5576  		expectedErr string
  5577  	}{
  5578  		{testName: "when consensus type is empty", ordererType: "solo", expectedErr: "marshaling etcdraft metadata: consenters are required"},
  5579  	}
  5580  
  5581  	for _, tt := range tests {
  5582  		tt := tt
  5583  		t.Run(tt.testName, func(t *testing.T) {
  5584  			gt := NewGomegaWithT(t)
  5585  
  5586  			baseOrdererConf, _ := baseSoloOrderer(t)
  5587  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  5588  			gt.Expect(err).NotTo(HaveOccurred())
  5589  
  5590  			delete(ordererGroup.Values, orderer.ConsensusTypeKey)
  5591  			config := &cb.Config{
  5592  				ChannelGroup: &cb.ConfigGroup{
  5593  					Groups: map[string]*cb.ConfigGroup{
  5594  						OrdererGroupKey: ordererGroup,
  5595  					},
  5596  				},
  5597  			}
  5598  
  5599  			c := New(config)
  5600  			err = c.Orderer().SetEtcdRaftConsensusType(orderer.EtcdRaft{}, "")
  5601  			gt.Expect(err).To(MatchError(tt.expectedErr))
  5602  		})
  5603  	}
  5604  }
  5605  
  5606  func TestSetConsensusState(t *testing.T) {
  5607  	t.Parallel()
  5608  
  5609  	gt := NewGomegaWithT(t)
  5610  
  5611  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  5612  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  5613  	gt.Expect(err).NotTo(HaveOccurred())
  5614  
  5615  	config := &cb.Config{
  5616  		ChannelGroup: &cb.ConfigGroup{
  5617  			Groups: map[string]*cb.ConfigGroup{
  5618  				OrdererGroupKey: ordererGroup,
  5619  			},
  5620  		},
  5621  	}
  5622  
  5623  	c := New(config)
  5624  
  5625  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  5626  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  5627  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  5628  
  5629  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  5630  	expectedConfigGroupJSON := fmt.Sprintf(`{
  5631  	"groups": {
  5632  		"OrdererOrg": {
  5633  			"groups": {},
  5634  			"mod_policy": "Admins",
  5635  			"policies": {
  5636  				"Admins": {
  5637  					"mod_policy": "Admins",
  5638  					"policy": {
  5639  						"type": 3,
  5640  						"value": {
  5641  							"rule": "MAJORITY",
  5642  							"sub_policy": "Admins"
  5643  						}
  5644  					},
  5645  					"version": "0"
  5646  				},
  5647  				"Endorsement": {
  5648  					"mod_policy": "Admins",
  5649  					"policy": {
  5650  						"type": 3,
  5651  						"value": {
  5652  							"rule": "MAJORITY",
  5653  							"sub_policy": "Endorsement"
  5654  						}
  5655  					},
  5656  					"version": "0"
  5657  				},
  5658  				"Readers": {
  5659  					"mod_policy": "Admins",
  5660  					"policy": {
  5661  						"type": 3,
  5662  						"value": {
  5663  							"rule": "ANY",
  5664  							"sub_policy": "Readers"
  5665  						}
  5666  					},
  5667  					"version": "0"
  5668  				},
  5669  				"Writers": {
  5670  					"mod_policy": "Admins",
  5671  					"policy": {
  5672  						"type": 3,
  5673  						"value": {
  5674  							"rule": "ANY",
  5675  							"sub_policy": "Writers"
  5676  						}
  5677  					},
  5678  					"version": "0"
  5679  				}
  5680  			},
  5681  			"values": {
  5682  				"Endpoints": {
  5683  					"mod_policy": "Admins",
  5684  					"value": {
  5685  						"addresses": [
  5686  							"localhost:123"
  5687  						]
  5688  					},
  5689  					"version": "0"
  5690  				},
  5691  				"MSP": {
  5692  					"mod_policy": "Admins",
  5693  					"value": {
  5694  						"config": {
  5695  							"admins": [
  5696  								"%[1]s"
  5697  							],
  5698  							"crypto_config": {
  5699  								"identity_identifier_hash_function": "SHA256",
  5700  								"signature_hash_family": "SHA3"
  5701  							},
  5702  							"fabric_node_ous": {
  5703  								"admin_ou_identifier": {
  5704  									"certificate": "%[1]s",
  5705  									"organizational_unit_identifier": "OUID"
  5706  								},
  5707  								"client_ou_identifier": {
  5708  									"certificate": "%[1]s",
  5709  									"organizational_unit_identifier": "OUID"
  5710  								},
  5711  								"enable": false,
  5712  								"orderer_ou_identifier": {
  5713  									"certificate": "%[1]s",
  5714  									"organizational_unit_identifier": "OUID"
  5715  								},
  5716  								"peer_ou_identifier": {
  5717  									"certificate": "%[1]s",
  5718  									"organizational_unit_identifier": "OUID"
  5719  								}
  5720  							},
  5721  							"intermediate_certs": [
  5722  								"%[1]s"
  5723  							],
  5724  							"name": "MSPID",
  5725  							"organizational_unit_identifiers": [
  5726  								{
  5727  									"certificate": "%[1]s",
  5728  									"organizational_unit_identifier": "OUID"
  5729  								}
  5730  							],
  5731  							"revocation_list": [
  5732  								"%[2]s"
  5733  							],
  5734  							"root_certs": [
  5735  								"%[1]s"
  5736  							],
  5737  							"signing_identity": null,
  5738  							"tls_intermediate_certs": [
  5739  								"%[1]s"
  5740  							],
  5741  							"tls_root_certs": [
  5742  								"%[1]s"
  5743  							]
  5744  						},
  5745  						"type": 0
  5746  					},
  5747  					"version": "0"
  5748  				}
  5749  			},
  5750  			"version": "0"
  5751  		}
  5752  	},
  5753  	"mod_policy": "Admins",
  5754  	"policies": {
  5755  		"Admins": {
  5756  			"mod_policy": "Admins",
  5757  			"policy": {
  5758  				"type": 3,
  5759  				"value": {
  5760  					"rule": "MAJORITY",
  5761  					"sub_policy": "Admins"
  5762  				}
  5763  			},
  5764  			"version": "0"
  5765  		},
  5766  		"BlockValidation": {
  5767  			"mod_policy": "Admins",
  5768  			"policy": {
  5769  				"type": 3,
  5770  				"value": {
  5771  					"rule": "ANY",
  5772  					"sub_policy": "Writers"
  5773  				}
  5774  			},
  5775  			"version": "0"
  5776  		},
  5777  		"Readers": {
  5778  			"mod_policy": "Admins",
  5779  			"policy": {
  5780  				"type": 3,
  5781  				"value": {
  5782  					"rule": "ANY",
  5783  					"sub_policy": "Readers"
  5784  				}
  5785  			},
  5786  			"version": "0"
  5787  		},
  5788  		"Writers": {
  5789  			"mod_policy": "Admins",
  5790  			"policy": {
  5791  				"type": 3,
  5792  				"value": {
  5793  					"rule": "ANY",
  5794  					"sub_policy": "Writers"
  5795  				}
  5796  			},
  5797  			"version": "0"
  5798  		}
  5799  	},
  5800  	"values": {
  5801  		"BatchSize": {
  5802  			"mod_policy": "Admins",
  5803  			"value": {
  5804  				"absolute_max_bytes": 100,
  5805  				"max_message_count": 100,
  5806  				"preferred_max_bytes": 100
  5807  			},
  5808  			"version": "0"
  5809  		},
  5810  		"BatchTimeout": {
  5811  			"mod_policy": "Admins",
  5812  			"value": {
  5813  				"timeout": "0s"
  5814  			},
  5815  			"version": "0"
  5816  		},
  5817  		"Capabilities": {
  5818  			"mod_policy": "Admins",
  5819  			"value": {
  5820  				"capabilities": {
  5821  					"V1_3": {}
  5822  				}
  5823  			},
  5824  			"version": "0"
  5825  		},
  5826  		"ChannelRestrictions": {
  5827  			"mod_policy": "Admins",
  5828  			"value": null,
  5829  			"version": "0"
  5830  		},
  5831  		"ConsensusType": {
  5832  			"mod_policy": "Admins",
  5833  			"value": {
  5834  				"metadata": {
  5835  					"consenters": [
  5836  						{
  5837  							"client_tls_cert": "%[3]s",
  5838  							"host": "node-1.example.com",
  5839  							"port": 7050,
  5840  							"server_tls_cert": "%[3]s"
  5841  						},
  5842  						{
  5843  							"client_tls_cert": "%[3]s",
  5844  							"host": "node-2.example.com",
  5845  							"port": 7050,
  5846  							"server_tls_cert": "%[3]s"
  5847  						},
  5848  						{
  5849  							"client_tls_cert": "%[3]s",
  5850  							"host": "node-3.example.com",
  5851  							"port": 7050,
  5852  							"server_tls_cert": "%[3]s"
  5853  						}
  5854  					],
  5855  					"options": {
  5856  						"election_tick": 0,
  5857  						"heartbeat_tick": 0,
  5858  						"max_inflight_blocks": 0,
  5859  						"snapshot_interval_size": 0,
  5860  						"tick_interval": ""
  5861  					}
  5862  				},
  5863  				"state": "STATE_MAINTENANCE",
  5864  				"type": "etcdraft"
  5865  			},
  5866  			"version": "0"
  5867  		}
  5868  	},
  5869  	"version": "0"
  5870  }
  5871  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  5872  
  5873  	err = c.Orderer().SetConsensusState(orderer.ConsensusStateMaintenance)
  5874  	gt.Expect(err).NotTo(HaveOccurred())
  5875  
  5876  	buf := bytes.Buffer{}
  5877  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  5878  	gt.Expect(err).NotTo(HaveOccurred())
  5879  
  5880  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  5881  }
  5882  
  5883  func TestSetConsensusStateFailures(t *testing.T) {
  5884  	t.Parallel()
  5885  
  5886  	tests := []struct {
  5887  		testName    string
  5888  		expectedErr string
  5889  	}{
  5890  		{testName: "when retrieving orderer config fails", expectedErr: "config does not contain value for ConsensusType"},
  5891  	}
  5892  
  5893  	for _, tt := range tests {
  5894  		tt := tt
  5895  		t.Run(tt.testName, func(t *testing.T) {
  5896  			gt := NewGomegaWithT(t)
  5897  
  5898  			baseOrdererConf, _ := baseSoloOrderer(t)
  5899  			ordererGroup, err := newOrdererGroup(baseOrdererConf)
  5900  			gt.Expect(err).NotTo(HaveOccurred())
  5901  
  5902  			delete(ordererGroup.Values, orderer.ConsensusTypeKey)
  5903  			config := &cb.Config{
  5904  				ChannelGroup: &cb.ConfigGroup{
  5905  					Groups: map[string]*cb.ConfigGroup{
  5906  						OrdererGroupKey: ordererGroup,
  5907  					},
  5908  				},
  5909  			}
  5910  
  5911  			c := New(config)
  5912  			err = c.Orderer().SetConsensusState("")
  5913  			gt.Expect(err).To(MatchError(tt.expectedErr))
  5914  		})
  5915  	}
  5916  }
  5917  
  5918  func TestSetEtcdRaftOptions(t *testing.T) {
  5919  	t.Parallel()
  5920  
  5921  	gt := NewGomegaWithT(t)
  5922  
  5923  	baseOrdererConf, _ := baseEtcdRaftOrderer(t)
  5924  	ordererGroup, err := newOrdererGroup(baseOrdererConf)
  5925  	gt.Expect(err).NotTo(HaveOccurred())
  5926  
  5927  	config := &cb.Config{
  5928  		ChannelGroup: &cb.ConfigGroup{
  5929  			Groups: map[string]*cb.ConfigGroup{
  5930  				OrdererGroupKey: ordererGroup,
  5931  			},
  5932  		},
  5933  	}
  5934  
  5935  	c := New(config)
  5936  
  5937  	ordererOrgMSP := baseOrdererConf.Organizations[0].MSP
  5938  	orgCertBase64, orgCRLBase64 := certCRLBase64(t, ordererOrgMSP)
  5939  	etcdRaftCert := baseOrdererConf.EtcdRaft.Consenters[0].ClientTLSCert
  5940  
  5941  	etcdRaftCertBase64 := base64.StdEncoding.EncodeToString(pemEncodeX509Certificate(etcdRaftCert))
  5942  	expectedConfigGroupJSON := fmt.Sprintf(`{
  5943  	"groups": {
  5944  		"OrdererOrg": {
  5945  			"groups": {},
  5946  			"mod_policy": "Admins",
  5947  			"policies": {
  5948  				"Admins": {
  5949  					"mod_policy": "Admins",
  5950  					"policy": {
  5951  						"type": 3,
  5952  						"value": {
  5953  							"rule": "MAJORITY",
  5954  							"sub_policy": "Admins"
  5955  						}
  5956  					},
  5957  					"version": "0"
  5958  				},
  5959  				"Endorsement": {
  5960  					"mod_policy": "Admins",
  5961  					"policy": {
  5962  						"type": 3,
  5963  						"value": {
  5964  							"rule": "MAJORITY",
  5965  							"sub_policy": "Endorsement"
  5966  						}
  5967  					},
  5968  					"version": "0"
  5969  				},
  5970  				"Readers": {
  5971  					"mod_policy": "Admins",
  5972  					"policy": {
  5973  						"type": 3,
  5974  						"value": {
  5975  							"rule": "ANY",
  5976  							"sub_policy": "Readers"
  5977  						}
  5978  					},
  5979  					"version": "0"
  5980  				},
  5981  				"Writers": {
  5982  					"mod_policy": "Admins",
  5983  					"policy": {
  5984  						"type": 3,
  5985  						"value": {
  5986  							"rule": "ANY",
  5987  							"sub_policy": "Writers"
  5988  						}
  5989  					},
  5990  					"version": "0"
  5991  				}
  5992  			},
  5993  			"values": {
  5994  				"Endpoints": {
  5995  					"mod_policy": "Admins",
  5996  					"value": {
  5997  						"addresses": [
  5998  							"localhost:123"
  5999  						]
  6000  					},
  6001  					"version": "0"
  6002  				},
  6003  				"MSP": {
  6004  					"mod_policy": "Admins",
  6005  					"value": {
  6006  						"config": {
  6007  							"admins": [
  6008  								"%[1]s"
  6009  							],
  6010  							"crypto_config": {
  6011  								"identity_identifier_hash_function": "SHA256",
  6012  								"signature_hash_family": "SHA3"
  6013  							},
  6014  							"fabric_node_ous": {
  6015  								"admin_ou_identifier": {
  6016  									"certificate": "%[1]s",
  6017  									"organizational_unit_identifier": "OUID"
  6018  								},
  6019  								"client_ou_identifier": {
  6020  									"certificate": "%[1]s",
  6021  									"organizational_unit_identifier": "OUID"
  6022  								},
  6023  								"enable": false,
  6024  								"orderer_ou_identifier": {
  6025  									"certificate": "%[1]s",
  6026  									"organizational_unit_identifier": "OUID"
  6027  								},
  6028  								"peer_ou_identifier": {
  6029  									"certificate": "%[1]s",
  6030  									"organizational_unit_identifier": "OUID"
  6031  								}
  6032  							},
  6033  							"intermediate_certs": [
  6034  								"%[1]s"
  6035  							],
  6036  							"name": "MSPID",
  6037  							"organizational_unit_identifiers": [
  6038  								{
  6039  									"certificate": "%[1]s",
  6040  									"organizational_unit_identifier": "OUID"
  6041  								}
  6042  							],
  6043  							"revocation_list": [
  6044  								"%[2]s"
  6045  							],
  6046  							"root_certs": [
  6047  								"%[1]s"
  6048  							],
  6049  							"signing_identity": null,
  6050  							"tls_intermediate_certs": [
  6051  								"%[1]s"
  6052  							],
  6053  							"tls_root_certs": [
  6054  								"%[1]s"
  6055  							]
  6056  						},
  6057  						"type": 0
  6058  					},
  6059  					"version": "0"
  6060  				}
  6061  			},
  6062  			"version": "0"
  6063  		}
  6064  	},
  6065  	"mod_policy": "Admins",
  6066  	"policies": {
  6067  		"Admins": {
  6068  			"mod_policy": "Admins",
  6069  			"policy": {
  6070  				"type": 3,
  6071  				"value": {
  6072  					"rule": "MAJORITY",
  6073  					"sub_policy": "Admins"
  6074  				}
  6075  			},
  6076  			"version": "0"
  6077  		},
  6078  		"BlockValidation": {
  6079  			"mod_policy": "Admins",
  6080  			"policy": {
  6081  				"type": 3,
  6082  				"value": {
  6083  					"rule": "ANY",
  6084  					"sub_policy": "Writers"
  6085  				}
  6086  			},
  6087  			"version": "0"
  6088  		},
  6089  		"Readers": {
  6090  			"mod_policy": "Admins",
  6091  			"policy": {
  6092  				"type": 3,
  6093  				"value": {
  6094  					"rule": "ANY",
  6095  					"sub_policy": "Readers"
  6096  				}
  6097  			},
  6098  			"version": "0"
  6099  		},
  6100  		"Writers": {
  6101  			"mod_policy": "Admins",
  6102  			"policy": {
  6103  				"type": 3,
  6104  				"value": {
  6105  					"rule": "ANY",
  6106  					"sub_policy": "Writers"
  6107  				}
  6108  			},
  6109  			"version": "0"
  6110  		}
  6111  	},
  6112  	"values": {
  6113  		"BatchSize": {
  6114  			"mod_policy": "Admins",
  6115  			"value": {
  6116  				"absolute_max_bytes": 100,
  6117  				"max_message_count": 100,
  6118  				"preferred_max_bytes": 100
  6119  			},
  6120  			"version": "0"
  6121  		},
  6122  		"BatchTimeout": {
  6123  			"mod_policy": "Admins",
  6124  			"value": {
  6125  				"timeout": "0s"
  6126  			},
  6127  			"version": "0"
  6128  		},
  6129  		"Capabilities": {
  6130  			"mod_policy": "Admins",
  6131  			"value": {
  6132  				"capabilities": {
  6133  					"V1_3": {}
  6134  				}
  6135  			},
  6136  			"version": "0"
  6137  		},
  6138  		"ChannelRestrictions": {
  6139  			"mod_policy": "Admins",
  6140  			"value": null,
  6141  			"version": "0"
  6142  		},
  6143  		"ConsensusType": {
  6144  			"mod_policy": "Admins",
  6145  			"value": {
  6146  				"metadata": {
  6147  					"consenters": [
  6148  						{
  6149  							"client_tls_cert": "%[3]s",
  6150  							"host": "node-1.example.com",
  6151  							"port": 7050,
  6152  							"server_tls_cert": "%[3]s"
  6153  						},
  6154  						{
  6155  							"client_tls_cert": "%[3]s",
  6156  							"host": "node-2.example.com",
  6157  							"port": 7050,
  6158  							"server_tls_cert": "%[3]s"
  6159  						},
  6160  						{
  6161  							"client_tls_cert": "%[3]s",
  6162  							"host": "node-3.example.com",
  6163  							"port": 7050,
  6164  							"server_tls_cert": "%[3]s"
  6165  						}
  6166  					],
  6167  					"options": {
  6168  						"election_tick": 10,
  6169  						"heartbeat_tick": 20,
  6170  						"max_inflight_blocks": 5,
  6171  						"snapshot_interval_size": 25,
  6172  						"tick_interval": "200"
  6173  					}
  6174  				},
  6175  				"state": "STATE_NORMAL",
  6176  				"type": "etcdraft"
  6177  			},
  6178  			"version": "0"
  6179  		}
  6180  	},
  6181  	"version": "0"
  6182  }
  6183  `, orgCertBase64, orgCRLBase64, etcdRaftCertBase64)
  6184  
  6185  	err = c.Orderer().EtcdRaftOptions().SetTickInterval("200")
  6186  	gt.Expect(err).NotTo(HaveOccurred())
  6187  
  6188  	err = c.Orderer().EtcdRaftOptions().SetElectionInterval(10)
  6189  	gt.Expect(err).NotTo(HaveOccurred())
  6190  
  6191  	err = c.Orderer().EtcdRaftOptions().SetHeartbeatTick(20)
  6192  	gt.Expect(err).NotTo(HaveOccurred())
  6193  
  6194  	err = c.Orderer().EtcdRaftOptions().SetMaxInflightBlocks(5)
  6195  	gt.Expect(err).NotTo(HaveOccurred())
  6196  
  6197  	err = c.Orderer().EtcdRaftOptions().SetSnapshotIntervalSize(25)
  6198  	gt.Expect(err).NotTo(HaveOccurred())
  6199  
  6200  	buf := bytes.Buffer{}
  6201  	err = protolator.DeepMarshalJSON(&buf, &ordererext.DynamicOrdererGroup{ConfigGroup: c.Orderer().ordererGroup})
  6202  	gt.Expect(err).NotTo(HaveOccurred())
  6203  
  6204  	gt.Expect(buf.String()).To(Equal(expectedConfigGroupJSON))
  6205  }
  6206  
  6207  func baseOrdererOfType(t *testing.T, ordererType string) (Orderer, []*ecdsa.PrivateKey) {
  6208  	switch ordererType {
  6209  	case orderer.ConsensusTypeKafka:
  6210  		return baseKafkaOrderer(t)
  6211  	case orderer.ConsensusTypeEtcdRaft:
  6212  		return baseEtcdRaftOrderer(t)
  6213  	default:
  6214  		return baseSoloOrderer(t)
  6215  	}
  6216  }
  6217  
  6218  func baseSoloOrderer(t *testing.T) (Orderer, []*ecdsa.PrivateKey) {
  6219  	baseMSP, privKey := baseMSP(t)
  6220  	return Orderer{
  6221  		Policies:    ordererStandardPolicies(),
  6222  		OrdererType: orderer.ConsensusTypeSolo,
  6223  		Organizations: []Organization{
  6224  			{
  6225  				Name:     "OrdererOrg",
  6226  				Policies: orgStandardPolicies(),
  6227  				OrdererEndpoints: []string{
  6228  					"localhost:123",
  6229  				},
  6230  				MSP: baseMSP,
  6231  			},
  6232  		},
  6233  		Capabilities: []string{"V1_3"},
  6234  		BatchSize: orderer.BatchSize{
  6235  			MaxMessageCount:   100,
  6236  			AbsoluteMaxBytes:  100,
  6237  			PreferredMaxBytes: 100,
  6238  		},
  6239  		State:     orderer.ConsensusStateNormal,
  6240  		ModPolicy: AdminsPolicyKey,
  6241  	}, []*ecdsa.PrivateKey{privKey}
  6242  }
  6243  
  6244  func baseKafkaOrderer(t *testing.T) (Orderer, []*ecdsa.PrivateKey) {
  6245  	soloOrderer, privKeys := baseSoloOrderer(t)
  6246  	soloOrderer.OrdererType = orderer.ConsensusTypeKafka
  6247  	soloOrderer.Kafka = orderer.Kafka{
  6248  		Brokers: []string{"broker1", "broker2"},
  6249  	}
  6250  
  6251  	return soloOrderer, privKeys
  6252  }
  6253  
  6254  func baseEtcdRaftOrderer(t *testing.T) (Orderer, []*ecdsa.PrivateKey) {
  6255  	caCert, caPrivKey := generateCACertAndPrivateKey(t, "orderer-org")
  6256  	cert, _ := generateCertAndPrivateKeyFromCACert(t, "orderer-org", caCert, caPrivKey)
  6257  
  6258  	soloOrderer, privKeys := baseSoloOrderer(t)
  6259  	soloOrderer.OrdererType = orderer.ConsensusTypeEtcdRaft
  6260  	soloOrderer.EtcdRaft = orderer.EtcdRaft{
  6261  		Consenters: []orderer.Consenter{
  6262  			{
  6263  				Address: orderer.EtcdAddress{
  6264  					Host: "node-1.example.com",
  6265  					Port: 7050,
  6266  				},
  6267  				ClientTLSCert: cert,
  6268  				ServerTLSCert: cert,
  6269  			},
  6270  			{
  6271  				Address: orderer.EtcdAddress{
  6272  					Host: "node-2.example.com",
  6273  					Port: 7050,
  6274  				},
  6275  				ClientTLSCert: cert,
  6276  				ServerTLSCert: cert,
  6277  			},
  6278  			{
  6279  				Address: orderer.EtcdAddress{
  6280  					Host: "node-3.example.com",
  6281  					Port: 7050,
  6282  				},
  6283  				ClientTLSCert: cert,
  6284  				ServerTLSCert: cert,
  6285  			},
  6286  		},
  6287  		Options: orderer.EtcdRaftOptions{},
  6288  	}
  6289  
  6290  	return soloOrderer, privKeys
  6291  }
  6292  
  6293  // baseOrdererChannelGroup creates a channel config group
  6294  // that only contains an Orderer group.
  6295  func baseOrdererChannelGroup(t *testing.T, ordererType string) (*cb.ConfigGroup, []*ecdsa.PrivateKey, error) {
  6296  	channelGroup := newConfigGroup()
  6297  
  6298  	ordererConf, privKeys := baseOrdererOfType(t, ordererType)
  6299  	ordererGroup, err := newOrdererGroup(ordererConf)
  6300  	if err != nil {
  6301  		return nil, nil, err
  6302  	}
  6303  	channelGroup.Groups[OrdererGroupKey] = ordererGroup
  6304  
  6305  	return channelGroup, privKeys, nil
  6306  }
  6307  
  6308  // marshalOrPanic is a helper for proto marshal.
  6309  func marshalOrPanic(pb proto.Message) []byte {
  6310  	data, err := proto.Marshal(pb)
  6311  	if err != nil {
  6312  		panic(err)
  6313  	}
  6314  
  6315  	return data
  6316  }