github.com/anjalikarhana/fabric@v2.1.1+incompatible/integration/raft/config_test.go (about)

     1  /*
     2  Copyright IBM Corp All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package raft
     8  
     9  import (
    10  	"bytes"
    11  	"crypto/ecdsa"
    12  	"crypto/rand"
    13  	"crypto/x509"
    14  	"encoding/pem"
    15  	"fmt"
    16  	"io/ioutil"
    17  	"os"
    18  	"path/filepath"
    19  	"strings"
    20  	"sync"
    21  	"syscall"
    22  	"time"
    23  
    24  	docker "github.com/fsouza/go-dockerclient"
    25  	"github.com/golang/protobuf/proto"
    26  	"github.com/hyperledger/fabric-protos-go/common"
    27  	"github.com/hyperledger/fabric-protos-go/msp"
    28  	protosorderer "github.com/hyperledger/fabric-protos-go/orderer"
    29  	"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    30  	"github.com/hyperledger/fabric/common/crypto/tlsgen"
    31  	"github.com/hyperledger/fabric/integration/nwo"
    32  	"github.com/hyperledger/fabric/integration/nwo/commands"
    33  	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
    34  	"github.com/hyperledger/fabric/internal/configtxgen/genesisconfig"
    35  	"github.com/hyperledger/fabric/protoutil"
    36  	. "github.com/onsi/ginkgo"
    37  	. "github.com/onsi/gomega"
    38  	"github.com/onsi/gomega/gbytes"
    39  	"github.com/onsi/gomega/gexec"
    40  	"github.com/tedsuo/ifrit"
    41  	"github.com/tedsuo/ifrit/ginkgomon"
    42  )
    43  
    44  var _ = Describe("EndToEnd reconfiguration and onboarding", func() {
    45  	var (
    46  		testDir string
    47  		client  *docker.Client
    48  		network *nwo.Network
    49  		peer    *nwo.Peer
    50  
    51  		networkProcess   ifrit.Process
    52  		ordererProcesses []ifrit.Process
    53  		ordererRunners   []*ginkgomon.Runner
    54  	)
    55  
    56  	BeforeEach(func() {
    57  		ordererRunners = nil
    58  		ordererProcesses = nil
    59  
    60  		var err error
    61  		testDir, err = ioutil.TempDir("", "e2e-etcdraft_reconfig")
    62  		Expect(err).NotTo(HaveOccurred())
    63  
    64  		client, err = docker.NewClientFromEnv()
    65  		Expect(err).NotTo(HaveOccurred())
    66  	})
    67  
    68  	AfterEach(func() {
    69  		if networkProcess != nil {
    70  			networkProcess.Signal(syscall.SIGTERM)
    71  			Eventually(networkProcess.Wait(), network.EventuallyTimeout).Should(Receive())
    72  		}
    73  		if network != nil {
    74  			network.Cleanup()
    75  		}
    76  		for _, ordererInstance := range ordererProcesses {
    77  			ordererInstance.Signal(syscall.SIGTERM)
    78  			Eventually(ordererInstance.Wait(), network.EventuallyTimeout).Should(Receive())
    79  		}
    80  		os.RemoveAll(testDir)
    81  	})
    82  
    83  	Describe("three node etcdraft network with 2 orgs", func() {
    84  		BeforeEach(func() {
    85  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
    86  			network.GenerateConfigTree()
    87  			network.Bootstrap()
    88  
    89  			networkRunner := network.NetworkGroupRunner()
    90  			networkProcess = ifrit.Invoke(networkRunner)
    91  			Eventually(networkProcess.Ready(), network.EventuallyTimeout).Should(BeClosed())
    92  		})
    93  
    94  		// This tests:
    95  		//
    96  		// 1. channel creation with raft orderer,
    97  		// 2. all the nodes on three-node raft cluster are in sync wrt blocks,
    98  		// 3. raft orderer processes type A config updates and delivers the
    99  		//    config blocks to the peers.
   100  		It("executes an etcdraft network with 2 orgs and three orderer nodes", func() {
   101  			orderer1 := network.Orderer("orderer1")
   102  			orderer2 := network.Orderer("orderer2")
   103  			orderer3 := network.Orderer("orderer3")
   104  			peer := network.Peer("Org1", "peer0")
   105  			blockFile1 := filepath.Join(testDir, "newest_orderer1_block.pb")
   106  			blockFile2 := filepath.Join(testDir, "newest_orderer2_block.pb")
   107  			blockFile3 := filepath.Join(testDir, "newest_orderer3_block.pb")
   108  
   109  			By("Ordering service system channel is ready")
   110  			assertBlockReception(map[string]int{
   111  				"systemchannel": 0,
   112  			}, []*nwo.Orderer{orderer1, orderer2, orderer3}, peer, network)
   113  
   114  			fetchLatestBlock := func(targetOrderer *nwo.Orderer, blockFile string) {
   115  				c := commands.ChannelFetch{
   116  					ChannelID:  "testchannel",
   117  					Block:      "newest",
   118  					OutputFile: blockFile,
   119  				}
   120  				if targetOrderer != nil {
   121  					c.Orderer = network.OrdererAddress(targetOrderer, nwo.ListenPort)
   122  				}
   123  				sess, err := network.PeerAdminSession(peer, c)
   124  				Expect(err).NotTo(HaveOccurred())
   125  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   126  			}
   127  
   128  			By("Creating a new channel")
   129  			network.CreateChannel("testchannel", orderer1, peer)
   130  
   131  			// the above can work even if the orderer nodes are not in the same Raft
   132  			// cluster; we need to verify all the three orderer nodes are in sync wrt
   133  			// blocks.
   134  			By("Fetching the latest blocks from all the orderer nodes and testing them for equality")
   135  			fetchLatestBlock(orderer1, blockFile1)
   136  			fetchLatestBlock(orderer2, blockFile2)
   137  			fetchLatestBlock(orderer3, blockFile3)
   138  			b1 := nwo.UnmarshalBlockFromFile(blockFile1)
   139  			b2 := nwo.UnmarshalBlockFromFile(blockFile2)
   140  			b3 := nwo.UnmarshalBlockFromFile(blockFile3)
   141  			Expect(protoutil.BlockHeaderBytes(b1.Header)).To(Equal(protoutil.BlockHeaderBytes(b2.Header)))
   142  			Expect(protoutil.BlockHeaderBytes(b2.Header)).To(Equal(protoutil.BlockHeaderBytes(b3.Header)))
   143  		})
   144  	})
   145  
   146  	Describe("Invalid Raft config metadata", func() {
   147  		It("refuses to start orderer or rejects config update", func() {
   148  			By("Creating malformed genesis block")
   149  			network = nwo.New(nwo.BasicEtcdRaft(), testDir, client, StartPort(), components)
   150  			network.GenerateConfigTree()
   151  			network.Bootstrap()
   152  
   153  			sysProfile := genesisconfig.Load(network.SystemChannel.Profile, network.RootDir)
   154  			Expect(sysProfile.Orderer).NotTo(BeNil())
   155  			sysProfile.Orderer.EtcdRaft.Options.ElectionTick = sysProfile.Orderer.EtcdRaft.Options.HeartbeatTick
   156  			pgen := encoder.New(sysProfile)
   157  			genesisBlock := pgen.GenesisBlockForChannel(network.SystemChannel.Name)
   158  			data, err := proto.Marshal(genesisBlock)
   159  			Expect(err).NotTo(HaveOccurred())
   160  			ioutil.WriteFile(network.OutputBlockPath(network.SystemChannel.Name), data, 0644)
   161  
   162  			By("Starting orderer with malformed genesis block")
   163  			ordererRunner := network.OrdererGroupRunner()
   164  			process := ifrit.Invoke(ordererRunner)
   165  			Eventually(process.Wait, network.EventuallyTimeout).Should(Receive()) // orderer process should exit
   166  			os.RemoveAll(testDir)
   167  
   168  			By("Starting orderer with correct genesis block")
   169  			testDir, err = ioutil.TempDir("", "e2e")
   170  			Expect(err).NotTo(HaveOccurred())
   171  			network = nwo.New(nwo.BasicEtcdRaft(), testDir, client, StartPort(), components)
   172  			network.GenerateConfigTree()
   173  			network.Bootstrap()
   174  
   175  			orderer := network.Orderer("orderer")
   176  			runner := network.OrdererRunner(orderer)
   177  			process = ifrit.Invoke(runner)
   178  			Eventually(process.Ready, network.EventuallyTimeout).Should(BeClosed())
   179  			defer func() {
   180  				process.Signal(syscall.SIGTERM)
   181  				Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
   182  			}()
   183  
   184  			By("Waiting for system channel to be ready")
   185  			findLeader([]*ginkgomon.Runner{runner})
   186  
   187  			By("Creating malformed channel creation config tx")
   188  			channel := "testchannel"
   189  			sysProfile = genesisconfig.Load(network.SystemChannel.Profile, network.RootDir)
   190  			Expect(sysProfile.Orderer).NotTo(BeNil())
   191  			appProfile := genesisconfig.Load(network.ProfileForChannel(channel), network.RootDir)
   192  			Expect(appProfile).NotTo(BeNil())
   193  			o := *sysProfile.Orderer
   194  			appProfile.Orderer = &o
   195  			appProfile.Orderer.EtcdRaft = proto.Clone(sysProfile.Orderer.EtcdRaft).(*etcdraft.ConfigMetadata)
   196  			appProfile.Orderer.EtcdRaft.Options.HeartbeatTick = appProfile.Orderer.EtcdRaft.Options.ElectionTick
   197  			configtx, err := encoder.MakeChannelCreationTransactionWithSystemChannelContext(channel, nil, appProfile, sysProfile)
   198  			Expect(err).NotTo(HaveOccurred())
   199  			data, err = proto.Marshal(configtx)
   200  			Expect(err).NotTo(HaveOccurred())
   201  			ioutil.WriteFile(network.CreateChannelTxPath(channel), data, 0644)
   202  
   203  			By("Submitting malformed channel creation config tx to orderer")
   204  			org1Peer0 := network.Peer("Org1", "peer0")
   205  			org2Peer0 := network.Peer("Org2", "peer0")
   206  
   207  			exitCode := network.CreateChannelExitCode(channel, orderer, org1Peer0, org1Peer0, org2Peer0, orderer)
   208  			Expect(exitCode).NotTo(Equal(0))
   209  			Consistently(process.Wait).ShouldNot(Receive()) // malformed tx should not crash orderer
   210  			Expect(runner.Err()).To(gbytes.Say(`invalid new config metdadata: ElectionTick \(10\) must be greater than HeartbeatTick \(10\)`))
   211  
   212  			By("Submitting channel config update with illegal value")
   213  			channel = network.SystemChannel.Name
   214  			config := nwo.GetConfig(network, org1Peer0, orderer, channel)
   215  			updatedConfig := proto.Clone(config).(*common.Config)
   216  
   217  			consensusTypeConfigValue := updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"]
   218  			consensusTypeValue := &protosorderer.ConsensusType{}
   219  			Expect(proto.Unmarshal(consensusTypeConfigValue.Value, consensusTypeValue)).To(Succeed())
   220  
   221  			metadata := &etcdraft.ConfigMetadata{}
   222  			Expect(proto.Unmarshal(consensusTypeValue.Metadata, metadata)).To(Succeed())
   223  
   224  			metadata.Options.HeartbeatTick = 10
   225  			metadata.Options.ElectionTick = 10
   226  
   227  			newMetadata, err := proto.Marshal(metadata)
   228  			Expect(err).NotTo(HaveOccurred())
   229  			consensusTypeValue.Metadata = newMetadata
   230  
   231  			updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"] = &common.ConfigValue{
   232  				ModPolicy: "Admins",
   233  				Value:     protoutil.MarshalOrPanic(consensusTypeValue),
   234  			}
   235  
   236  			sess := nwo.UpdateOrdererConfigSession(network, orderer, channel, config, updatedConfig, org1Peer0, orderer)
   237  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   238  			Expect(sess.Err).To(gbytes.Say(`invalid new config metdadata: ElectionTick \(10\) must be greater than HeartbeatTick \(10\)`))
   239  		})
   240  	})
   241  
   242  	When("a single node cluster is expanded", func() {
   243  		It("is still possible to onboard the new cluster member and then another one with a different TLS root CA", func() {
   244  			launch := func(o *nwo.Orderer) {
   245  				runner := network.OrdererRunner(o)
   246  				ordererRunners = append(ordererRunners, runner)
   247  
   248  				process := ifrit.Invoke(runner)
   249  				Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   250  				ordererProcesses = append(ordererProcesses, process)
   251  			}
   252  
   253  			network = nwo.New(nwo.BasicEtcdRaft(), testDir, client, StartPort(), components)
   254  			network.GenerateConfigTree()
   255  			network.Bootstrap()
   256  
   257  			orderer := network.Orderer("orderer")
   258  			peer = network.Peer("Org1", "peer0")
   259  
   260  			By("Launching the orderer")
   261  			launch(orderer)
   262  
   263  			By("Checking that it elected itself as a leader")
   264  			findLeader(ordererRunners)
   265  
   266  			By("Extending the network configuration to add a new orderer")
   267  			orderer2 := &nwo.Orderer{
   268  				Name:         "orderer2",
   269  				Organization: "OrdererOrg",
   270  			}
   271  			ports := nwo.Ports{}
   272  			for _, portName := range nwo.OrdererPortNames() {
   273  				ports[portName] = network.ReservePort()
   274  			}
   275  			network.PortsByOrdererID[orderer2.ID()] = ports
   276  			network.Orderers = append(network.Orderers, orderer2)
   277  			network.GenerateOrdererConfig(orderer2)
   278  			extendNetwork(network)
   279  
   280  			secondOrdererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(orderer2), "server.crt")
   281  			secondOrdererCertificate, err := ioutil.ReadFile(secondOrdererCertificatePath)
   282  			Expect(err).NotTo(HaveOccurred())
   283  
   284  			By("Adding the second orderer")
   285  			addConsenter(network, peer, orderer, "systemchannel", etcdraft.Consenter{
   286  				ServerTlsCert: secondOrdererCertificate,
   287  				ClientTlsCert: secondOrdererCertificate,
   288  				Host:          "127.0.0.1",
   289  				Port:          uint32(network.OrdererPort(orderer2, nwo.ClusterPort)),
   290  			})
   291  
   292  			By("Obtaining the last config block from the orderer")
   293  			// Get the last config block of the system channel
   294  			configBlock := nwo.GetConfigBlock(network, peer, orderer, "systemchannel")
   295  			// Plant it in the file system of orderer2, the new node to be onboarded.
   296  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
   297  			Expect(err).NotTo(HaveOccurred())
   298  
   299  			By("Waiting for the existing orderer to relinquish its leadership")
   300  			Eventually(ordererRunners[0].Err(), network.EventuallyTimeout).Should(gbytes.Say("1 stepped down to follower since quorum is not active"))
   301  			Eventually(ordererRunners[0].Err(), network.EventuallyTimeout).Should(gbytes.Say("No leader is present, cluster size is 2"))
   302  			By("Launching the second orderer")
   303  			launch(orderer2)
   304  			By("Waiting for a leader to be re-elected")
   305  			findLeader(ordererRunners)
   306  
   307  			// In the next part of the test we're going to bring up a third node
   308  			// with a different TLS root CA. We're then going to remove the TLS
   309  			// root CA and restart the orderer, to ensure that we can dynamically
   310  			// update TLS root CAs in Raft while membership stays the same.
   311  
   312  			By("Creating configuration for a third orderer with a different TLS root CA")
   313  			orderer3 := &nwo.Orderer{
   314  				Name:         "orderer3",
   315  				Organization: "OrdererOrg",
   316  			}
   317  			ports = nwo.Ports{}
   318  			for _, portName := range nwo.OrdererPortNames() {
   319  				ports[portName] = network.ReservePort()
   320  			}
   321  			network.PortsByOrdererID[orderer3.ID()] = ports
   322  			network.Orderers = append(network.Orderers, orderer3)
   323  			network.GenerateOrdererConfig(orderer3)
   324  
   325  			tmpDir, err := ioutil.TempDir("", "e2e-etcfraft_reconfig")
   326  			Expect(err).NotTo(HaveOccurred())
   327  			defer os.RemoveAll(tmpDir)
   328  
   329  			sess, err := network.Cryptogen(commands.Generate{
   330  				Config: network.CryptoConfigPath(),
   331  				Output: tmpDir,
   332  			})
   333  			Expect(err).NotTo(HaveOccurred())
   334  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   335  
   336  			name := network.Orderers[0].Name
   337  			domain := network.Organization(network.Orderers[0].Organization).Domain
   338  			nameDomain := fmt.Sprintf("%s.%s", name, domain)
   339  			ordererTLSPath := filepath.Join(tmpDir, "ordererOrganizations", domain, "orderers", nameDomain, "tls")
   340  
   341  			caKeyPath := filepath.Join(tmpDir, "ordererOrganizations", domain, "tlsca", "priv_sk")
   342  			caCertPath := filepath.Join(tmpDir, "ordererOrganizations", domain, "tlsca", fmt.Sprintf("tlsca.%s-cert.pem", domain))
   343  
   344  			caKey, err := ioutil.ReadFile(caKeyPath)
   345  			Expect(err).NotTo(HaveOccurred())
   346  
   347  			caCert, err := ioutil.ReadFile(caCertPath)
   348  			Expect(err).NotTo(HaveOccurred())
   349  
   350  			thirdOrdererCertificatePath := filepath.Join(ordererTLSPath, "server.crt")
   351  			thirdOrdererCertificate, err := ioutil.ReadFile(thirdOrdererCertificatePath)
   352  			Expect(err).NotTo(HaveOccurred())
   353  
   354  			By("Changing its subject name")
   355  			caCert, thirdOrdererCertificate = changeSubjectName(caCert, caKey, thirdOrdererCertificate, "tlsca2")
   356  
   357  			By("Updating it on the file system")
   358  			err = ioutil.WriteFile(caCertPath, caCert, 0644)
   359  			Expect(err).NotTo(HaveOccurred())
   360  			err = ioutil.WriteFile(thirdOrdererCertificatePath, thirdOrdererCertificate, 0644)
   361  			Expect(err).NotTo(HaveOccurred())
   362  
   363  			By("Overwriting the TLS directory of the new orderer")
   364  			for _, fileName := range []string{"server.crt", "server.key", "ca.crt"} {
   365  				dst := filepath.Join(network.OrdererLocalTLSDir(orderer3), fileName)
   366  
   367  				data, err := ioutil.ReadFile(filepath.Join(ordererTLSPath, fileName))
   368  				Expect(err).NotTo(HaveOccurred())
   369  
   370  				err = ioutil.WriteFile(dst, data, 0644)
   371  				Expect(err).NotTo(HaveOccurred())
   372  			}
   373  
   374  			By("Obtaining the last config block from the orderer once more to update the bootstrap file")
   375  			configBlock = nwo.GetConfigBlock(network, peer, orderer, "systemchannel")
   376  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
   377  			Expect(err).NotTo(HaveOccurred())
   378  
   379  			By("Launching orderer3")
   380  			launch(orderer3)
   381  
   382  			By("Expanding the TLS root CA certificates")
   383  			nwo.UpdateOrdererMSP(network, peer, orderer, "systemchannel", "OrdererOrg", func(config msp.FabricMSPConfig) msp.FabricMSPConfig {
   384  				config.TlsRootCerts = append(config.TlsRootCerts, caCert)
   385  				return config
   386  			})
   387  
   388  			By("Adding orderer3 to the channel")
   389  			addConsenter(network, peer, orderer, "systemchannel", etcdraft.Consenter{
   390  				ServerTlsCert: thirdOrdererCertificate,
   391  				ClientTlsCert: thirdOrdererCertificate,
   392  				Host:          "127.0.0.1",
   393  				Port:          uint32(network.OrdererPort(orderer3, nwo.ClusterPort)),
   394  			})
   395  
   396  			By("Waiting for orderer3 to see the leader")
   397  			findLeader([]*ginkgomon.Runner{ordererRunners[2]})
   398  
   399  			By("Removing orderer3's TLS root CA certificate")
   400  			nwo.UpdateOrdererMSP(network, peer, orderer, "systemchannel", "OrdererOrg", func(config msp.FabricMSPConfig) msp.FabricMSPConfig {
   401  				config.TlsRootCerts = config.TlsRootCerts[:len(config.TlsRootCerts)-1]
   402  				return config
   403  			})
   404  
   405  			By("Killing orderer3")
   406  			o3Proc := ordererProcesses[2]
   407  			o3Proc.Signal(syscall.SIGKILL)
   408  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive(MatchError("exit status 137")))
   409  
   410  			By("Restarting orderer3")
   411  			o3Runner := network.OrdererRunner(orderer3)
   412  			ordererRunners[2] = o3Runner
   413  			o3Proc = ifrit.Invoke(o3Runner)
   414  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   415  			ordererProcesses[2] = o3Proc
   416  
   417  			By("Ensuring TLS handshakes fail with the other orderers")
   418  			for i, oRunner := range ordererRunners {
   419  				if i < 2 {
   420  					Eventually(oRunner.Err(), network.EventuallyTimeout).Should(gbytes.Say("TLS handshake failed with error tls: client didn't provide a certificate"))
   421  					continue
   422  				}
   423  				Eventually(oRunner.Err(), network.EventuallyTimeout).Should(gbytes.Say("TLS handshake failed with error remote error: tls: bad certificate"))
   424  				Eventually(oRunner.Err(), network.EventuallyTimeout).Should(gbytes.Say("Suspecting our own eviction from the channel"))
   425  			}
   426  
   427  			By("Attemping to add a consenter with invalid certs")
   428  			// create new certs that are not in the channel config
   429  			ca, err := tlsgen.NewCA()
   430  			Expect(err).NotTo(HaveOccurred())
   431  			client, err := ca.NewClientCertKeyPair()
   432  			Expect(err).NotTo(HaveOccurred())
   433  
   434  			current, updated := consenterAdder(
   435  				network,
   436  				peer,
   437  				orderer,
   438  				"systemchannel",
   439  				etcdraft.Consenter{
   440  					ServerTlsCert: client.Cert,
   441  					ClientTlsCert: client.Cert,
   442  					Host:          "127.0.0.1",
   443  					Port:          uint32(network.OrdererPort(orderer3, nwo.ListenPort)),
   444  				},
   445  			)
   446  			sess = nwo.UpdateOrdererConfigSession(network, orderer, network.SystemChannel.Name, current, updated, peer, orderer)
   447  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   448  			Expect(sess.Err).To(gbytes.Say(fmt.Sprintf("BAD_REQUEST -- error applying config update to existing channel 'systemchannel': consensus metadata update for channel config update is invalid: verifying tls client cert with serial number %d: x509: certificate signed by unknown authority", client.TLSCert.SerialNumber)))
   449  		})
   450  	})
   451  
   452  	When("the orderer certificates are all rotated", func() {
   453  		It("is possible to rotate certificate by adding & removing cert in single config", func() {
   454  			layout := nwo.MultiNodeEtcdRaft()
   455  			network = nwo.New(layout, testDir, client, StartPort(), components)
   456  			network.GenerateConfigTree()
   457  			network.Bootstrap()
   458  
   459  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   460  			orderers := []*nwo.Orderer{o1, o2, o3}
   461  			peer = network.Peer("Org1", "peer0")
   462  
   463  			By("Launching the orderers")
   464  			for _, o := range orderers {
   465  				runner := network.OrdererRunner(o)
   466  				ordererRunners = append(ordererRunners, runner)
   467  				process := ifrit.Invoke(runner)
   468  				ordererProcesses = append(ordererProcesses, process)
   469  			}
   470  
   471  			for _, ordererProc := range ordererProcesses {
   472  				Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   473  			}
   474  
   475  			By("Finding leader")
   476  			leader := findLeader(ordererRunners)
   477  			leaderIndex := leader - 1
   478  			blockSeq := 0
   479  
   480  			By("Checking that all orderers are online")
   481  			assertBlockReception(map[string]int{
   482  				"systemchannel": blockSeq,
   483  			}, orderers, peer, network)
   484  
   485  			By("Preparing new certificates for the orderer nodes")
   486  			extendNetwork(network)
   487  			certificateRotations := refreshOrdererPEMs(network)
   488  
   489  			swap := func(o *nwo.Orderer, certificate []byte, c etcdraft.Consenter) {
   490  				updateEtcdRaftMetadata(network, peer, o, network.SystemChannel.Name, func(metadata *etcdraft.ConfigMetadata) {
   491  					var newConsenters []*etcdraft.Consenter
   492  					for _, consenter := range metadata.Consenters {
   493  						if bytes.Equal(consenter.ClientTlsCert, certificate) || bytes.Equal(consenter.ServerTlsCert, certificate) {
   494  							continue
   495  						}
   496  						newConsenters = append(newConsenters, consenter)
   497  					}
   498  					newConsenters = append(newConsenters, &c)
   499  
   500  					metadata.Consenters = newConsenters
   501  				})
   502  				blockSeq++
   503  			}
   504  
   505  			rotate := func(target int) {
   506  				// submit a config tx to rotate the cert of an orderer.
   507  				// The orderer being rotated is going to be unavailable
   508  				// eventually, therefore submitter of tx is different
   509  				// from the target, so the configuration can be reliably
   510  				// checked.
   511  				submitter := (target + 1) % 3
   512  				rotation := certificateRotations[target]
   513  				targetOrderer := network.Orderers[target]
   514  				remainder := func() []*nwo.Orderer {
   515  					var ret []*nwo.Orderer
   516  					for i, o := range network.Orderers {
   517  						if i == target {
   518  							continue
   519  						}
   520  						ret = append(ret, o)
   521  					}
   522  					return ret
   523  				}()
   524  				submitterOrderer := network.Orderers[submitter]
   525  				port := network.OrdererPort(targetOrderer, nwo.ClusterPort)
   526  
   527  				fmt.Fprintf(GinkgoWriter, "Rotating certificate of orderer node %d\n", target+1)
   528  				swap(submitterOrderer, rotation.oldCert, etcdraft.Consenter{
   529  					ServerTlsCert: rotation.newCert,
   530  					ClientTlsCert: rotation.newCert,
   531  					Host:          "127.0.0.1",
   532  					Port:          uint32(port),
   533  				})
   534  
   535  				By("Waiting for all orderers to sync")
   536  				assertBlockReception(map[string]int{
   537  					"systemchannel": blockSeq,
   538  				}, remainder, peer, network)
   539  
   540  				By("Waiting for rotated node to be unavailable")
   541  				c := commands.ChannelFetch{
   542  					ChannelID:  network.SystemChannel.Name,
   543  					Block:      "newest",
   544  					OutputFile: "/dev/null",
   545  					Orderer:    network.OrdererAddress(targetOrderer, nwo.ClusterPort),
   546  				}
   547  				Eventually(func() string {
   548  					sess, err := network.OrdererAdminSession(targetOrderer, peer, c)
   549  					Expect(err).NotTo(HaveOccurred())
   550  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit())
   551  					if sess.ExitCode() != 0 {
   552  						return fmt.Sprintf("exit code is %d: %s", sess.ExitCode(), string(sess.Err.Contents()))
   553  					}
   554  					sessErr := string(sess.Err.Contents())
   555  					expected := fmt.Sprintf("Received block: %d", blockSeq)
   556  					if strings.Contains(sessErr, expected) {
   557  						return ""
   558  					}
   559  					return sessErr
   560  				}, network.EventuallyTimeout, time.Second).ShouldNot(BeEmpty())
   561  
   562  				By("Killing the orderer")
   563  				ordererProcesses[target].Signal(syscall.SIGTERM)
   564  				Eventually(ordererProcesses[target].Wait(), network.EventuallyTimeout).Should(Receive())
   565  
   566  				By("Starting the orderer again")
   567  				ordererRunner := network.OrdererRunner(targetOrderer)
   568  				ordererRunners = append(ordererRunners, ordererRunner)
   569  				ordererProcesses[target] = ifrit.Invoke(ordererRunner)
   570  				Eventually(ordererProcesses[target].Ready(), network.EventuallyTimeout).Should(BeClosed())
   571  
   572  				By("And waiting for it to stabilize")
   573  				assertBlockReception(map[string]int{
   574  					"systemchannel": blockSeq,
   575  				}, orderers, peer, network)
   576  			}
   577  
   578  			By(fmt.Sprintf("Rotating cert on leader %d", leader))
   579  			rotate(leaderIndex)
   580  
   581  			By("Rotating certificates of other orderer nodes")
   582  			for i := range certificateRotations {
   583  				if i != leaderIndex {
   584  					rotate(i)
   585  				}
   586  			}
   587  		})
   588  
   589  		It("is still possible to onboard new orderers", func() {
   590  			// In this test, we have 3 OSNs and we rotate their TLS certificates one by one,
   591  			// by adding the future certificate to the channel, killing the OSN to make it
   592  			// grab the new certificate, and then removing the old certificate from the channel.
   593  
   594  			// After we completely rotate all the certificates, we put the last config block
   595  			// of the system channel into the file system of orderer4, and then launch it,
   596  			// and ensure it onboards and pulls channels testchannel only, and not testchannel2
   597  			// which it is not part of.
   598  
   599  			// Consenter i after its certificate is rotated is denoted as consenter i'
   600  			// The blocks of channels contain the following updates:
   601  			//    | system channel height | testchannel  height  | update description
   602  			// ------------------------------------------------------------------------
   603  			// 0  |            2          |         1            | adding consenter 1'
   604  			// 1  |            3          |         2            | removing consenter 1
   605  			// 2  |            4          |         3            | adding consenter 2'
   606  			// 3  |            5          |         4            | removing consenter 2
   607  			// 4  |            6          |         5            | adding consenter 3'
   608  			// 5  |            7          |         6            | removing consenter 3
   609  			// 6  |            8          |         6            | creating channel testchannel2
   610  			// 7  |            9          |         6            | creating channel testchannel3
   611  			// 8  |            10         |         7            | adding consenter 4
   612  
   613  			layout := nwo.MultiNodeEtcdRaft()
   614  			layout.Channels = append(layout.Channels, &nwo.Channel{
   615  				Name:    "testchannel2",
   616  				Profile: "TwoOrgsChannel",
   617  			}, &nwo.Channel{
   618  				Name:    "testchannel3",
   619  				Profile: "TwoOrgsChannel",
   620  			})
   621  
   622  			network = nwo.New(layout, testDir, client, StartPort(), components)
   623  			network.GenerateConfigTree()
   624  			network.Bootstrap()
   625  
   626  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   627  			orderers := []*nwo.Orderer{o1, o2, o3}
   628  			peer = network.Peer("Org1", "peer0")
   629  
   630  			By("Launching the orderers")
   631  			for _, o := range orderers {
   632  				runner := network.OrdererRunner(o)
   633  				ordererRunners = append(ordererRunners, runner)
   634  				process := ifrit.Invoke(runner)
   635  				ordererProcesses = append(ordererProcesses, process)
   636  			}
   637  
   638  			for _, ordererProc := range ordererProcesses {
   639  				Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   640  			}
   641  
   642  			By("Checking that all orderers are online")
   643  			assertBlockReception(map[string]int{
   644  				"systemchannel": 0,
   645  			}, orderers, peer, network)
   646  
   647  			By("Creating a channel and checking that all orderers got the channel creation")
   648  			network.CreateChannel("testchannel", network.Orderers[0], peer)
   649  			assertBlockReception(map[string]int{
   650  				"systemchannel": 1,
   651  				"testchannel":   0,
   652  			}, orderers, peer, network)
   653  
   654  			By("Preparing new certificates for the orderer nodes")
   655  			extendNetwork(network)
   656  			certificateRotations := refreshOrdererPEMs(network)
   657  
   658  			expectedBlockHeightsPerChannel := []map[string]int{
   659  				{"systemchannel": 2, "testchannel": 1},
   660  				{"systemchannel": 3, "testchannel": 2},
   661  				{"systemchannel": 4, "testchannel": 3},
   662  				{"systemchannel": 5, "testchannel": 4},
   663  				{"systemchannel": 6, "testchannel": 5},
   664  				{"systemchannel": 7, "testchannel": 6},
   665  			}
   666  
   667  			for i, rotation := range certificateRotations {
   668  				o := network.Orderers[i]
   669  				port := network.OrdererPort(o, nwo.ClusterPort)
   670  
   671  				By(fmt.Sprintf("Adding the future certificate of orderer node %d", i))
   672  				for _, channelName := range []string{"systemchannel", "testchannel"} {
   673  					addConsenter(network, peer, o, channelName, etcdraft.Consenter{
   674  						ServerTlsCert: rotation.newCert,
   675  						ClientTlsCert: rotation.newCert,
   676  						Host:          "127.0.0.1",
   677  						Port:          uint32(port),
   678  					})
   679  				}
   680  
   681  				By("Waiting for all orderers to sync")
   682  				assertBlockReception(expectedBlockHeightsPerChannel[i*2], orderers, peer, network)
   683  
   684  				By("Killing the orderer")
   685  				ordererProcesses[i].Signal(syscall.SIGTERM)
   686  				Eventually(ordererProcesses[i].Wait(), network.EventuallyTimeout).Should(Receive())
   687  
   688  				By("Starting the orderer again")
   689  				ordererRunner := network.OrdererRunner(orderers[i])
   690  				ordererRunners = append(ordererRunners, ordererRunner)
   691  				ordererProcesses[i] = ifrit.Invoke(ordererRunner)
   692  				Eventually(ordererProcesses[i].Ready(), network.EventuallyTimeout).Should(BeClosed())
   693  
   694  				By("And waiting for it to stabilize")
   695  				assertBlockReception(expectedBlockHeightsPerChannel[i*2], orderers, peer, network)
   696  
   697  				By("Removing the previous certificate of the old orderer")
   698  				for _, channelName := range []string{"systemchannel", "testchannel"} {
   699  					removeConsenter(network, peer, network.Orderers[(i+1)%len(network.Orderers)], channelName, rotation.oldCert)
   700  				}
   701  
   702  				By("Waiting for all orderers to sync")
   703  				assertBlockReception(expectedBlockHeightsPerChannel[i*2+1], orderers, peer, network)
   704  			}
   705  
   706  			By("Creating testchannel2")
   707  			network.CreateChannel("testchannel2", network.Orderers[0], peer)
   708  			assertBlockReception(map[string]int{
   709  				"systemchannel": 8,
   710  			}, orderers, peer, network)
   711  
   712  			By("Creating testchannel3")
   713  			network.CreateChannel("testchannel3", network.Orderers[0], peer)
   714  			assertBlockReception(map[string]int{
   715  				"systemchannel": 9,
   716  			}, orderers, peer, network)
   717  
   718  			o4 := &nwo.Orderer{
   719  				Name:         "orderer4",
   720  				Organization: "OrdererOrg",
   721  			}
   722  
   723  			By("Configuring orderer4 in the network")
   724  			ports := nwo.Ports{}
   725  			for _, portName := range nwo.OrdererPortNames() {
   726  				ports[portName] = network.ReservePort()
   727  			}
   728  			network.PortsByOrdererID[o4.ID()] = ports
   729  
   730  			network.Orderers = append(network.Orderers, o4)
   731  			network.GenerateOrdererConfig(network.Orderer("orderer4"))
   732  
   733  			By("Adding orderer4 to the channels")
   734  			orderer4CertificatePath := filepath.Join(network.OrdererLocalTLSDir(o4), "server.crt")
   735  			orderer4Certificate, err := ioutil.ReadFile(orderer4CertificatePath)
   736  			Expect(err).NotTo(HaveOccurred())
   737  			for _, channel := range []string{"systemchannel", "testchannel"} {
   738  				addConsenter(network, peer, o1, channel, etcdraft.Consenter{
   739  					ServerTlsCert: orderer4Certificate,
   740  					ClientTlsCert: orderer4Certificate,
   741  					Host:          "127.0.0.1",
   742  					Port:          uint32(network.OrdererPort(o4, nwo.ClusterPort)),
   743  				})
   744  			}
   745  
   746  			By("Ensuring all orderers know about orderer4's addition")
   747  			assertBlockReception(map[string]int{
   748  				"systemchannel": 10,
   749  				"testchannel":   7,
   750  			}, orderers, peer, network)
   751  
   752  			By("Broadcasting envelope to testchannel")
   753  			env := CreateBroadcastEnvelope(network, peer, "testchannel", []byte("hello"))
   754  			resp, err := nwo.Broadcast(network, o1, env)
   755  			Expect(err).NotTo(HaveOccurred())
   756  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   757  
   758  			assertBlockReception(map[string]int{
   759  				"testchannel": 8,
   760  			}, orderers, peer, network)
   761  
   762  			By("Corrupting the readers policy of testchannel3")
   763  			revokeReaderAccess(network, "testchannel3", o3, peer)
   764  
   765  			// Get the last config block of the system channel
   766  			configBlock := nwo.GetConfigBlock(network, peer, o1, "systemchannel")
   767  			// Plant it in the file system of orderer4, the new node to be onboarded.
   768  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
   769  			Expect(err).NotTo(HaveOccurred())
   770  
   771  			By("Launching orderer4")
   772  			orderers = append(orderers, o4)
   773  			orderer4Runner := network.OrdererRunner(o4)
   774  			ordererRunners = append(ordererRunners, orderer4Runner)
   775  			// Spawn orderer4's process
   776  			o4process := ifrit.Invoke(orderer4Runner)
   777  			Eventually(o4process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   778  			ordererProcesses = append(ordererProcesses, o4process)
   779  
   780  			By("And waiting for it to sync with the rest of the orderers")
   781  			assertBlockReception(map[string]int{
   782  				"systemchannel": 10,
   783  				"testchannel":   8,
   784  			}, orderers, peer, network)
   785  
   786  			By("Ensuring orderer4 doesn't serve testchannel2 and testchannel3")
   787  			env = CreateBroadcastEnvelope(network, peer, "testchannel2", []byte("hello"))
   788  			resp, err = nwo.Broadcast(network, o4, env)
   789  			Expect(err).NotTo(HaveOccurred())
   790  			Expect(resp.Status).To(Equal(common.Status_SERVICE_UNAVAILABLE))
   791  
   792  			env = CreateBroadcastEnvelope(network, peer, "testchannel3", []byte("hello"))
   793  			resp, err = nwo.Broadcast(network, o4, env)
   794  			Expect(err).NotTo(HaveOccurred())
   795  			Expect(resp.Status).To(Equal(common.Status_SERVICE_UNAVAILABLE))
   796  
   797  			belongRegex := `\QI do not belong to channel testchannel2 or am forbidden pulling it (not in the channel), skipping chain retrieval\E`
   798  			forbiddenRegex := `\QI do not belong to channel testchannel3 or am forbidden pulling it (forbidden pulling the channel), skipping chain retrieval\E`
   799  
   800  			Expect(orderer4Runner.Err()).To(gbytes.Say(belongRegex + "|" + forbiddenRegex))
   801  			Expect(orderer4Runner.Err()).To(gbytes.Say(belongRegex + "|" + forbiddenRegex))
   802  
   803  			By("Adding orderer4 to testchannel2")
   804  			addConsenter(network, peer, o1, "testchannel2", etcdraft.Consenter{
   805  				ServerTlsCert: orderer4Certificate,
   806  				ClientTlsCert: orderer4Certificate,
   807  				Host:          "127.0.0.1",
   808  				Port:          uint32(network.OrdererPort(o4, nwo.ClusterPort)),
   809  			})
   810  
   811  			By("Waiting for orderer4 and to replicate testchannel2")
   812  			assertBlockReception(map[string]int{
   813  				"testchannel2": 1,
   814  			}, []*nwo.Orderer{o4}, peer, network)
   815  
   816  			By("Ensuring orderer4 doesn't have any errors in the logs")
   817  			Consistently(orderer4Runner.Err()).ShouldNot(gbytes.Say("ERRO"))
   818  
   819  			By("Submitting a transaction through orderer4")
   820  			env = CreateBroadcastEnvelope(network, peer, "testchannel2", []byte("hello"))
   821  			resp, err = nwo.Broadcast(network, o4, env)
   822  			Expect(err).NotTo(HaveOccurred())
   823  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   824  
   825  			By("And ensuring it is propagated amongst all orderers")
   826  			assertBlockReception(map[string]int{
   827  				"testchannel2": 2,
   828  			}, orderers, peer, network)
   829  		})
   830  	})
   831  
   832  	When("an orderer channel is created with a subset of nodes", func() {
   833  		It("is still possible to onboard a new orderer to the channel", func() {
   834  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   835  			network.Profiles = append(network.Profiles, &nwo.Profile{
   836  				Name:          "myprofile",
   837  				Consortium:    "SampleConsortium",
   838  				Orderers:      []string{"orderer1"},
   839  				Organizations: []string{"Org1"},
   840  			})
   841  			network.Channels = append(network.Channels, &nwo.Channel{
   842  				Name:        "mychannel",
   843  				Profile:     "myprofile",
   844  				BaseProfile: "SampleDevModeEtcdRaft",
   845  			})
   846  
   847  			network.GenerateConfigTree()
   848  			network.Bootstrap()
   849  
   850  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   851  			orderers := []*nwo.Orderer{o1, o2, o3}
   852  			peer = network.Peer("Org1", "peer0")
   853  
   854  			By("Launching the orderers")
   855  			for _, o := range orderers {
   856  				runner := network.OrdererRunner(o)
   857  				ordererRunners = append(ordererRunners, runner)
   858  				process := ifrit.Invoke(runner)
   859  				ordererProcesses = append(ordererProcesses, process)
   860  			}
   861  
   862  			for _, ordererProc := range ordererProcesses {
   863  				Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   864  			}
   865  
   866  			By("Waiting for the system channel to be available")
   867  			assertBlockReception(map[string]int{
   868  				"systemchannel": 0,
   869  			}, orderers, peer, network)
   870  
   871  			By("Creating a channel with a subset of orderers")
   872  			network.CreateChannel("mychannel", o1, peer, peer, o1)
   873  
   874  			By("Waiting for the channel to be available")
   875  			assertBlockReception(map[string]int{
   876  				"mychannel": 0,
   877  			}, []*nwo.Orderer{o1}, peer, network)
   878  
   879  			By("Ensuring only orderer1 services the channel")
   880  			ensureEvicted(o2, peer, network, "mychannel")
   881  			ensureEvicted(o3, peer, network, "mychannel")
   882  
   883  			By("Adding orderer2 to the channel")
   884  			ordererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(o2), "server.crt")
   885  			ordererCertificate, err := ioutil.ReadFile(ordererCertificatePath)
   886  			Expect(err).NotTo(HaveOccurred())
   887  
   888  			addConsenter(network, peer, o1, "mychannel", etcdraft.Consenter{
   889  				ServerTlsCert: ordererCertificate,
   890  				ClientTlsCert: ordererCertificate,
   891  				Host:          "127.0.0.1",
   892  				Port:          uint32(network.OrdererPort(o2, nwo.ClusterPort)),
   893  			})
   894  
   895  			By("Waiting for orderer2 to join the channel")
   896  			assertBlockReception(map[string]int{
   897  				"mychannel": 1,
   898  			}, []*nwo.Orderer{o1, o2}, peer, network)
   899  
   900  			By("Adding orderer3 to the channel")
   901  			ordererCertificatePath = filepath.Join(network.OrdererLocalTLSDir(o3), "server.crt")
   902  			ordererCertificate, err = ioutil.ReadFile(ordererCertificatePath)
   903  			Expect(err).NotTo(HaveOccurred())
   904  			addConsenter(network, peer, o1, "mychannel", etcdraft.Consenter{
   905  				ServerTlsCert: ordererCertificate,
   906  				ClientTlsCert: ordererCertificate,
   907  				Host:          "127.0.0.1",
   908  				Port:          uint32(network.OrdererPort(o3, nwo.ClusterPort)),
   909  			})
   910  
   911  			By("Waiting for orderer3 to join the channel")
   912  			assertBlockReception(map[string]int{
   913  				"mychannel": 2,
   914  			}, orderers, peer, network)
   915  		})
   916  	})
   917  
   918  	When("orderer cluster is not healthy", func() {
   919  		var (
   920  			o1, o2 *nwo.Orderer
   921  		)
   922  
   923  		BeforeEach(func() {
   924  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   925  			network.GenerateConfigTree()
   926  			network.Bootstrap()
   927  
   928  			o1, o2 = network.Orderer("orderer1"), network.Orderer("orderer2")
   929  			orderers := []*nwo.Orderer{o1, o2}
   930  			By("Launching the orderers")
   931  			for _, o := range orderers {
   932  				runner := network.OrdererRunner(o)
   933  				ordererRunners = append(ordererRunners, runner)
   934  				process := ifrit.Invoke(runner)
   935  				ordererProcesses = append(ordererProcesses, process)
   936  			}
   937  
   938  			for _, ordererProc := range ordererProcesses {
   939  				Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   940  			}
   941  		})
   942  
   943  		AfterEach(func() {
   944  			for _, ordererInstance := range ordererProcesses {
   945  				ordererInstance.Signal(syscall.SIGTERM)
   946  				Eventually(ordererInstance.Wait(), network.EventuallyTimeout).Should(Receive())
   947  			}
   948  		})
   949  
   950  		It("refuses to reconfig if it results in quorum loss", func() {
   951  			By("Waiting for them to elect a leader")
   952  			findLeader(ordererRunners)
   953  
   954  			extendNetwork(network)
   955  			certificatesOfOrderers := refreshOrdererPEMs(network)
   956  
   957  			By("Removing alive node from 2/3 cluster")
   958  			peer := network.Peer("Org1", "peer0")
   959  			current, updated := consenterRemover(network, peer, o2, network.SystemChannel.Name, certificatesOfOrderers[1].oldCert)
   960  			Eventually(func() []byte {
   961  				sess := nwo.UpdateOrdererConfigSession(network, o2, network.SystemChannel.Name, current, updated, peer, o2)
   962  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   963  				return sess.Err.Contents()
   964  			}, network.EventuallyTimeout).Should(ContainSubstring("2 out of 3 nodes are alive, configuration will result in quorum loss"))
   965  
   966  			By("Adding node to 2/3 cluster")
   967  			current, updated = consenterAdder(
   968  				network,
   969  				peer,
   970  				o2,
   971  				network.SystemChannel.Name,
   972  				etcdraft.Consenter{
   973  					ServerTlsCert: certificatesOfOrderers[0].newCert,
   974  					ClientTlsCert: certificatesOfOrderers[0].newCert,
   975  					Host:          "127.0.0.1",
   976  					Port:          uint32(network.OrdererPort(o1, nwo.ListenPort)),
   977  				},
   978  			)
   979  			sess := nwo.UpdateOrdererConfigSession(network, o2, network.SystemChannel.Name, current, updated, peer, o2)
   980  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   981  			Expect(string(sess.Err.Contents())).To(ContainSubstring("2 out of 3 nodes are alive, configuration will result in quorum loss"))
   982  		})
   983  	})
   984  
   985  	When("an orderer node is evicted", func() {
   986  		BeforeEach(func() {
   987  			ordererRunners = nil
   988  			ordererProcesses = nil
   989  
   990  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   991  			network.GenerateConfigTree()
   992  			network.Bootstrap()
   993  
   994  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   995  			orderers := []*nwo.Orderer{o1, o2, o3}
   996  			peer = network.Peer("Org1", "peer0")
   997  
   998  			By("Launching the orderers")
   999  			for _, o := range orderers {
  1000  				runner := network.OrdererRunner(o)
  1001  				ordererRunners = append(ordererRunners, runner)
  1002  				process := ifrit.Invoke(runner)
  1003  				ordererProcesses = append(ordererProcesses, process)
  1004  			}
  1005  
  1006  			for _, ordererProc := range ordererProcesses {
  1007  				Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
  1008  			}
  1009  		})
  1010  
  1011  		AfterEach(func() {
  1012  			for _, ordererInstance := range ordererProcesses {
  1013  				ordererInstance.Signal(syscall.SIGTERM)
  1014  				Eventually(ordererInstance.Wait(), network.EventuallyTimeout).Should(Receive())
  1015  			}
  1016  		})
  1017  
  1018  		It("doesn't complain and does it obediently", func() {
  1019  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
  1020  			orderers := []*nwo.Orderer{o1, o2, o3}
  1021  
  1022  			By("Waiting for them to elect a leader")
  1023  			firstEvictedNode := findLeader(ordererRunners) - 1
  1024  
  1025  			By("Removing the leader from 3-node channel")
  1026  			server1CertBytes, err := ioutil.ReadFile(filepath.Join(network.OrdererLocalTLSDir(orderers[firstEvictedNode]), "server.crt"))
  1027  			Expect(err).To(Not(HaveOccurred()))
  1028  
  1029  			removeConsenter(network, peer, network.Orderers[(firstEvictedNode+1)%3], "systemchannel", server1CertBytes)
  1030  
  1031  			var survivedOrdererRunners []*ginkgomon.Runner
  1032  			for i := range orderers {
  1033  				if i == firstEvictedNode {
  1034  					continue
  1035  				}
  1036  
  1037  				survivedOrdererRunners = append(survivedOrdererRunners, ordererRunners[i])
  1038  			}
  1039  
  1040  			secondEvictedNode := findLeader(survivedOrdererRunners) - 1
  1041  
  1042  			var surviver int
  1043  			for i := range orderers {
  1044  				if i != firstEvictedNode && i != secondEvictedNode {
  1045  					surviver = i
  1046  					break
  1047  				}
  1048  			}
  1049  
  1050  			const stopMsg = "Raft node stopped channel=systemchannel"
  1051  			fmt.Fprintln(GinkgoWriter, "Ensuring the evicted orderer stops rafting on channel systemchannel")
  1052  			Eventually(ordererRunners[firstEvictedNode].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say(stopMsg))
  1053  
  1054  			By("Ensuring the evicted orderer now doesn't serve clients")
  1055  			ensureEvicted(orderers[firstEvictedNode], peer, network, "systemchannel")
  1056  
  1057  			By("Removing the leader from 2-node channel")
  1058  			server2CertBytes, err := ioutil.ReadFile(filepath.Join(network.OrdererLocalTLSDir(orderers[secondEvictedNode]), "server.crt"))
  1059  			Expect(err).To(Not(HaveOccurred()))
  1060  
  1061  			removeConsenter(network, peer, orderers[surviver], "systemchannel", server2CertBytes)
  1062  			findLeader([]*ginkgomon.Runner{ordererRunners[surviver]})
  1063  
  1064  			fmt.Fprintln(GinkgoWriter, "Ensuring the other orderer detect the eviction of the node on channel systemchannel")
  1065  			Eventually(ordererRunners[secondEvictedNode].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say(stopMsg))
  1066  
  1067  			By("Ensuring the evicted orderer now doesn't serve clients")
  1068  			ensureEvicted(orderers[secondEvictedNode], peer, network, "systemchannel")
  1069  
  1070  			By("Re-adding first evicted orderer")
  1071  			addConsenter(network, peer, network.Orderers[surviver], "systemchannel", etcdraft.Consenter{
  1072  				Host:          "127.0.0.1",
  1073  				Port:          uint32(network.OrdererPort(orderers[firstEvictedNode], nwo.ClusterPort)),
  1074  				ClientTlsCert: server1CertBytes,
  1075  				ServerTlsCert: server1CertBytes,
  1076  			})
  1077  
  1078  			By("Ensuring re-added orderer starts serving system channel")
  1079  			assertBlockReception(map[string]int{
  1080  				"systemchannel": 3,
  1081  			}, []*nwo.Orderer{orderers[firstEvictedNode]}, peer, network)
  1082  
  1083  			env := CreateBroadcastEnvelope(network, orderers[secondEvictedNode], network.SystemChannel.Name, []byte("foo"))
  1084  			resp, err := nwo.Broadcast(network, orderers[surviver], env)
  1085  			Expect(err).NotTo(HaveOccurred())
  1086  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
  1087  		})
  1088  
  1089  		It("notices it even if it is down at the time of its eviction", func() {
  1090  			o1 := network.Orderer("orderer1")
  1091  			o2 := network.Orderer("orderer2")
  1092  			o3 := network.Orderer("orderer3")
  1093  
  1094  			orderers := []*nwo.Orderer{o1, o2, o3}
  1095  
  1096  			By("Waiting for them to elect a leader")
  1097  			findLeader(ordererRunners)
  1098  
  1099  			By("Creating a channel")
  1100  			network.CreateChannel("testchannel", o1, peer)
  1101  
  1102  			assertBlockReception(map[string]int{
  1103  				"testchannel":   0,
  1104  				"systemchannel": 1,
  1105  			}, []*nwo.Orderer{o1, o2, o3}, peer, network)
  1106  
  1107  			By("Killing the orderer")
  1108  			ordererProcesses[0].Signal(syscall.SIGTERM)
  1109  			Eventually(ordererProcesses[0].Wait(), network.EventuallyTimeout).Should(Receive())
  1110  
  1111  			// We need to wait for stabilization, as we might have killed the leader OSN.
  1112  			By("Waiting for the channel to stabilize after killing the orderer")
  1113  			assertBlockReception(map[string]int{
  1114  				"testchannel":   0,
  1115  				"systemchannel": 1,
  1116  			}, []*nwo.Orderer{o2, o3}, peer, network)
  1117  
  1118  			By("Removing the first orderer from an application channel")
  1119  			extendNetwork(network)
  1120  			certificatesOfOrderers := refreshOrdererPEMs(network)
  1121  			removeConsenter(network, peer, o2, "testchannel", certificatesOfOrderers[0].oldCert)
  1122  
  1123  			certPath := certificatesOfOrderers[0].dstFile
  1124  			keyFile := strings.Replace(certPath, "server.crt", "server.key", -1)
  1125  			err := ioutil.WriteFile(certPath, certificatesOfOrderers[0].oldCert, 0644)
  1126  			Expect(err).To(Not(HaveOccurred()))
  1127  			err = ioutil.WriteFile(keyFile, certificatesOfOrderers[0].oldKey, 0644)
  1128  			Expect(err).To(Not(HaveOccurred()))
  1129  
  1130  			By("Starting the orderer again")
  1131  			ordererRunner := network.OrdererRunner(orderers[0])
  1132  			ordererRunners[0] = ordererRunner
  1133  			ordererProcesses[0] = ifrit.Invoke(ordererRunner)
  1134  			Eventually(ordererProcesses[0].Ready(), network.EventuallyTimeout).Should(BeClosed())
  1135  
  1136  			By("Ensuring the remaining OSNs reject authentication")
  1137  			Eventually(ordererRunners[1].Err(), time.Minute, time.Second).Should(gbytes.Say("certificate extracted from TLS connection isn't authorized"))
  1138  			Eventually(ordererRunners[2].Err(), time.Minute, time.Second).Should(gbytes.Say("certificate extracted from TLS connection isn't authorized"))
  1139  
  1140  			By("Ensuring it detects its eviction")
  1141  			evictionDetection := gbytes.Say(`Detected our own eviction from the channel in block \[1\] channel=testchannel`)
  1142  			Eventually(ordererRunner.Err(), time.Minute, time.Second).Should(evictionDetection)
  1143  
  1144  			By("Ensuring all blocks are pulled up to the block that evicts the OSN")
  1145  			Eventually(ordererRunner.Err(), time.Minute, time.Second).Should(gbytes.Say("Periodic check is stopping. channel=testchannel"))
  1146  			Eventually(ordererRunner.Err(), time.Minute, time.Second).Should(gbytes.Say("Pulled all blocks up to eviction block. channel=testchannel"))
  1147  
  1148  			By("Killing the evicted orderer")
  1149  			ordererProcesses[0].Signal(syscall.SIGTERM)
  1150  			Eventually(ordererProcesses[0].Wait(), network.EventuallyTimeout).Should(Receive())
  1151  
  1152  			By("Starting the evicted orderer again")
  1153  			ordererRunner = network.OrdererRunner(orderers[0])
  1154  			ordererRunners[0] = ordererRunner
  1155  			ordererProcesses[0] = ifrit.Invoke(ordererRunner)
  1156  			Eventually(ordererProcesses[0].Ready(), network.EventuallyTimeout).Should(BeClosed())
  1157  
  1158  			By("Ensuring the evicted orderer starts up marked the channel is inactive")
  1159  			Eventually(ordererRunner.Err(), time.Minute, time.Second).Should(gbytes.Say("Found 1 inactive chains"))
  1160  
  1161  			iDoNotBelong := "I do not belong to channel testchannel or am forbidden pulling it"
  1162  			Eventually(ordererRunner.Err(), time.Minute, time.Second).Should(gbytes.Say(iDoNotBelong))
  1163  
  1164  			By("Adding the evicted orderer back to the application channel")
  1165  			addConsenter(network, peer, o2, "testchannel", etcdraft.Consenter{
  1166  				ServerTlsCert: certificatesOfOrderers[0].oldCert,
  1167  				ClientTlsCert: certificatesOfOrderers[0].oldCert,
  1168  				Host:          "127.0.0.1",
  1169  				Port:          uint32(network.OrdererPort(orderers[0], nwo.ClusterPort)),
  1170  			})
  1171  
  1172  			By("Ensuring the re-added orderer joins the Raft cluster")
  1173  			findLeader([]*ginkgomon.Runner{ordererRunner})
  1174  		})
  1175  	})
  1176  
  1177  	When("an orderer node is joined", func() {
  1178  		It("isn't influenced by outdated orderers", func() {
  1179  			// This test checks that if a lagged is not aware of newly added nodes,
  1180  			// among which leader is present, it eventually pulls config block from
  1181  			// the orderer it knows, gets the certificates from it and participate
  1182  			// in consensus again.
  1183  			//
  1184  			// Steps:
  1185  			// Initial nodes in cluster: <1, 2, 3, 4>
  1186  			// - start <1, 2, 3>
  1187  			// - add <5, 6, 7>, start <5, 6, 7>
  1188  			// - kill <1>
  1189  			// - submit a tx, so that Raft index on <1> is behind <5, 6, 7> and <2, 3>
  1190  			// - kill <2, 3>
  1191  			// - start <1> and <4>. Since <1> is behind <5, 6, 7>, leader is certainly
  1192  			//   going to be elected from <5, 6, 7>
  1193  			// - assert that even <4> is not aware of leader, it can pull config block
  1194  			//   from <1>, and start participating in consensus.
  1195  
  1196  			orderers := make([]*nwo.Orderer, 7)
  1197  			ordererRunners = make([]*ginkgomon.Runner, 7)
  1198  			ordererProcesses = make([]ifrit.Process, 7)
  1199  
  1200  			for i := range orderers {
  1201  				orderers[i] = &nwo.Orderer{
  1202  					Name:         fmt.Sprintf("orderer%d", i+1),
  1203  					Organization: "OrdererOrg",
  1204  				}
  1205  			}
  1206  
  1207  			layout := nwo.MultiNodeEtcdRaft()
  1208  			layout.Orderers = orderers[:4]
  1209  			layout.Profiles[0].Orderers = []string{"orderer1", "orderer2", "orderer3", "orderer4"}
  1210  
  1211  			network = nwo.New(layout, testDir, client, StartPort(), components)
  1212  			network.GenerateConfigTree()
  1213  			network.Bootstrap()
  1214  
  1215  			peer = network.Peer("Org1", "peer0")
  1216  
  1217  			launch := func(i int) {
  1218  				runner := network.OrdererRunner(orderers[i])
  1219  				ordererRunners[i] = runner
  1220  				process := ifrit.Invoke(runner)
  1221  				Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
  1222  				ordererProcesses[i] = process
  1223  			}
  1224  
  1225  			By("Launching 3 out of 4 orderers")
  1226  			for i := range orderers[:3] {
  1227  				launch(i)
  1228  			}
  1229  
  1230  			leader := findLeader(ordererRunners[:3])
  1231  
  1232  			By("Checking that all orderers are online")
  1233  			assertBlockReception(map[string]int{
  1234  				"systemchannel": 0,
  1235  			}, orderers[:3], peer, network)
  1236  
  1237  			By("Configuring orderer[5, 6, 7] in the network")
  1238  			extendNetwork(network)
  1239  
  1240  			for _, o := range orderers[4:7] {
  1241  				ports := nwo.Ports{}
  1242  				for _, portName := range nwo.OrdererPortNames() {
  1243  					ports[portName] = network.ReservePort()
  1244  				}
  1245  				network.PortsByOrdererID[o.ID()] = ports
  1246  
  1247  				network.Orderers = append(network.Orderers, o)
  1248  				network.GenerateOrdererConfig(o)
  1249  			}
  1250  
  1251  			// Backup previous system channel block
  1252  			genesisBootBlock, err := ioutil.ReadFile(filepath.Join(testDir, "systemchannel_block.pb"))
  1253  			Expect(err).NotTo(HaveOccurred())
  1254  			restoreBootBlock := func() {
  1255  				err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), genesisBootBlock, 0644)
  1256  				Expect(err).NotTo(HaveOccurred())
  1257  			}
  1258  
  1259  			blockSeq := 0 // there's only one block in channel - genesis
  1260  			for _, i := range []int{4, 5, 6} {
  1261  				By(fmt.Sprintf("Adding orderer%d", i+1))
  1262  				ordererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(orderers[i]), "server.crt")
  1263  				ordererCertificate, err := ioutil.ReadFile(ordererCertificatePath)
  1264  				Expect(err).NotTo(HaveOccurred())
  1265  
  1266  				addConsenter(network, peer, orderers[0], "systemchannel", etcdraft.Consenter{
  1267  					ServerTlsCert: ordererCertificate,
  1268  					ClientTlsCert: ordererCertificate,
  1269  					Host:          "127.0.0.1",
  1270  					Port:          uint32(network.OrdererPort(orderers[i], nwo.ClusterPort)),
  1271  				})
  1272  				blockSeq++
  1273  
  1274  				// Get the last config block of the system channel
  1275  				configBlock := nwo.GetConfigBlock(network, peer, orderers[0], "systemchannel")
  1276  				// Plant it in the file system of orderer, the new node to be onboarded.
  1277  				err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
  1278  				Expect(err).NotTo(HaveOccurred())
  1279  
  1280  				By(fmt.Sprintf("Launching orderer%d", i+1))
  1281  				launch(i)
  1282  
  1283  				By(fmt.Sprintf("Checking that orderer%d has onboarded the network", i+1))
  1284  				assertBlockReception(map[string]int{
  1285  					"systemchannel": blockSeq,
  1286  				}, []*nwo.Orderer{orderers[i]}, peer, network)
  1287  			}
  1288  
  1289  			Expect(findLeader(ordererRunners[4:])).To(Equal(leader))
  1290  
  1291  			// Later on, when we start [1, 4, 5, 6, 7], we want to make sure that leader
  1292  			// is elected from [5, 6, 7], who are unknown to [4]. So we can assert that
  1293  			// [4] suspects its own eviction, pulls block from [1], and join the cluster.
  1294  			// Otherwise, if [1] is elected, and all other nodes already knew it, [4] may
  1295  			// simply replicate missing blocks with Raft, instead of pulling from others
  1296  			// triggered by eviction suspector.
  1297  
  1298  			By("Killing orderer1")
  1299  			ordererProcesses[0].Signal(syscall.SIGTERM)
  1300  			Eventually(ordererProcesses[0].Wait(), network.EventuallyTimeout).Should(Receive())
  1301  
  1302  			By("Submitting another tx to increment Raft index on alive orderers")
  1303  			if leader == 1 {
  1304  				// if orderer1 was leader, we should expect a new leader being elected before going forward
  1305  				findLeader([]*ginkgomon.Runner{ordererRunners[4]})
  1306  			}
  1307  
  1308  			env := CreateBroadcastEnvelope(network, orderers[4], network.SystemChannel.Name, []byte("hello"))
  1309  			resp, err := nwo.Broadcast(network, orderers[4], env)
  1310  			Expect(err).NotTo(HaveOccurred())
  1311  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
  1312  			blockSeq++
  1313  
  1314  			assertBlockReception(map[string]int{
  1315  				"systemchannel": blockSeq,
  1316  			}, []*nwo.Orderer{orderers[1], orderers[2], orderers[4], orderers[5], orderers[6]}, peer, network) // alive orderers: 2, 3, 5, 6, 7
  1317  
  1318  			By("Killing orderer[2,3]")
  1319  			for _, i := range []int{1, 2} {
  1320  				ordererProcesses[i].Signal(syscall.SIGTERM)
  1321  				Eventually(ordererProcesses[i].Wait(), network.EventuallyTimeout).Should(Receive())
  1322  			}
  1323  
  1324  			By("Launching the orderer that was never started")
  1325  			restoreBootBlock()
  1326  			launch(3)
  1327  
  1328  			By("Launching orderer1")
  1329  			launch(0)
  1330  
  1331  			By("Waiting until it suspects its eviction from the channel")
  1332  			Eventually(ordererRunners[3].Err(), time.Minute, time.Second).Should(gbytes.Say("Suspecting our own eviction from the channel"))
  1333  
  1334  			By("Making sure 4/7 orderers form quorum and serve request")
  1335  			assertBlockReception(map[string]int{
  1336  				"systemchannel": blockSeq,
  1337  			}, []*nwo.Orderer{orderers[3], orderers[4], orderers[5], orderers[6]}, peer, network) // alive orderers: 4, 5, 6, 7
  1338  		})
  1339  	})
  1340  
  1341  	It("can create a channel that contains a subset of orderers in system channel", func() {
  1342  		config := nwo.BasicEtcdRaft()
  1343  		config.Orderers = []*nwo.Orderer{
  1344  			{Name: "orderer1", Organization: "OrdererOrg"},
  1345  			{Name: "orderer2", Organization: "OrdererOrg"},
  1346  			{Name: "orderer3", Organization: "OrdererOrg"},
  1347  		}
  1348  		config.Profiles = []*nwo.Profile{{
  1349  			Name:     "SampleDevModeEtcdRaft",
  1350  			Orderers: []string{"orderer1", "orderer2", "orderer3"},
  1351  		}, {
  1352  			Name:          "ThreeOrdererChannel",
  1353  			Consortium:    "SampleConsortium",
  1354  			Organizations: []string{"Org1", "Org2"},
  1355  			Orderers:      []string{"orderer1", "orderer2", "orderer3"},
  1356  		}, {
  1357  			Name:          "SingleOrdererChannel",
  1358  			Consortium:    "SampleConsortium",
  1359  			Organizations: []string{"Org1", "Org2"},
  1360  			Orderers:      []string{"orderer1"},
  1361  		}}
  1362  		config.Channels = []*nwo.Channel{
  1363  			{Name: "single-orderer-channel", Profile: "SingleOrdererChannel", BaseProfile: "SampleDevModeEtcdRaft"},
  1364  			{Name: "three-orderer-channel", Profile: "ThreeOrdererChannel"},
  1365  		}
  1366  
  1367  		network = nwo.New(config, testDir, client, StartPort(), components)
  1368  		o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
  1369  		orderers := []*nwo.Orderer{o1, o2, o3}
  1370  		peer = network.Peer("Org1", "peer0")
  1371  
  1372  		network.GenerateConfigTree()
  1373  		network.Bootstrap()
  1374  
  1375  		By("Launching the orderers")
  1376  		for _, o := range orderers {
  1377  			runner := network.OrdererRunner(o)
  1378  			ordererRunners = append(ordererRunners, runner)
  1379  			process := ifrit.Invoke(runner)
  1380  			ordererProcesses = append(ordererProcesses, process)
  1381  		}
  1382  
  1383  		for _, ordererProc := range ordererProcesses {
  1384  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
  1385  		}
  1386  
  1387  		By("Creating an application channel with a subset of orderers in system channel")
  1388  		additionalPeer := network.Peer("Org2", "peer0")
  1389  		network.CreateChannel("single-orderer-channel", network.Orderers[0], peer, additionalPeer, network.Orderers[0])
  1390  
  1391  		By("Creating another channel via the orderer that is in system channel but not app channel")
  1392  		network.CreateChannel("three-orderer-channel", network.Orderers[2], peer)
  1393  	})
  1394  
  1395  	It("can add a new orderer organization", func() {
  1396  		network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
  1397  		o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
  1398  		orderers := []*nwo.Orderer{o1, o2, o3}
  1399  
  1400  		network.GenerateConfigTree()
  1401  		network.Bootstrap()
  1402  
  1403  		By("Launching the orderers")
  1404  		for _, o := range orderers {
  1405  			runner := network.OrdererRunner(o)
  1406  			ordererRunners = append(ordererRunners, runner)
  1407  			process := ifrit.Invoke(runner)
  1408  			ordererProcesses = append(ordererProcesses, process)
  1409  		}
  1410  
  1411  		for _, ordererProc := range ordererProcesses {
  1412  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
  1413  		}
  1414  
  1415  		By("Waiting for system channel to be ready")
  1416  		findLeader(ordererRunners)
  1417  
  1418  		peer := network.Peer("Org1", "peer0")
  1419  		channel := "systemchannel"
  1420  
  1421  		config := nwo.GetConfig(network, peer, o1, channel)
  1422  		updatedConfig := proto.Clone(config).(*common.Config)
  1423  
  1424  		ordererOrg := updatedConfig.ChannelGroup.Groups["Orderer"].Groups["OrdererOrg"]
  1425  		mspConfig := &msp.MSPConfig{}
  1426  		proto.Unmarshal(ordererOrg.Values["MSP"].Value, mspConfig)
  1427  
  1428  		fabMSPConfig := &msp.FabricMSPConfig{}
  1429  		proto.Unmarshal(mspConfig.Config, fabMSPConfig)
  1430  
  1431  		fabMSPConfig.Name = "OrdererMSP2"
  1432  
  1433  		mspConfig.Config, _ = proto.Marshal(fabMSPConfig)
  1434  		updatedConfig.ChannelGroup.Groups["Orderer"].Groups["OrdererMSP2"] = &common.ConfigGroup{
  1435  			Values: map[string]*common.ConfigValue{
  1436  				"MSP": {
  1437  					Value:     protoutil.MarshalOrPanic(mspConfig),
  1438  					ModPolicy: "Admins",
  1439  				},
  1440  			},
  1441  			ModPolicy: "Admins",
  1442  		}
  1443  
  1444  		nwo.UpdateOrdererConfig(network, o1, channel, config, updatedConfig, peer, o1)
  1445  	})
  1446  })
  1447  
  1448  func ensureEvicted(evictedOrderer *nwo.Orderer, submitter *nwo.Peer, network *nwo.Network, channel string) {
  1449  	c := commands.ChannelFetch{
  1450  		ChannelID:  channel,
  1451  		Block:      "newest",
  1452  		OutputFile: "/dev/null",
  1453  		Orderer:    network.OrdererAddress(evictedOrderer, nwo.ListenPort),
  1454  	}
  1455  
  1456  	sess, err := network.OrdererAdminSession(evictedOrderer, submitter, c)
  1457  	Expect(err).NotTo(HaveOccurred())
  1458  
  1459  	Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit())
  1460  	Expect(sess.Err).To(gbytes.Say("SERVICE_UNAVAILABLE"))
  1461  }
  1462  
  1463  var extendedCryptoConfig = `---
  1464  OrdererOrgs:
  1465  - Name: OrdererOrg
  1466    Domain: example.com
  1467    EnableNodeOUs: false
  1468    CA:
  1469      Hostname: ca
  1470    Specs:
  1471    - Hostname: orderer1
  1472      SANS:
  1473      - localhost
  1474      - 127.0.0.1
  1475      - ::1
  1476    - Hostname: orderer1new
  1477      SANS:
  1478      - localhost
  1479      - 127.0.0.1
  1480      - ::1
  1481    - Hostname: orderer2
  1482      SANS:
  1483      - localhost
  1484      - 127.0.0.1
  1485      - ::1
  1486    - Hostname: orderer2new
  1487      SANS:
  1488      - localhost
  1489      - 127.0.0.1
  1490      - ::1
  1491    - Hostname: orderer3
  1492      SANS:
  1493      - localhost
  1494      - 127.0.0.1
  1495      - ::1
  1496    - Hostname: orderer3new
  1497      SANS:
  1498      - localhost
  1499      - 127.0.0.1
  1500      - ::1
  1501    - Hostname: orderer4
  1502      SANS:
  1503      - localhost
  1504      - 127.0.0.1
  1505      - ::1
  1506    - Hostname: orderer5
  1507      SANS:
  1508      - localhost
  1509      - 127.0.0.1
  1510      - ::1
  1511    - Hostname: orderer6
  1512      SANS:
  1513      - localhost
  1514      - 127.0.0.1
  1515      - ::1
  1516    - Hostname: orderer7
  1517      SANS:
  1518      - localhost
  1519      - 127.0.0.1
  1520      - ::1
  1521  `
  1522  
  1523  type certificateChange struct {
  1524  	srcFile string
  1525  	dstFile string
  1526  	oldCert []byte
  1527  	oldKey  []byte
  1528  	newCert []byte
  1529  }
  1530  
  1531  // extendNetwork rotates adds an additional orderer
  1532  func extendNetwork(n *nwo.Network) {
  1533  	// Overwrite the current crypto-config with additional orderers
  1534  	cryptoConfigYAML, err := ioutil.TempFile("", "crypto-config.yaml")
  1535  	Expect(err).NotTo(HaveOccurred())
  1536  	defer os.Remove(cryptoConfigYAML.Name())
  1537  
  1538  	err = ioutil.WriteFile(cryptoConfigYAML.Name(), []byte(extendedCryptoConfig), 0644)
  1539  	Expect(err).NotTo(HaveOccurred())
  1540  
  1541  	// Invoke cryptogen extend to add new orderers
  1542  	sess, err := n.Cryptogen(commands.Extend{
  1543  		Config: cryptoConfigYAML.Name(),
  1544  		Input:  n.CryptoPath(),
  1545  	})
  1546  	Expect(err).NotTo(HaveOccurred())
  1547  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
  1548  }
  1549  
  1550  // refreshOrdererPEMs rotates all TLS certificates of all nodes,
  1551  // and returns the deltas
  1552  func refreshOrdererPEMs(n *nwo.Network) []*certificateChange {
  1553  	var fileChanges []*certificateChange
  1554  	// Populate source to destination files
  1555  	err := filepath.Walk(n.CryptoPath(), func(path string, info os.FileInfo, err error) error {
  1556  		if !strings.Contains(path, "/tls/") {
  1557  			return nil
  1558  		}
  1559  		if strings.Contains(path, "new") {
  1560  			fileChanges = append(fileChanges, &certificateChange{
  1561  				srcFile: path,
  1562  				dstFile: strings.Replace(path, "new", "", -1),
  1563  			})
  1564  		}
  1565  		return nil
  1566  	})
  1567  	Expect(err).NotTo(HaveOccurred())
  1568  
  1569  	var serverCertChanges []*certificateChange
  1570  
  1571  	// Overwrite the destination files with the contents of the source files.
  1572  	for _, certChange := range fileChanges {
  1573  		previousCertBytes, err := ioutil.ReadFile(certChange.dstFile)
  1574  		Expect(err).NotTo(HaveOccurred())
  1575  
  1576  		newCertBytes, err := ioutil.ReadFile(certChange.srcFile)
  1577  		Expect(err).NotTo(HaveOccurred())
  1578  
  1579  		err = ioutil.WriteFile(certChange.dstFile, newCertBytes, 0644)
  1580  		Expect(err).NotTo(HaveOccurred())
  1581  
  1582  		if !strings.Contains(certChange.dstFile, "server.crt") {
  1583  			continue
  1584  		}
  1585  
  1586  		// Read the previous key file
  1587  		previousKeyBytes, err := ioutil.ReadFile(strings.Replace(certChange.dstFile, "server.crt", "server.key", -1))
  1588  		Expect(err).NotTo(HaveOccurred())
  1589  
  1590  		serverCertChanges = append(serverCertChanges, certChange)
  1591  		certChange.newCert = newCertBytes
  1592  		certChange.oldCert = previousCertBytes
  1593  		certChange.oldKey = previousKeyBytes
  1594  	}
  1595  	return serverCertChanges
  1596  }
  1597  
  1598  // assertBlockReception asserts that the given orderers have expected heights for the given channel--> height mapping
  1599  func assertBlockReception(expectedHeightsPerChannel map[string]int, orderers []*nwo.Orderer, p *nwo.Peer, n *nwo.Network) {
  1600  	assertReception := func(channelName string, blockSeq int) {
  1601  		var wg sync.WaitGroup
  1602  		wg.Add(len(orderers))
  1603  		for _, orderer := range orderers {
  1604  			go func(orderer *nwo.Orderer) {
  1605  				defer GinkgoRecover()
  1606  				defer wg.Done()
  1607  				waitForBlockReception(orderer, p, n, channelName, blockSeq)
  1608  			}(orderer)
  1609  		}
  1610  		wg.Wait()
  1611  	}
  1612  
  1613  	var wg sync.WaitGroup
  1614  	wg.Add(len(expectedHeightsPerChannel))
  1615  
  1616  	for channelName, blockSeq := range expectedHeightsPerChannel {
  1617  		go func(channelName string, blockSeq int) {
  1618  			defer GinkgoRecover()
  1619  			defer wg.Done()
  1620  			assertReception(channelName, blockSeq)
  1621  		}(channelName, blockSeq)
  1622  	}
  1623  	wg.Wait()
  1624  }
  1625  
  1626  func waitForBlockReception(o *nwo.Orderer, submitter *nwo.Peer, network *nwo.Network, channelName string, blockSeq int) {
  1627  	c := commands.ChannelFetch{
  1628  		ChannelID:  channelName,
  1629  		Block:      "newest",
  1630  		OutputFile: "/dev/null",
  1631  		Orderer:    network.OrdererAddress(o, nwo.ListenPort),
  1632  	}
  1633  	Eventually(func() string {
  1634  		sess, err := network.OrdererAdminSession(o, submitter, c)
  1635  		Expect(err).NotTo(HaveOccurred())
  1636  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit())
  1637  		if sess.ExitCode() != 0 {
  1638  			return fmt.Sprintf("exit code is %d: %s", sess.ExitCode(), string(sess.Err.Contents()))
  1639  		}
  1640  		sessErr := string(sess.Err.Contents())
  1641  		expected := fmt.Sprintf("Received block: %d", blockSeq)
  1642  		if strings.Contains(sessErr, expected) {
  1643  			return ""
  1644  		}
  1645  		return sessErr
  1646  	}, network.EventuallyTimeout, time.Second).Should(BeEmpty())
  1647  }
  1648  
  1649  func revokeReaderAccess(network *nwo.Network, channel string, orderer *nwo.Orderer, peer *nwo.Peer) {
  1650  	config := nwo.GetConfig(network, peer, orderer, channel)
  1651  	updatedConfig := proto.Clone(config).(*common.Config)
  1652  
  1653  	// set the policy
  1654  	adminPolicy := protoutil.MarshalOrPanic(&common.ImplicitMetaPolicy{
  1655  		SubPolicy: "Admins",
  1656  		Rule:      common.ImplicitMetaPolicy_MAJORITY,
  1657  	})
  1658  	updatedConfig.ChannelGroup.Groups["Orderer"].Policies["Readers"].Policy.Value = adminPolicy
  1659  	nwo.UpdateOrdererConfig(network, orderer, channel, config, updatedConfig, peer, orderer)
  1660  }
  1661  
  1662  // consenterAdder constructs configs that can be used by `UpdateOrdererConfig`
  1663  // to add a consenter.
  1664  func consenterAdder(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, consenter etcdraft.Consenter) (current, updated *common.Config) {
  1665  	config := nwo.GetConfig(n, peer, orderer, channel)
  1666  	updatedConfig := proto.Clone(config).(*common.Config)
  1667  
  1668  	consensusTypeConfigValue := updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"]
  1669  	consensusTypeValue := &protosorderer.ConsensusType{}
  1670  	err := proto.Unmarshal(consensusTypeConfigValue.Value, consensusTypeValue)
  1671  	Expect(err).NotTo(HaveOccurred())
  1672  
  1673  	metadata := &etcdraft.ConfigMetadata{}
  1674  	err = proto.Unmarshal(consensusTypeValue.Metadata, metadata)
  1675  	Expect(err).NotTo(HaveOccurred())
  1676  
  1677  	metadata.Consenters = append(metadata.Consenters, &consenter)
  1678  
  1679  	consensusTypeValue.Metadata, err = proto.Marshal(metadata)
  1680  	Expect(err).NotTo(HaveOccurred())
  1681  
  1682  	updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"] = &common.ConfigValue{
  1683  		ModPolicy: "Admins",
  1684  		Value:     protoutil.MarshalOrPanic(consensusTypeValue),
  1685  	}
  1686  
  1687  	return config, updatedConfig
  1688  }
  1689  
  1690  // consenterRemover constructs configs that can be used by
  1691  // `UpdateOrdererConfig` to remove a consenter.
  1692  func consenterRemover(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, certificate []byte) (current, updated *common.Config) {
  1693  	config := nwo.GetConfig(n, peer, orderer, channel)
  1694  	updatedConfig := proto.Clone(config).(*common.Config)
  1695  
  1696  	consensusTypeConfigValue := updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"]
  1697  	consensusTypeValue := &protosorderer.ConsensusType{}
  1698  	err := proto.Unmarshal(consensusTypeConfigValue.Value, consensusTypeValue)
  1699  	Expect(err).NotTo(HaveOccurred())
  1700  
  1701  	metadata := &etcdraft.ConfigMetadata{}
  1702  	err = proto.Unmarshal(consensusTypeValue.Metadata, metadata)
  1703  	Expect(err).NotTo(HaveOccurred())
  1704  
  1705  	var newConsenters []*etcdraft.Consenter
  1706  	for _, consenter := range metadata.Consenters {
  1707  		if bytes.Equal(consenter.ClientTlsCert, certificate) || bytes.Equal(consenter.ServerTlsCert, certificate) {
  1708  			continue
  1709  		}
  1710  		newConsenters = append(newConsenters, consenter)
  1711  	}
  1712  
  1713  	metadata.Consenters = newConsenters
  1714  	consensusTypeValue.Metadata, err = proto.Marshal(metadata)
  1715  	Expect(err).NotTo(HaveOccurred())
  1716  
  1717  	updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"] = &common.ConfigValue{
  1718  		ModPolicy: "Admins",
  1719  		Value:     protoutil.MarshalOrPanic(consensusTypeValue),
  1720  	}
  1721  
  1722  	return config, updatedConfig
  1723  }
  1724  
  1725  // addConsenter adds a new consenter to the given channel.
  1726  func addConsenter(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, consenter etcdraft.Consenter) {
  1727  	updateEtcdRaftMetadata(n, peer, orderer, channel, func(metadata *etcdraft.ConfigMetadata) {
  1728  		metadata.Consenters = append(metadata.Consenters, &consenter)
  1729  	})
  1730  }
  1731  
  1732  // removeConsenter removes a consenter with the given certificate in PEM format
  1733  // from the given channel.
  1734  func removeConsenter(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, certificate []byte) {
  1735  	updateEtcdRaftMetadata(n, peer, orderer, channel, func(metadata *etcdraft.ConfigMetadata) {
  1736  		var newConsenters []*etcdraft.Consenter
  1737  		for _, consenter := range metadata.Consenters {
  1738  			if bytes.Equal(consenter.ClientTlsCert, certificate) || bytes.Equal(consenter.ServerTlsCert, certificate) {
  1739  				continue
  1740  			}
  1741  			newConsenters = append(newConsenters, consenter)
  1742  		}
  1743  
  1744  		metadata.Consenters = newConsenters
  1745  	})
  1746  }
  1747  
  1748  // updateEtcdRaftMetadata executes a config update that updates the etcdraft
  1749  // metadata according to the given function f.
  1750  func updateEtcdRaftMetadata(network *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, f func(md *etcdraft.ConfigMetadata)) {
  1751  	nwo.UpdateConsensusMetadata(network, peer, orderer, channel, func(originalMetadata []byte) []byte {
  1752  		metadata := &etcdraft.ConfigMetadata{}
  1753  		err := proto.Unmarshal(originalMetadata, metadata)
  1754  		Expect(err).NotTo(HaveOccurred())
  1755  
  1756  		f(metadata)
  1757  
  1758  		newMetadata, err := proto.Marshal(metadata)
  1759  		Expect(err).NotTo(HaveOccurred())
  1760  		return newMetadata
  1761  	})
  1762  }
  1763  
  1764  func changeSubjectName(caCertPEM, caKeyPEM, leafPEM []byte, newSubjectName string) (newCA, newLeaf []byte) {
  1765  	keyAsDER, _ := pem.Decode(caKeyPEM)
  1766  	caKeyWithoutType, err := x509.ParsePKCS8PrivateKey(keyAsDER.Bytes)
  1767  	Expect(err).NotTo(HaveOccurred())
  1768  	caKey := caKeyWithoutType.(*ecdsa.PrivateKey)
  1769  
  1770  	caCertAsDER, _ := pem.Decode(caCertPEM)
  1771  	caCert, err := x509.ParseCertificate(caCertAsDER.Bytes)
  1772  	Expect(err).NotTo(HaveOccurred())
  1773  
  1774  	// Change its subject name
  1775  	caCert.Subject.CommonName = newSubjectName
  1776  	caCert.Issuer.CommonName = newSubjectName
  1777  	caCert.RawTBSCertificate = nil
  1778  	caCert.RawSubjectPublicKeyInfo = nil
  1779  	caCert.Raw = nil
  1780  	caCert.RawSubject = nil
  1781  	caCert.RawIssuer = nil
  1782  
  1783  	// The CA signs its own certificate
  1784  	caCertBytes, err := x509.CreateCertificate(rand.Reader, caCert, caCert, caCert.PublicKey, caKey)
  1785  	Expect(err).NotTo(HaveOccurred())
  1786  
  1787  	// Now it's the turn of the leaf certificate
  1788  	leafAsDER, _ := pem.Decode(leafPEM)
  1789  	leafCert, err := x509.ParseCertificate(leafAsDER.Bytes)
  1790  	Expect(err).NotTo(HaveOccurred())
  1791  
  1792  	leafCert.Raw = nil
  1793  	leafCert.RawIssuer = nil
  1794  	leafCert.RawTBSCertificate = nil
  1795  
  1796  	// The CA signs the leaf cert
  1797  	leafCertBytes, err := x509.CreateCertificate(rand.Reader, leafCert, caCert, leafCert.PublicKey, caKey)
  1798  	Expect(err).NotTo(HaveOccurred())
  1799  
  1800  	newCA = pem.EncodeToMemory(&pem.Block{Bytes: caCertBytes, Type: "CERTIFICATE"})
  1801  	newLeaf = pem.EncodeToMemory(&pem.Block{Bytes: leafCertBytes, Type: "CERTIFICATE"})
  1802  	return
  1803  }