github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/raft/cft_test.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package raft
     8  
     9  import (
    10  	"crypto/ecdsa"
    11  	"crypto/rand"
    12  	"crypto/x509"
    13  	"encoding/pem"
    14  	"fmt"
    15  	"io/ioutil"
    16  	"os"
    17  	"path"
    18  	"path/filepath"
    19  	"strconv"
    20  	"strings"
    21  	"sync"
    22  	"syscall"
    23  	"time"
    24  
    25  	docker "github.com/fsouza/go-dockerclient"
    26  	"github.com/golang/protobuf/proto"
    27  	"github.com/hechain20/hechain/common/configtx"
    28  	"github.com/hechain20/hechain/common/util"
    29  	"github.com/hechain20/hechain/integration/nwo"
    30  	"github.com/hechain20/hechain/integration/nwo/commands"
    31  	"github.com/hechain20/hechain/integration/ordererclient"
    32  	"github.com/hechain20/hechain/protoutil"
    33  	conftx "github.com/hyperledger/fabric-config/configtx"
    34  	"github.com/hyperledger/fabric-protos-go/common"
    35  	"github.com/hyperledger/fabric-protos-go/msp"
    36  	"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    37  	. "github.com/onsi/ginkgo"
    38  	. "github.com/onsi/gomega"
    39  	"github.com/onsi/gomega/gbytes"
    40  	"github.com/onsi/gomega/gexec"
    41  	"github.com/tedsuo/ifrit"
    42  	"github.com/tedsuo/ifrit/ginkgomon"
    43  	"github.com/tedsuo/ifrit/grouper"
    44  )
    45  
    46  var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
    47  	var (
    48  		testDir string
    49  		client  *docker.Client
    50  		network *nwo.Network
    51  		peer    *nwo.Peer
    52  
    53  		ordererProc, o1Proc, o2Proc, o3Proc ifrit.Process
    54  	)
    55  
    56  	BeforeEach(func() {
    57  		var err error
    58  		testDir, err = ioutil.TempDir("", "e2e")
    59  		Expect(err).NotTo(HaveOccurred())
    60  
    61  		client, err = docker.NewClientFromEnv()
    62  		Expect(err).NotTo(HaveOccurred())
    63  	})
    64  
    65  	AfterEach(func() {
    66  		for _, oProc := range []ifrit.Process{o1Proc, o2Proc, o3Proc} {
    67  			if oProc != nil {
    68  				oProc.Signal(syscall.SIGTERM)
    69  				Eventually(oProc.Wait(), network.EventuallyTimeout).Should(Receive())
    70  			}
    71  		}
    72  
    73  		if ordererProc != nil {
    74  			ordererProc.Signal(syscall.SIGTERM)
    75  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
    76  		}
    77  
    78  		if network != nil {
    79  			network.Cleanup()
    80  		}
    81  		os.RemoveAll(testDir)
    82  	})
    83  
    84  	When("orderer stops and restarts", func() {
    85  		It("keeps network up and running", func() {
    86  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
    87  
    88  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
    89  			peer = network.Peer("Org1", "peer0")
    90  
    91  			network.GenerateConfigTree()
    92  			network.Bootstrap()
    93  
    94  			o1Runner := network.OrdererRunner(o1)
    95  			// Enable debug log for orderer2 so we could assert its content later
    96  			o2Runner := network.OrdererRunner(o2, "FABRIC_LOGGING_SPEC=orderer.consensus.etcdraft=debug:info")
    97  			o3Runner := network.OrdererRunner(o3)
    98  			orderers := grouper.Members{
    99  				{Name: o2.ID(), Runner: o2Runner},
   100  				{Name: o3.ID(), Runner: o3Runner},
   101  			}
   102  			ordererGroup := grouper.NewParallel(syscall.SIGTERM, orderers)
   103  
   104  			o1Proc = ifrit.Invoke(o1Runner)
   105  			ordererProc = ifrit.Invoke(ordererGroup)
   106  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   107  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   108  
   109  			findLeader([]*ginkgomon.Runner{o1Runner})
   110  
   111  			By("performing operation with orderer1")
   112  			env := CreateBroadcastEnvelope(network, o1, network.SystemChannel.Name, []byte("foo"))
   113  			resp, err := ordererclient.Broadcast(network, o1, env)
   114  			Expect(err).NotTo(HaveOccurred())
   115  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   116  
   117  			block := FetchBlock(network, o1, 1, network.SystemChannel.Name)
   118  			Expect(block).NotTo(BeNil())
   119  
   120  			By("killing orderer1")
   121  			o1Proc.Signal(syscall.SIGKILL)
   122  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive(MatchError("exit status 137")))
   123  
   124  			By("observing active nodes to shrink")
   125  			Eventually(o2Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("Current active nodes in cluster are: \\[2 3\\]"))
   126  
   127  			By("broadcasting envelope to running orderer")
   128  			resp, err = ordererclient.Broadcast(network, o2, env)
   129  			Expect(err).NotTo(HaveOccurred())
   130  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   131  
   132  			block = FetchBlock(network, o2, 2, network.SystemChannel.Name)
   133  			Expect(block).NotTo(BeNil())
   134  
   135  			By("restarting orderer1")
   136  			o1Runner = network.OrdererRunner(o1)
   137  			o1Proc = ifrit.Invoke(o1Runner)
   138  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   139  			findLeader([]*ginkgomon.Runner{o1Runner})
   140  
   141  			By("broadcasting envelope to restarted orderer")
   142  			resp, err = ordererclient.Broadcast(network, o1, env)
   143  			Expect(err).NotTo(HaveOccurred())
   144  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   145  
   146  			blko1 := FetchBlock(network, o1, 3, network.SystemChannel.Name)
   147  			blko2 := FetchBlock(network, o2, 3, network.SystemChannel.Name)
   148  
   149  			Expect(blko1.Header.DataHash).To(Equal(blko2.Header.DataHash))
   150  		})
   151  	})
   152  
   153  	When("an orderer is behind the latest snapshot on leader", func() {
   154  		It("catches up using the block stored in snapshot", func() {
   155  			// Steps:
   156  			// - start o2 & o3
   157  			// - send several transactions so snapshot is created
   158  			// - kill o2 & o3, so that entries prior to snapshot are not in memory upon restart
   159  			// - start o1 & o2
   160  			// - assert that o1 can catch up with o2 using snapshot
   161  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   162  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   163  			peer = network.Peer("Org1", "peer0")
   164  
   165  			network.GenerateConfigTree()
   166  			network.Bootstrap()
   167  
   168  			orderers := grouper.Members{
   169  				{Name: o2.ID(), Runner: network.OrdererRunner(o2)},
   170  				{Name: o3.ID(), Runner: network.OrdererRunner(o3)},
   171  			}
   172  			ordererGroup := grouper.NewParallel(syscall.SIGTERM, orderers)
   173  
   174  			By("Starting 2/3 of cluster")
   175  			ordererProc = ifrit.Invoke(ordererGroup)
   176  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   177  
   178  			By("Creating testchannel")
   179  			channelID := "testchannel"
   180  			network.CreateChannel(channelID, o2, peer)
   181  
   182  			By("Submitting several transactions to trigger snapshot")
   183  			o2SnapDir := path.Join(network.RootDir, "orderers", o2.ID(), "etcdraft", "snapshot")
   184  
   185  			env := CreateBroadcastEnvelope(network, o2, channelID, make([]byte, 2000))
   186  			for i := 1; i <= 4; i++ { // 4 < MaxSnapshotFiles(5), so that no snapshot is pruned
   187  				// Note that MaxMessageCount is 1 be default, so every tx results in a new block
   188  				resp, err := ordererclient.Broadcast(network, o2, env)
   189  				Expect(err).NotTo(HaveOccurred())
   190  				Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   191  
   192  				// Assert that new snapshot file is created before broadcasting next tx,
   193  				// so that number of snapshots is deterministic. Otherwise, it is not
   194  				// guaranteed that every block triggers a snapshot file being created,
   195  				// due to the mechanism to prevent excessive snapshotting.
   196  				Eventually(func() int {
   197  					files, err := ioutil.ReadDir(path.Join(o2SnapDir, channelID))
   198  					Expect(err).NotTo(HaveOccurred())
   199  					return len(files)
   200  				}, network.EventuallyTimeout).Should(Equal(i)) // snapshot interval is 1 KB, every block triggers snapshot
   201  			}
   202  
   203  			By("Killing orderers so they don't have blocks prior to latest snapshot in the memory")
   204  			ordererProc.Signal(syscall.SIGKILL)
   205  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   206  
   207  			By("Starting lagged orderer and one of up-to-date orderers")
   208  			orderers = grouper.Members{
   209  				{Name: o1.ID(), Runner: network.OrdererRunner(o1)},
   210  				{Name: o2.ID(), Runner: network.OrdererRunner(o2)},
   211  			}
   212  			ordererGroup = grouper.NewParallel(syscall.SIGTERM, orderers)
   213  			ordererProc = ifrit.Invoke(ordererGroup)
   214  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   215  
   216  			o1SnapDir := path.Join(network.RootDir, "orderers", o1.ID(), "etcdraft", "snapshot")
   217  
   218  			By("Asserting that orderer1 has snapshot dir for both system and application channel")
   219  			Eventually(func() int {
   220  				files, err := ioutil.ReadDir(o1SnapDir)
   221  				Expect(err).NotTo(HaveOccurred())
   222  				return len(files)
   223  			}, network.EventuallyTimeout).Should(Equal(2))
   224  
   225  			By("Asserting that orderer1 receives and persists snapshot")
   226  			Eventually(func() int {
   227  				files, err := ioutil.ReadDir(path.Join(o1SnapDir, channelID))
   228  				Expect(err).NotTo(HaveOccurred())
   229  				return len(files)
   230  			}, network.EventuallyTimeout).Should(Equal(1))
   231  
   232  			By("Asserting cluster is still functional")
   233  			env = CreateBroadcastEnvelope(network, o1, channelID, make([]byte, 1000))
   234  			resp, err := ordererclient.Broadcast(network, o1, env)
   235  			Expect(err).NotTo(HaveOccurred())
   236  			Eventually(resp.Status, network.EventuallyTimeout).Should(Equal(common.Status_SUCCESS))
   237  
   238  			for i := 1; i <= 5; i++ {
   239  				blko1 := FetchBlock(network, o1, uint64(i), channelID)
   240  				blko2 := FetchBlock(network, o2, uint64(i), channelID)
   241  
   242  				Expect(blko1.Header.DataHash).To(Equal(blko2.Header.DataHash))
   243  				metao1, err := protoutil.GetConsenterMetadataFromBlock(blko1)
   244  				Expect(err).NotTo(HaveOccurred())
   245  				metao2, err := protoutil.GetConsenterMetadataFromBlock(blko2)
   246  				Expect(err).NotTo(HaveOccurred())
   247  
   248  				bmo1 := &etcdraft.BlockMetadata{}
   249  				proto.Unmarshal(metao1.Value, bmo1)
   250  				bmo2 := &etcdraft.BlockMetadata{}
   251  				proto.Unmarshal(metao2.Value, bmo2)
   252  
   253  				Expect(bmo2).To(Equal(bmo1))
   254  			}
   255  		})
   256  
   257  		It("catches up and replicates consenters metadata", func() {
   258  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   259  			orderers := []*nwo.Orderer{network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")}
   260  			peer = network.Peer("Org1", "peer0")
   261  
   262  			network.GenerateConfigTree()
   263  			network.Bootstrap()
   264  
   265  			ordererRunners := []*ginkgomon.Runner{}
   266  			orderersMembers := grouper.Members{}
   267  			for _, o := range orderers {
   268  				runner := network.OrdererRunner(o)
   269  				ordererRunners = append(ordererRunners, runner)
   270  				orderersMembers = append(orderersMembers, grouper.Member{
   271  					Name:   o.ID(),
   272  					Runner: runner,
   273  				})
   274  			}
   275  
   276  			By("Starting ordering service cluster")
   277  			ordererGroup := grouper.NewParallel(syscall.SIGTERM, orderersMembers)
   278  			ordererProc = ifrit.Invoke(ordererGroup)
   279  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   280  
   281  			By("Setting up new OSN to be added to the cluster")
   282  			o4 := &nwo.Orderer{
   283  				Name:         "orderer4",
   284  				Organization: "OrdererOrg",
   285  			}
   286  			ports := nwo.Ports{}
   287  			for _, portName := range nwo.OrdererPortNames() {
   288  				ports[portName] = network.ReservePort()
   289  			}
   290  
   291  			network.PortsByOrdererID[o4.ID()] = ports
   292  			network.Orderers = append(network.Orderers, o4)
   293  			network.GenerateOrdererConfig(o4)
   294  			extendNetwork(network)
   295  
   296  			ordererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(o4), "server.crt")
   297  			ordererCert, err := ioutil.ReadFile(ordererCertificatePath)
   298  			Expect(err).NotTo(HaveOccurred())
   299  
   300  			By("Adding new ordering service node")
   301  			addConsenter(network, peer, orderers[0], "systemchannel", etcdraft.Consenter{
   302  				ServerTlsCert: ordererCert,
   303  				ClientTlsCert: ordererCert,
   304  				Host:          "127.0.0.1",
   305  				Port:          uint32(network.OrdererPort(o4, nwo.ClusterPort)),
   306  			})
   307  
   308  			// Get the last config block of the system channel
   309  			configBlock := nwo.GetConfigBlock(network, peer, orderers[0], "systemchannel")
   310  			// Plant it in the file system of orderer, the new node to be onboarded.
   311  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0o644)
   312  
   313  			Expect(err).NotTo(HaveOccurred())
   314  			By("Starting new ordering service node")
   315  			r4 := network.OrdererRunner(o4)
   316  			orderers = append(orderers, o4)
   317  			ordererRunners = append(ordererRunners, r4)
   318  			o4process := ifrit.Invoke(r4)
   319  			Eventually(o4process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   320  
   321  			By("Pick ordering service node to be evicted")
   322  			victimIdx := findLeader(ordererRunners) - 1
   323  			victim := orderers[victimIdx]
   324  			victimCertBytes, err := ioutil.ReadFile(filepath.Join(network.OrdererLocalTLSDir(victim), "server.crt"))
   325  			Expect(err).NotTo(HaveOccurred())
   326  
   327  			assertBlockReception(map[string]int{
   328  				"systemchannel": 1,
   329  			}, orderers, peer, network)
   330  
   331  			By("Removing OSN from the channel")
   332  			remainedOrderers := []*nwo.Orderer{}
   333  			remainedRunners := []*ginkgomon.Runner{}
   334  
   335  			for i, o := range orderers {
   336  				if i == victimIdx {
   337  					continue
   338  				}
   339  				remainedOrderers = append(remainedOrderers, o)
   340  				remainedRunners = append(remainedRunners, ordererRunners[i])
   341  			}
   342  
   343  			removeConsenter(network, peer, remainedOrderers[0], "systemchannel", victimCertBytes)
   344  
   345  			By("Asserting all remaining nodes got last block")
   346  			assertBlockReception(map[string]int{
   347  				"systemchannel": 2,
   348  			}, remainedOrderers, peer, network)
   349  			By("Making sure OSN was evicted and configuration applied")
   350  			findLeader(remainedRunners)
   351  
   352  			By("Restarting all nodes")
   353  			o4process.Signal(syscall.SIGTERM)
   354  			Eventually(o4process.Wait(), network.EventuallyTimeout).Should(Receive())
   355  			ordererProc.Signal(syscall.SIGTERM)
   356  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   357  
   358  			r1 := network.OrdererRunner(remainedOrderers[1])
   359  			r2 := network.OrdererRunner(remainedOrderers[2])
   360  			orderersMembers = grouper.Members{
   361  				{Name: remainedOrderers[1].ID(), Runner: r1},
   362  				{Name: remainedOrderers[2].ID(), Runner: r2},
   363  			}
   364  
   365  			ordererGroup = grouper.NewParallel(syscall.SIGTERM, orderersMembers)
   366  			ordererProc = ifrit.Invoke(ordererGroup)
   367  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   368  			findLeader([]*ginkgomon.Runner{r1, r2})
   369  
   370  			By("Submitting several transactions to trigger snapshot")
   371  			env := CreateBroadcastEnvelope(network, remainedOrderers[1], "systemchannel", make([]byte, 2000))
   372  			for i := 3; i <= 10; i++ {
   373  				// Note that MaxMessageCount is 1 be default, so every tx results in a new block
   374  				resp, err := ordererclient.Broadcast(network, remainedOrderers[1], env)
   375  				Expect(err).NotTo(HaveOccurred())
   376  				Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   377  			}
   378  
   379  			assertBlockReception(map[string]int{
   380  				"systemchannel": 10,
   381  			}, []*nwo.Orderer{remainedOrderers[2]}, peer, network)
   382  
   383  			By("Clean snapshot folder of lagging behind node")
   384  			snapDir := path.Join(network.RootDir, "orderers", remainedOrderers[0].ID(), "etcdraft", "snapshot")
   385  			snapshots, err := ioutil.ReadDir(snapDir)
   386  			Expect(err).NotTo(HaveOccurred())
   387  
   388  			for _, snap := range snapshots {
   389  				os.RemoveAll(path.Join(snapDir, snap.Name()))
   390  			}
   391  
   392  			ordererProc.Signal(syscall.SIGTERM)
   393  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   394  
   395  			r0 := network.OrdererRunner(remainedOrderers[0])
   396  			r1 = network.OrdererRunner(remainedOrderers[1])
   397  			orderersMembers = grouper.Members{
   398  				{Name: remainedOrderers[0].ID(), Runner: r0},
   399  				{Name: remainedOrderers[1].ID(), Runner: r1},
   400  			}
   401  
   402  			ordererGroup = grouper.NewParallel(syscall.SIGTERM, orderersMembers)
   403  			ordererProc = ifrit.Invoke(ordererGroup)
   404  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   405  			findLeader([]*ginkgomon.Runner{r0, r1})
   406  
   407  			By("Asserting that orderer1 receives and persists snapshot")
   408  			Eventually(func() int {
   409  				files, err := ioutil.ReadDir(path.Join(snapDir, "systemchannel"))
   410  				Expect(err).NotTo(HaveOccurred())
   411  				return len(files)
   412  			}, network.EventuallyTimeout).Should(BeNumerically(">", 0))
   413  
   414  			assertBlockReception(map[string]int{
   415  				"systemchannel": 10,
   416  			}, []*nwo.Orderer{remainedOrderers[0]}, peer, network)
   417  
   418  			By("Make sure we can restart and connect to orderer1 with orderer4")
   419  			ordererProc.Signal(syscall.SIGTERM)
   420  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   421  
   422  			r0 = network.OrdererRunner(remainedOrderers[0])
   423  			r2 = network.OrdererRunner(remainedOrderers[2])
   424  			orderersMembers = grouper.Members{
   425  				{Name: remainedOrderers[0].ID(), Runner: r0},
   426  				{Name: remainedOrderers[2].ID(), Runner: r2},
   427  			}
   428  
   429  			ordererGroup = grouper.NewParallel(syscall.SIGTERM, orderersMembers)
   430  			ordererProc = ifrit.Invoke(ordererGroup)
   431  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   432  			findLeader([]*ginkgomon.Runner{r0, r2})
   433  
   434  			for i := 1; i <= 10; i++ {
   435  				blko1 := FetchBlock(network, remainedOrderers[0], uint64(i), "systemchannel")
   436  				blko2 := FetchBlock(network, remainedOrderers[2], uint64(i), "systemchannel")
   437  				Expect(blko1.Header.DataHash).To(Equal(blko2.Header.DataHash))
   438  				metao1, err := protoutil.GetConsenterMetadataFromBlock(blko1)
   439  				Expect(err).NotTo(HaveOccurred())
   440  				metao2, err := protoutil.GetConsenterMetadataFromBlock(blko2)
   441  				Expect(err).NotTo(HaveOccurred())
   442  
   443  				bmo1 := &etcdraft.BlockMetadata{}
   444  				proto.Unmarshal(metao1.Value, bmo1)
   445  				bmo2 := &etcdraft.BlockMetadata{}
   446  				proto.Unmarshal(metao2.Value, bmo2)
   447  
   448  				Expect(bmo2).To(Equal(bmo1))
   449  			}
   450  		})
   451  	})
   452  
   453  	When("The leader dies", func() {
   454  		It("Elects a new leader", func() {
   455  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   456  
   457  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   458  
   459  			network.GenerateConfigTree()
   460  			network.Bootstrap()
   461  
   462  			By("Running the orderer nodes")
   463  			o1Runner := network.OrdererRunner(o1)
   464  			o2Runner := network.OrdererRunner(o2)
   465  			o3Runner := network.OrdererRunner(o3)
   466  
   467  			o1Proc = ifrit.Invoke(o1Runner)
   468  			o2Proc = ifrit.Invoke(o2Runner)
   469  			o3Proc = ifrit.Invoke(o3Runner)
   470  
   471  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   472  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   473  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   474  
   475  			By("Waiting for them to elect a leader")
   476  			ordererProcesses := []ifrit.Process{o1Proc, o2Proc, o3Proc}
   477  			remainingAliveRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   478  			leader := findLeader(remainingAliveRunners)
   479  
   480  			leaderIndex := leader - 1
   481  			By(fmt.Sprintf("Killing the leader (%d)", leader))
   482  			ordererProcesses[leaderIndex].Signal(syscall.SIGTERM)
   483  			By("Waiting for it to die")
   484  			Eventually(ordererProcesses[leaderIndex].Wait(), network.EventuallyTimeout).Should(Receive())
   485  
   486  			// Remove the leader from the orderer runners
   487  			remainingAliveRunners = append(remainingAliveRunners[:leaderIndex], remainingAliveRunners[leaderIndex+1:]...)
   488  
   489  			By("Waiting for a new leader to be elected")
   490  			leader = findLeader(remainingAliveRunners)
   491  			By(fmt.Sprintf("Orderer %d took over as a leader", leader))
   492  		})
   493  	})
   494  
   495  	When("Leader cannot reach quorum", func() {
   496  		It("Steps down", func() {
   497  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   498  
   499  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   500  			orderers := []*nwo.Orderer{o1, o2, o3}
   501  			peer = network.Peer("Org1", "peer0")
   502  			network.GenerateConfigTree()
   503  			network.Bootstrap()
   504  
   505  			By("Running the orderer nodes")
   506  			o1Runner := network.OrdererRunner(o1)
   507  			o2Runner := network.OrdererRunner(o2)
   508  			o3Runner := network.OrdererRunner(o3)
   509  			oRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   510  
   511  			o1Proc = ifrit.Invoke(o1Runner)
   512  			o2Proc = ifrit.Invoke(o2Runner)
   513  			o3Proc = ifrit.Invoke(o3Runner)
   514  
   515  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   516  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   517  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   518  
   519  			By("Waiting for them to elect a leader")
   520  			ordererProcesses := []ifrit.Process{o1Proc, o2Proc, o3Proc}
   521  			remainingAliveRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   522  			leaderID := findLeader(remainingAliveRunners)
   523  			leaderIndex := leaderID - 1
   524  			leader := orderers[leaderIndex]
   525  
   526  			followerIndices := func() []int {
   527  				var f []int
   528  				for i := range ordererProcesses {
   529  					if leaderIndex != i {
   530  						f = append(f, i)
   531  					}
   532  				}
   533  
   534  				return f
   535  			}()
   536  
   537  			By(fmt.Sprintf("Killing two followers (%d and %d)", followerIndices[0]+1, followerIndices[1]+1))
   538  			ordererProcesses[followerIndices[0]].Signal(syscall.SIGTERM)
   539  			ordererProcesses[followerIndices[1]].Signal(syscall.SIGTERM)
   540  
   541  			By("Waiting for followers to die")
   542  			// This significantly slows test (~10s). However, reducing ElectionTimeout
   543  			// would introduce some flakes when disk write is exceptionally slow.
   544  			Eventually(ordererProcesses[followerIndices[0]].Wait(), network.EventuallyTimeout).Should(Receive())
   545  			Eventually(ordererProcesses[followerIndices[1]].Wait(), network.EventuallyTimeout).Should(Receive())
   546  
   547  			By("Waiting for leader to step down")
   548  			Eventually(oRunners[leaderIndex].Err(), time.Minute, time.Second).Should(gbytes.Say(fmt.Sprintf("%d stepped down to follower since quorum is not active", leaderID)))
   549  
   550  			By("Submitting tx to leader")
   551  			// This should fail because current leader steps down
   552  			// and there is no leader at this point of time
   553  			env := CreateBroadcastEnvelope(network, leader, network.SystemChannel.Name, []byte("foo"))
   554  			resp, err := ordererclient.Broadcast(network, leader, env)
   555  			Expect(err).NotTo(HaveOccurred())
   556  			Expect(resp.Status).To(Equal(common.Status_SERVICE_UNAVAILABLE))
   557  		})
   558  	})
   559  
   560  	When("orderer TLS certificates expire", func() {
   561  		It("is still possible to recover", func() {
   562  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   563  
   564  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   565  			peer = network.Peer("Org1", "peer0")
   566  
   567  			network.GenerateConfigTree()
   568  			network.Bootstrap()
   569  
   570  			ordererDomain := network.Organization(o1.Organization).Domain
   571  			ordererTLSCAKeyPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   572  				ordererDomain, "tlsca", "priv_sk")
   573  
   574  			ordererTLSCAKey, err := ioutil.ReadFile(ordererTLSCAKeyPath)
   575  			Expect(err).NotTo(HaveOccurred())
   576  
   577  			ordererTLSCACertPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   578  				ordererDomain, "tlsca", fmt.Sprintf("tlsca.%s-cert.pem", ordererDomain))
   579  			ordererTLSCACert, err := ioutil.ReadFile(ordererTLSCACertPath)
   580  			Expect(err).NotTo(HaveOccurred())
   581  
   582  			serverTLSCerts := make(map[string][]byte)
   583  			for _, orderer := range []*nwo.Orderer{o1, o2, o3} {
   584  				tlsCertPath := filepath.Join(network.OrdererLocalTLSDir(orderer), "server.crt")
   585  				serverTLSCerts[tlsCertPath], err = ioutil.ReadFile(tlsCertPath)
   586  				Expect(err).NotTo(HaveOccurred())
   587  			}
   588  
   589  			By("Expiring orderer TLS certificates")
   590  			for filePath, certPEM := range serverTLSCerts {
   591  				expiredCert, earlyMadeCACert := expireCertificate(certPEM, ordererTLSCACert, ordererTLSCAKey, time.Now())
   592  				err = ioutil.WriteFile(filePath, expiredCert, 0o600)
   593  				Expect(err).NotTo(HaveOccurred())
   594  
   595  				err = ioutil.WriteFile(ordererTLSCACertPath, earlyMadeCACert, 0o600)
   596  				Expect(err).NotTo(HaveOccurred())
   597  			}
   598  
   599  			By("Regenerating config")
   600  			sess, err := network.ConfigTxGen(commands.OutputBlock{
   601  				ChannelID:   network.SystemChannel.Name,
   602  				Profile:     network.SystemChannel.Profile,
   603  				ConfigPath:  network.RootDir,
   604  				OutputBlock: network.OutputBlockPath(network.SystemChannel.Name),
   605  			})
   606  			Expect(err).NotTo(HaveOccurred())
   607  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   608  
   609  			By("Running the orderer nodes")
   610  			o1Runner := network.OrdererRunner(o1)
   611  			o2Runner := network.OrdererRunner(o2)
   612  			o3Runner := network.OrdererRunner(o3)
   613  
   614  			o1Proc = ifrit.Invoke(o1Runner)
   615  			o2Proc = ifrit.Invoke(o2Runner)
   616  			o3Proc = ifrit.Invoke(o3Runner)
   617  
   618  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   619  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   620  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   621  
   622  			By("Waiting for TLS handshakes to fail")
   623  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   624  			Eventually(o2Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   625  			Eventually(o3Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   626  
   627  			By("Killing orderers")
   628  			o1Proc.Signal(syscall.SIGTERM)
   629  			o2Proc.Signal(syscall.SIGTERM)
   630  			o3Proc.Signal(syscall.SIGTERM)
   631  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   632  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   633  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   634  
   635  			o1Runner = network.OrdererRunner(o1)
   636  			o2Runner = network.OrdererRunner(o2)
   637  			o3Runner = network.OrdererRunner(o3)
   638  
   639  			By("Launching orderers with a clustered timeshift")
   640  			orderers := []*nwo.Orderer{o1, o2, o3}
   641  			for _, orderer := range orderers {
   642  				ordererConfig := network.ReadOrdererConfig(orderer)
   643  				ordererConfig.General.Cluster.TLSHandshakeTimeShift = 5 * time.Minute
   644  				network.WriteOrdererConfig(orderer, ordererConfig)
   645  			}
   646  
   647  			o1Proc = ifrit.Invoke(o1Runner)
   648  			o2Proc = ifrit.Invoke(o2Runner)
   649  			o3Proc = ifrit.Invoke(o3Runner)
   650  
   651  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   652  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   653  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   654  
   655  			By("Waiting for a leader to be elected")
   656  			findLeader([]*ginkgomon.Runner{o1Runner, o2Runner, o3Runner})
   657  
   658  			By("Killing orderers")
   659  			o1Proc.Signal(syscall.SIGTERM)
   660  			o2Proc.Signal(syscall.SIGTERM)
   661  			o3Proc.Signal(syscall.SIGTERM)
   662  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   663  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   664  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   665  
   666  			o1Runner = network.OrdererRunner(o1)
   667  			o2Runner = network.OrdererRunner(o2)
   668  			o3Runner = network.OrdererRunner(o3)
   669  
   670  			By("Launching orderers again without a general timeshift re-using the cluster port")
   671  			for _, orderer := range orderers {
   672  				ordererConfig := network.ReadOrdererConfig(orderer)
   673  				ordererConfig.General.ListenPort = ordererConfig.General.Cluster.ListenPort
   674  				ordererConfig.General.TLS.Certificate = ordererConfig.General.Cluster.ServerCertificate
   675  				ordererConfig.General.TLS.PrivateKey = ordererConfig.General.Cluster.ServerPrivateKey
   676  				ordererConfig.General.Cluster.TLSHandshakeTimeShift = 0
   677  				ordererConfig.General.Cluster.ListenPort = 0
   678  				ordererConfig.General.Cluster.ListenAddress = ""
   679  				ordererConfig.General.Cluster.ServerCertificate = ""
   680  				ordererConfig.General.Cluster.ServerPrivateKey = ""
   681  				ordererConfig.General.Cluster.ClientCertificate = ""
   682  				ordererConfig.General.Cluster.ClientPrivateKey = ""
   683  				network.WriteOrdererConfig(orderer, ordererConfig)
   684  			}
   685  
   686  			o1Proc = ifrit.Invoke(o1Runner)
   687  			o2Proc = ifrit.Invoke(o2Runner)
   688  			o3Proc = ifrit.Invoke(o3Runner)
   689  
   690  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   691  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   692  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   693  
   694  			By("Waiting for TLS handshakes to fail")
   695  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   696  			Eventually(o2Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   697  			Eventually(o3Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   698  
   699  			By("Killing orderers")
   700  			o1Proc.Signal(syscall.SIGTERM)
   701  			o2Proc.Signal(syscall.SIGTERM)
   702  			o3Proc.Signal(syscall.SIGTERM)
   703  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   704  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   705  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   706  
   707  			o1Runner = network.OrdererRunner(o1)
   708  			o2Runner = network.OrdererRunner(o2)
   709  			o3Runner = network.OrdererRunner(o3)
   710  
   711  			By("Launching orderers again with a general timeshift re-using the cluster port")
   712  			for _, orderer := range orderers {
   713  				ordererConfig := network.ReadOrdererConfig(orderer)
   714  				ordererConfig.General.TLS.TLSHandshakeTimeShift = 5 * time.Minute
   715  				network.WriteOrdererConfig(orderer, ordererConfig)
   716  			}
   717  
   718  			o1Proc = ifrit.Invoke(o1Runner)
   719  			o2Proc = ifrit.Invoke(o2Runner)
   720  			o3Proc = ifrit.Invoke(o3Runner)
   721  
   722  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   723  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   724  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   725  
   726  			By("Waiting for a leader to be elected")
   727  			findLeader([]*ginkgomon.Runner{o1Runner, o2Runner, o3Runner})
   728  
   729  			By("submitting config updates to orderers with expired TLS certs to replace the expired certs")
   730  			timeShift := 5 * time.Minute
   731  			for _, o := range orderers {
   732  				channelConfig := fetchConfig(network, peer, o, nwo.ClusterPort, network.SystemChannel.Name, timeShift)
   733  				c := conftx.New(channelConfig)
   734  				err = c.Orderer().RemoveConsenter(consenterChannelConfig(network, o))
   735  				Expect(err).NotTo(HaveOccurred())
   736  
   737  				By("renewing the orderer TLS certificates for " + o.Name)
   738  				renewOrdererCertificates(network, o)
   739  				err = c.Orderer().AddConsenter(consenterChannelConfig(network, o))
   740  				Expect(err).NotTo(HaveOccurred())
   741  
   742  				By("updating the config for " + o.Name)
   743  				updateOrdererConfig(network, o, nwo.ClusterPort, network.SystemChannel.Name, timeShift, c.OriginalConfig(), c.UpdatedConfig(), peer)
   744  			}
   745  
   746  			By("Killing orderers")
   747  			o1Proc.Signal(syscall.SIGTERM)
   748  			o2Proc.Signal(syscall.SIGTERM)
   749  			o3Proc.Signal(syscall.SIGTERM)
   750  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   751  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   752  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   753  
   754  			o1Runner = network.OrdererRunner(o1)
   755  			o2Runner = network.OrdererRunner(o2)
   756  			o3Runner = network.OrdererRunner(o3)
   757  
   758  			By("Launching orderers again without a general timeshift")
   759  			for _, o := range orderers {
   760  				ordererConfig := network.ReadOrdererConfig(o)
   761  				ordererConfig.General.TLS.TLSHandshakeTimeShift = 0
   762  				network.WriteOrdererConfig(o, ordererConfig)
   763  			}
   764  
   765  			o1Proc = ifrit.Invoke(o1Runner)
   766  			o2Proc = ifrit.Invoke(o2Runner)
   767  			o3Proc = ifrit.Invoke(o3Runner)
   768  
   769  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   770  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   771  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   772  
   773  			By("Waiting for a leader to be elected")
   774  			findLeader([]*ginkgomon.Runner{o1Runner, o2Runner, o3Runner})
   775  		})
   776  
   777  		It("disregards certificate renewal if only the validity period changed", func() {
   778  			config := nwo.MultiNodeEtcdRaft()
   779  			config.Channels = append(config.Channels, &nwo.Channel{Name: "foo", Profile: "TwoOrgsChannel"})
   780  			config.Channels = append(config.Channels, &nwo.Channel{Name: "bar", Profile: "TwoOrgsChannel"})
   781  			network = nwo.New(config, testDir, client, StartPort(), components)
   782  
   783  			network.GenerateConfigTree()
   784  			network.Bootstrap()
   785  
   786  			peer = network.Peer("Org1", "peer0")
   787  
   788  			o1 := network.Orderer("orderer1")
   789  			o2 := network.Orderer("orderer2")
   790  			o3 := network.Orderer("orderer3")
   791  
   792  			orderers := []*nwo.Orderer{o1, o2, o3}
   793  
   794  			o1Runner := network.OrdererRunner(o1)
   795  			o2Runner := network.OrdererRunner(o2)
   796  			o3Runner := network.OrdererRunner(o3)
   797  			ordererRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   798  
   799  			o1Proc = ifrit.Invoke(o1Runner)
   800  			o2Proc = ifrit.Invoke(o2Runner)
   801  			o3Proc = ifrit.Invoke(o3Runner)
   802  			ordererProcesses := []ifrit.Process{o1Proc, o2Proc, o3Proc}
   803  
   804  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   805  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   806  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   807  
   808  			By("Waiting for them to elect a leader")
   809  			findLeader(ordererRunners)
   810  
   811  			By("Creating a channel")
   812  			network.CreateChannel("foo", o1, peer)
   813  
   814  			assertBlockReception(map[string]int{
   815  				"foo":           0,
   816  				"systemchannel": 1,
   817  			}, []*nwo.Orderer{o1, o2, o3}, peer, network)
   818  
   819  			By("Killing all orderers")
   820  			for i := range orderers {
   821  				ordererProcesses[i].Signal(syscall.SIGTERM)
   822  				Eventually(ordererProcesses[i].Wait(), network.EventuallyTimeout).Should(Receive())
   823  			}
   824  
   825  			By("Renewing the certificates for all orderers")
   826  			renewOrdererCertificates(network, o1, o2, o3)
   827  
   828  			By("Starting the orderers again")
   829  			for i := range orderers {
   830  				ordererRunner := network.OrdererRunner(orderers[i])
   831  				ordererRunners[i] = ordererRunner
   832  				ordererProcesses[i] = ifrit.Invoke(ordererRunner)
   833  				Eventually(ordererProcesses[0].Ready(), network.EventuallyTimeout).Should(BeClosed())
   834  			}
   835  
   836  			o1Proc = ordererProcesses[0]
   837  			o2Proc = ordererProcesses[1]
   838  			o3Proc = ordererProcesses[2]
   839  
   840  			By("Waiting for them to elect a leader once again")
   841  			findLeader(ordererRunners)
   842  
   843  			By("Creating a channel again")
   844  			network.CreateChannel("bar", o1, peer)
   845  
   846  			assertBlockReception(map[string]int{
   847  				"foo":           0,
   848  				"bar":           0,
   849  				"systemchannel": 2,
   850  			}, []*nwo.Orderer{o1, o2, o3}, peer, network)
   851  		})
   852  	})
   853  
   854  	When("admin certificate expires", func() {
   855  		It("is still possible to replace them", func() {
   856  			network = nwo.New(nwo.BasicEtcdRaft(), testDir, client, StartPort(), components)
   857  			network.GenerateConfigTree()
   858  			network.Bootstrap()
   859  
   860  			peer = network.Peer("Org1", "peer0")
   861  			orderer := network.Orderer("orderer")
   862  
   863  			ordererDomain := network.Organization(orderer.Organization).Domain
   864  			ordererCAKeyPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations", ordererDomain, "ca", "priv_sk")
   865  
   866  			ordererCAKey, err := ioutil.ReadFile(ordererCAKeyPath)
   867  			Expect(err).NotTo(HaveOccurred())
   868  
   869  			ordererCACertPath := network.OrdererCACert(orderer)
   870  			ordererCACert, err := ioutil.ReadFile(ordererCACertPath)
   871  			Expect(err).NotTo(HaveOccurred())
   872  
   873  			adminCertPath := network.OrdererUserCert(orderer, "Admin")
   874  
   875  			originalAdminCert, err := ioutil.ReadFile(adminCertPath)
   876  			Expect(err).NotTo(HaveOccurred())
   877  
   878  			expiredAdminCert, earlyCACert := expireCertificate(originalAdminCert, ordererCACert, ordererCAKey, time.Now())
   879  			err = ioutil.WriteFile(adminCertPath, expiredAdminCert, 0o600)
   880  			Expect(err).NotTo(HaveOccurred())
   881  
   882  			adminPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   883  				ordererDomain, "msp", "admincerts", fmt.Sprintf("Admin@%s-cert.pem", ordererDomain))
   884  			err = ioutil.WriteFile(adminPath, expiredAdminCert, 0o600)
   885  			Expect(err).NotTo(HaveOccurred())
   886  
   887  			err = ioutil.WriteFile(ordererCACertPath, earlyCACert, 0o600)
   888  			Expect(err).NotTo(HaveOccurred())
   889  
   890  			ordererCACertPath = network.OrdererCACert(orderer)
   891  			err = ioutil.WriteFile(ordererCACertPath, earlyCACert, 0o600)
   892  			Expect(err).NotTo(HaveOccurred())
   893  
   894  			By("Regenerating config")
   895  			sess, err := network.ConfigTxGen(commands.OutputBlock{
   896  				ChannelID:   network.SystemChannel.Name,
   897  				Profile:     network.SystemChannel.Profile,
   898  				ConfigPath:  network.RootDir,
   899  				OutputBlock: network.OutputBlockPath(network.SystemChannel.Name),
   900  			})
   901  			Expect(err).NotTo(HaveOccurred())
   902  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   903  
   904  			runner := network.OrdererRunner(orderer)
   905  			runner.Command.Env = append(runner.Command.Env, "FABRIC_LOGGING_SPEC=debug")
   906  			ordererProc = ifrit.Invoke(runner)
   907  
   908  			By("Waiting for orderer to elect a leader")
   909  			findLeader([]*ginkgomon.Runner{runner})
   910  
   911  			By("Creating config update that adds another orderer admin")
   912  			bootBlockPath := filepath.Join(network.RootDir, fmt.Sprintf("%s_block.pb", network.SystemChannel.Name))
   913  			bootBlock, err := ioutil.ReadFile(bootBlockPath)
   914  			Expect(err).NotTo(HaveOccurred())
   915  
   916  			current := configFromBootstrapBlock(bootBlock)
   917  			updatedConfig := addAdminCertToConfig(current, originalAdminCert)
   918  
   919  			tempDir, err := ioutil.TempDir("", "adminExpirationTest")
   920  			Expect(err).NotTo(HaveOccurred())
   921  
   922  			configBlockFile := filepath.Join(tempDir, "update.pb")
   923  			defer os.RemoveAll(tempDir)
   924  			nwo.ComputeUpdateOrdererConfig(configBlockFile, network, network.SystemChannel.Name, current, updatedConfig, peer)
   925  
   926  			updateTransaction, err := ioutil.ReadFile(configBlockFile)
   927  			Expect(err).NotTo(HaveOccurred())
   928  
   929  			By("Creating config update")
   930  			channelCreateTxn := createConfigTx(updateTransaction, network.SystemChannel.Name, network, orderer, peer)
   931  
   932  			By("Updating channel config and failing")
   933  			p, err := ordererclient.Broadcast(network, orderer, channelCreateTxn)
   934  			Expect(err).NotTo(HaveOccurred())
   935  			Expect(p.Status).To(Equal(common.Status_BAD_REQUEST))
   936  			Expect(p.Info).To(ContainSubstring("broadcast client identity expired"))
   937  
   938  			By("Attempting to fetch a block from orderer and failing")
   939  			denv := CreateDeliverEnvelope(network, orderer, 0, network.SystemChannel.Name)
   940  			Expect(denv).NotTo(BeNil())
   941  
   942  			block, err := ordererclient.Deliver(network, orderer, denv)
   943  			Expect(err).To(HaveOccurred())
   944  			Expect(block).To(BeNil())
   945  			Eventually(runner.Err(), time.Minute, time.Second).Should(gbytes.Say("deliver client identity expired"))
   946  
   947  			By("Killing orderer")
   948  			ordererProc.Signal(syscall.SIGTERM)
   949  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   950  
   951  			By("Launching orderers again")
   952  			runner = network.OrdererRunner(orderer)
   953  			runner.Command.Env = append(runner.Command.Env, "ORDERER_GENERAL_AUTHENTICATION_NOEXPIRATIONCHECKS=true")
   954  			ordererProc = ifrit.Invoke(runner)
   955  
   956  			By("Waiting for orderer to launch again")
   957  			findLeader([]*ginkgomon.Runner{runner})
   958  
   959  			By("Updating channel config and succeeding")
   960  			p, err = ordererclient.Broadcast(network, orderer, channelCreateTxn)
   961  			Expect(err).NotTo(HaveOccurred())
   962  			Expect(p.Status).To(Equal(common.Status_SUCCESS))
   963  
   964  			By("Fetching a block from the orderer and succeeding")
   965  			block = FetchBlock(network, orderer, 1, network.SystemChannel.Name)
   966  			Expect(block).NotTo(BeNil())
   967  
   968  			By("Restore the original admin cert")
   969  			err = ioutil.WriteFile(adminCertPath, originalAdminCert, 0o600)
   970  			Expect(err).NotTo(HaveOccurred())
   971  
   972  			By("Ensure we can fetch the block using our original un-expired admin cert")
   973  			ccb := func() uint64 {
   974  				return nwo.GetConfigBlock(network, peer, orderer, network.SystemChannel.Name).Header.Number
   975  			}
   976  			Eventually(ccb, network.EventuallyTimeout).Should(Equal(uint64(1)))
   977  		})
   978  	})
   979  })
   980  
   981  func findLeader(ordererRunners []*ginkgomon.Runner) int {
   982  	var wg sync.WaitGroup
   983  	wg.Add(len(ordererRunners))
   984  
   985  	findLeader := func(runner *ginkgomon.Runner) int {
   986  		Eventually(runner.Err(), time.Minute, time.Second).Should(gbytes.Say("Raft leader changed: [0-9] -> "))
   987  
   988  		idBuff := make([]byte, 1)
   989  		_, err := runner.Err().Read(idBuff)
   990  		Expect(err).NotTo(HaveOccurred())
   991  
   992  		newLeader, err := strconv.ParseInt(string(idBuff), 10, 32)
   993  		Expect(err).To(BeNil())
   994  		return int(newLeader)
   995  	}
   996  
   997  	leaders := make(chan int, len(ordererRunners))
   998  
   999  	for _, runner := range ordererRunners {
  1000  		go func(runner *ginkgomon.Runner) {
  1001  			defer GinkgoRecover()
  1002  			defer wg.Done()
  1003  
  1004  			for {
  1005  				leader := findLeader(runner)
  1006  				if leader != 0 {
  1007  					leaders <- leader
  1008  					break
  1009  				}
  1010  			}
  1011  		}(runner)
  1012  	}
  1013  
  1014  	wg.Wait()
  1015  
  1016  	close(leaders)
  1017  	firstLeader := <-leaders
  1018  	for leader := range leaders {
  1019  		if firstLeader != leader {
  1020  			Fail(fmt.Sprintf("First leader is %d but saw %d also as a leader", firstLeader, leader))
  1021  		}
  1022  	}
  1023  
  1024  	return firstLeader
  1025  }
  1026  
  1027  func renewOrdererCertificates(network *nwo.Network, orderers ...*nwo.Orderer) {
  1028  	if len(orderers) == 0 {
  1029  		return
  1030  	}
  1031  	ordererDomain := network.Organization(orderers[0].Organization).Domain
  1032  	ordererTLSCAKeyPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
  1033  		ordererDomain, "tlsca", "priv_sk")
  1034  
  1035  	ordererTLSCAKey, err := ioutil.ReadFile(ordererTLSCAKeyPath)
  1036  	Expect(err).NotTo(HaveOccurred())
  1037  
  1038  	ordererTLSCACertPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
  1039  		ordererDomain, "tlsca", fmt.Sprintf("tlsca.%s-cert.pem", ordererDomain))
  1040  	ordererTLSCACert, err := ioutil.ReadFile(ordererTLSCACertPath)
  1041  	Expect(err).NotTo(HaveOccurred())
  1042  
  1043  	serverTLSCerts := map[string][]byte{}
  1044  	for _, orderer := range orderers {
  1045  		tlsCertPath := filepath.Join(network.OrdererLocalTLSDir(orderer), "server.crt")
  1046  		serverTLSCerts[tlsCertPath], err = ioutil.ReadFile(tlsCertPath)
  1047  		Expect(err).NotTo(HaveOccurred())
  1048  	}
  1049  
  1050  	for filePath, certPEM := range serverTLSCerts {
  1051  		renewedCert, _ := expireCertificate(certPEM, ordererTLSCACert, ordererTLSCAKey, time.Now().Add(time.Hour))
  1052  		err = ioutil.WriteFile(filePath, renewedCert, 0o600)
  1053  		Expect(err).NotTo(HaveOccurred())
  1054  	}
  1055  }
  1056  
  1057  func expireCertificate(certPEM, caCertPEM, caKeyPEM []byte, expirationTime time.Time) (expiredcertPEM []byte, earlyMadeCACertPEM []byte) {
  1058  	keyAsDER, _ := pem.Decode(caKeyPEM)
  1059  	caKeyWithoutType, err := x509.ParsePKCS8PrivateKey(keyAsDER.Bytes)
  1060  	Expect(err).NotTo(HaveOccurred())
  1061  	caKey := caKeyWithoutType.(*ecdsa.PrivateKey)
  1062  
  1063  	caCertAsDER, _ := pem.Decode(caCertPEM)
  1064  	caCert, err := x509.ParseCertificate(caCertAsDER.Bytes)
  1065  	Expect(err).NotTo(HaveOccurred())
  1066  
  1067  	certAsDER, _ := pem.Decode(certPEM)
  1068  	cert, err := x509.ParseCertificate(certAsDER.Bytes)
  1069  	Expect(err).NotTo(HaveOccurred())
  1070  
  1071  	cert.Raw = nil
  1072  	caCert.Raw = nil
  1073  	// The certificate was made 1 hour ago
  1074  	cert.NotBefore = time.Now().Add((-1) * time.Hour)
  1075  	// As well as the CA certificate
  1076  	caCert.NotBefore = time.Now().Add((-1) * time.Hour)
  1077  	// The certificate expires now
  1078  	cert.NotAfter = expirationTime
  1079  
  1080  	// The CA signs the certificate
  1081  	certBytes, err := x509.CreateCertificate(rand.Reader, cert, caCert, cert.PublicKey, caKey)
  1082  	Expect(err).NotTo(HaveOccurred())
  1083  
  1084  	// The CA signs its own certificate
  1085  	caCertBytes, err := x509.CreateCertificate(rand.Reader, caCert, caCert, caCert.PublicKey, caKey)
  1086  	Expect(err).NotTo(HaveOccurred())
  1087  
  1088  	expiredcertPEM = pem.EncodeToMemory(&pem.Block{Bytes: certBytes, Type: "CERTIFICATE"})
  1089  	earlyMadeCACertPEM = pem.EncodeToMemory(&pem.Block{Bytes: caCertBytes, Type: "CERTIFICATE"})
  1090  	return
  1091  }
  1092  
  1093  func createConfigTx(txData []byte, channelName string, network *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer) *common.Envelope {
  1094  	ctxEnv, err := protoutil.UnmarshalEnvelope(txData)
  1095  	Expect(err).NotTo(HaveOccurred())
  1096  
  1097  	payload, err := protoutil.UnmarshalPayload(ctxEnv.Payload)
  1098  	Expect(err).NotTo(HaveOccurred())
  1099  
  1100  	configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(payload.Data)
  1101  	Expect(err).NotTo(HaveOccurred())
  1102  
  1103  	signer := network.OrdererUserSigner(orderer, "Admin")
  1104  	signConfigUpdate(signer, configUpdateEnv)
  1105  
  1106  	env, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG_UPDATE, channelName, signer, configUpdateEnv, 0, 0)
  1107  	Expect(err).NotTo(HaveOccurred())
  1108  
  1109  	return env
  1110  }
  1111  
  1112  func signConfigUpdate(signer *nwo.SigningIdentity, configUpdateEnv *common.ConfigUpdateEnvelope) *common.ConfigUpdateEnvelope {
  1113  	sigHeader, err := protoutil.NewSignatureHeader(signer)
  1114  	Expect(err).NotTo(HaveOccurred())
  1115  
  1116  	configSig := &common.ConfigSignature{
  1117  		SignatureHeader: protoutil.MarshalOrPanic(sigHeader),
  1118  	}
  1119  
  1120  	configSig.Signature, err = signer.Sign(util.ConcatenateBytes(configSig.SignatureHeader, configUpdateEnv.ConfigUpdate))
  1121  	Expect(err).NotTo(HaveOccurred())
  1122  
  1123  	configUpdateEnv.Signatures = append(configUpdateEnv.Signatures, configSig)
  1124  	return configUpdateEnv
  1125  }
  1126  
  1127  func addAdminCertToConfig(originalConfig *common.Config, additionalAdmin []byte) *common.Config {
  1128  	updatedConfig := proto.Clone(originalConfig).(*common.Config)
  1129  
  1130  	rawMSPConfig := updatedConfig.ChannelGroup.Groups["Orderer"].Groups["OrdererOrg"].Values["MSP"]
  1131  	mspConfig := &msp.MSPConfig{}
  1132  	err := proto.Unmarshal(rawMSPConfig.Value, mspConfig)
  1133  	Expect(err).NotTo(HaveOccurred())
  1134  
  1135  	fabricConfig := &msp.FabricMSPConfig{}
  1136  	err = proto.Unmarshal(mspConfig.Config, fabricConfig)
  1137  	Expect(err).NotTo(HaveOccurred())
  1138  
  1139  	fabricConfig.Admins = append(fabricConfig.Admins, additionalAdmin)
  1140  	mspConfig.Config = protoutil.MarshalOrPanic(fabricConfig)
  1141  
  1142  	rawMSPConfig.Value = protoutil.MarshalOrPanic(mspConfig)
  1143  	return updatedConfig
  1144  }
  1145  
  1146  func configFromBootstrapBlock(bootstrapBlock []byte) *common.Config {
  1147  	block := &common.Block{}
  1148  	err := proto.Unmarshal(bootstrapBlock, block)
  1149  	Expect(err).NotTo(HaveOccurred())
  1150  	return configFromBlock(block)
  1151  }
  1152  
  1153  func configFromBlock(block *common.Block) *common.Config {
  1154  	envelope, err := protoutil.GetEnvelopeFromBlock(block.Data.Data[0])
  1155  	Expect(err).NotTo(HaveOccurred())
  1156  
  1157  	payload, err := protoutil.UnmarshalPayload(envelope.Payload)
  1158  	Expect(err).NotTo(HaveOccurred())
  1159  
  1160  	configEnv := &common.ConfigEnvelope{}
  1161  	err = proto.Unmarshal(payload.Data, configEnv)
  1162  	Expect(err).NotTo(HaveOccurred())
  1163  
  1164  	return configEnv.Config
  1165  }
  1166  
  1167  func fetchConfig(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, port nwo.PortName, channel string, tlsHandshakeTimeShift time.Duration) *common.Config {
  1168  	tempDir, err := ioutil.TempDir(n.RootDir, "fetchConfig")
  1169  	Expect(err).NotTo(HaveOccurred())
  1170  	defer os.RemoveAll(tempDir)
  1171  
  1172  	output := filepath.Join(tempDir, "config_block.pb")
  1173  	fetchConfigBlock(n, peer, orderer, port, n.SystemChannel.Name, output, tlsHandshakeTimeShift)
  1174  	configBlock := nwo.UnmarshalBlockFromFile(output)
  1175  	return configFromBlock(configBlock)
  1176  }
  1177  
  1178  func fetchConfigBlock(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, port nwo.PortName, channel, output string, tlsHandshakeTimeShift time.Duration) {
  1179  	fetch := func() int {
  1180  		sess, err := n.OrdererAdminSession(orderer, peer, commands.ChannelFetch{
  1181  			ChannelID:             channel,
  1182  			Block:                 "config",
  1183  			Orderer:               n.OrdererAddress(orderer, port),
  1184  			OutputFile:            output,
  1185  			ClientAuth:            n.ClientAuthRequired,
  1186  			TLSHandshakeTimeShift: tlsHandshakeTimeShift,
  1187  		})
  1188  		Expect(err).NotTo(HaveOccurred())
  1189  		code := sess.Wait(n.EventuallyTimeout).ExitCode()
  1190  		if code == 0 {
  1191  			Expect(sess.Err).To(gbytes.Say("Received block: "))
  1192  		}
  1193  		return code
  1194  	}
  1195  	Eventually(fetch, n.EventuallyTimeout).Should(Equal(0))
  1196  }
  1197  
  1198  func currentConfigBlockNumber(n *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, port nwo.PortName, channel string, tlsHandshakeTimeShift time.Duration) uint64 {
  1199  	tempDir, err := ioutil.TempDir(n.RootDir, "currentConfigBlock")
  1200  	Expect(err).NotTo(HaveOccurred())
  1201  	defer os.RemoveAll(tempDir)
  1202  
  1203  	output := filepath.Join(tempDir, "config_block.pb")
  1204  	fetchConfigBlock(n, peer, orderer, port, channel, output, tlsHandshakeTimeShift)
  1205  	configBlock := nwo.UnmarshalBlockFromFile(output)
  1206  	return configBlock.Header.Number
  1207  }
  1208  
  1209  func updateOrdererConfig(n *nwo.Network, orderer *nwo.Orderer, port nwo.PortName, channel string, tlsHandshakeTimeShift time.Duration, current, updated *common.Config, submitter *nwo.Peer, additionalSigners ...*nwo.Orderer) {
  1210  	tempDir, err := ioutil.TempDir(n.RootDir, "updateConfig")
  1211  	Expect(err).NotTo(HaveOccurred())
  1212  	updateFile := filepath.Join(tempDir, "update.pb")
  1213  	defer os.RemoveAll(tempDir)
  1214  
  1215  	currentBlockNumber := currentConfigBlockNumber(n, submitter, orderer, port, channel, tlsHandshakeTimeShift)
  1216  	nwo.ComputeUpdateOrdererConfig(updateFile, n, channel, current, updated, submitter, additionalSigners...)
  1217  
  1218  	Eventually(func() bool {
  1219  		sess, err := n.OrdererAdminSession(orderer, submitter, commands.ChannelUpdate{
  1220  			ChannelID:             channel,
  1221  			Orderer:               n.OrdererAddress(orderer, port),
  1222  			File:                  updateFile,
  1223  			ClientAuth:            n.ClientAuthRequired,
  1224  			TLSHandshakeTimeShift: tlsHandshakeTimeShift,
  1225  		})
  1226  		Expect(err).NotTo(HaveOccurred())
  1227  
  1228  		sess.Wait(n.EventuallyTimeout)
  1229  		if sess.ExitCode() != 0 {
  1230  			return false
  1231  		}
  1232  
  1233  		return strings.Contains(string(sess.Err.Contents()), "Successfully submitted channel update")
  1234  	}, n.EventuallyTimeout).Should(BeTrue())
  1235  
  1236  	ccb := func() uint64 {
  1237  		return currentConfigBlockNumber(n, submitter, orderer, port, channel, tlsHandshakeTimeShift)
  1238  	}
  1239  	Eventually(ccb, n.EventuallyTimeout).Should(BeNumerically(">", currentBlockNumber))
  1240  }