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