github.com/Hnampk/my-fabric@v0.0.0-20201028083322-75069da399c0/integration/raft/cft_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  	"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  	"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  	"github.com/hyperledger/fabric/cmd/common/signer"
    29  	"github.com/hyperledger/fabric/common/configtx"
    30  	"github.com/hyperledger/fabric/common/util"
    31  	"github.com/hyperledger/fabric/integration/nwo"
    32  	"github.com/hyperledger/fabric/integration/nwo/commands"
    33  	"github.com/hyperledger/fabric/protoutil"
    34  	. "github.com/onsi/ginkgo"
    35  	. "github.com/onsi/gomega"
    36  	"github.com/onsi/gomega/gbytes"
    37  	"github.com/onsi/gomega/gexec"
    38  	"github.com/tedsuo/ifrit"
    39  	"github.com/tedsuo/ifrit/ginkgomon"
    40  	"github.com/tedsuo/ifrit/grouper"
    41  )
    42  
    43  var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
    44  	var (
    45  		testDir string
    46  		client  *docker.Client
    47  		network *nwo.Network
    48  		peer    *nwo.Peer
    49  
    50  		ordererProc, o1Proc, o2Proc, o3Proc ifrit.Process
    51  	)
    52  
    53  	BeforeEach(func() {
    54  		var err error
    55  		testDir, err = ioutil.TempDir("", "e2e")
    56  		Expect(err).NotTo(HaveOccurred())
    57  
    58  		client, err = docker.NewClientFromEnv()
    59  		Expect(err).NotTo(HaveOccurred())
    60  	})
    61  
    62  	AfterEach(func() {
    63  		for _, oProc := range []ifrit.Process{o1Proc, o2Proc, o3Proc} {
    64  			if oProc != nil {
    65  				oProc.Signal(syscall.SIGTERM)
    66  				Eventually(oProc.Wait(), network.EventuallyTimeout).Should(Receive())
    67  			}
    68  		}
    69  
    70  		if ordererProc != nil {
    71  			ordererProc.Signal(syscall.SIGTERM)
    72  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
    73  		}
    74  
    75  		if network != nil {
    76  			network.Cleanup()
    77  		}
    78  		os.RemoveAll(testDir)
    79  	})
    80  
    81  	When("orderer stops and restarts", func() {
    82  		It("keeps network up and running", func() {
    83  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
    84  
    85  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
    86  			peer = network.Peer("Org1", "peer0")
    87  
    88  			network.GenerateConfigTree()
    89  			network.Bootstrap()
    90  
    91  			o1Runner := network.OrdererRunner(o1)
    92  			orderers := grouper.Members{
    93  				{Name: o2.ID(), Runner: network.OrdererRunner(o2)},
    94  				{Name: o3.ID(), Runner: network.OrdererRunner(o3)},
    95  			}
    96  			ordererGroup := grouper.NewParallel(syscall.SIGTERM, orderers)
    97  
    98  			o1Proc = ifrit.Invoke(o1Runner)
    99  			ordererProc = ifrit.Invoke(ordererGroup)
   100  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   101  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   102  
   103  			findLeader([]*ginkgomon.Runner{o1Runner})
   104  
   105  			By("performing operation with orderer1")
   106  			env := CreateBroadcastEnvelope(network, o1, network.SystemChannel.Name, []byte("foo"))
   107  			resp, err := nwo.Broadcast(network, o1, env)
   108  			Expect(err).NotTo(HaveOccurred())
   109  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   110  
   111  			block := FetchBlock(network, o1, 1, network.SystemChannel.Name)
   112  			Expect(block).NotTo(BeNil())
   113  
   114  			By("killing orderer1")
   115  			o1Proc.Signal(syscall.SIGKILL)
   116  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive(MatchError("exit status 137")))
   117  
   118  			By("broadcasting envelope to running orderer")
   119  			resp, err = nwo.Broadcast(network, o2, env)
   120  			Expect(err).NotTo(HaveOccurred())
   121  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   122  
   123  			block = FetchBlock(network, o2, 2, network.SystemChannel.Name)
   124  			Expect(block).NotTo(BeNil())
   125  
   126  			By("restarting orderer1")
   127  			o1Runner = network.OrdererRunner(o1)
   128  			o1Proc = ifrit.Invoke(o1Runner)
   129  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   130  			findLeader([]*ginkgomon.Runner{o1Runner})
   131  
   132  			By("broadcasting envelope to restarted orderer")
   133  			resp, err = nwo.Broadcast(network, o1, env)
   134  			Expect(err).NotTo(HaveOccurred())
   135  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   136  
   137  			blko1 := FetchBlock(network, o1, 3, network.SystemChannel.Name)
   138  			blko2 := FetchBlock(network, o2, 3, network.SystemChannel.Name)
   139  
   140  			Expect(blko1.Header.DataHash).To(Equal(blko2.Header.DataHash))
   141  		})
   142  	})
   143  
   144  	When("an orderer is behind the latest snapshot on leader", func() {
   145  		It("catches up using the block stored in snapshot", func() {
   146  			// Steps:
   147  			// - start o2 & o3
   148  			// - send several transactions so snapshot is created
   149  			// - kill o2 & o3, so that entries prior to snapshot are not in memory upon restart
   150  			// - start o1 & o2
   151  			// - assert that o1 can catch up with o2 using snapshot
   152  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   153  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   154  			peer = network.Peer("Org1", "peer0")
   155  
   156  			network.GenerateConfigTree()
   157  			network.Bootstrap()
   158  
   159  			orderers := grouper.Members{
   160  				{Name: o2.ID(), Runner: network.OrdererRunner(o2)},
   161  				{Name: o3.ID(), Runner: network.OrdererRunner(o3)},
   162  			}
   163  			ordererGroup := grouper.NewParallel(syscall.SIGTERM, orderers)
   164  
   165  			By("Starting 2/3 of cluster")
   166  			ordererProc = ifrit.Invoke(ordererGroup)
   167  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   168  
   169  			By("Creating testchannel")
   170  			channelID := "testchannel"
   171  			network.CreateChannel(channelID, o2, peer)
   172  
   173  			By("Submitting several transactions to trigger snapshot")
   174  			o2SnapDir := path.Join(network.RootDir, "orderers", o2.ID(), "etcdraft", "snapshot")
   175  
   176  			env := CreateBroadcastEnvelope(network, o2, channelID, make([]byte, 2000))
   177  			for i := 1; i <= 4; i++ { // 4 < MaxSnapshotFiles(5), so that no snapshot is pruned
   178  				// Note that MaxMessageCount is 1 be default, so every tx results in a new block
   179  				resp, err := nwo.Broadcast(network, o2, env)
   180  				Expect(err).NotTo(HaveOccurred())
   181  				Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   182  
   183  				// Assert that new snapshot file is created before broadcasting next tx,
   184  				// so that number of snapshots is deterministic. Otherwise, it is not
   185  				// guaranteed that every block triggers a snapshot file being created,
   186  				// due to the mechanism to prevent excessive snapshotting.
   187  				Eventually(func() int {
   188  					files, err := ioutil.ReadDir(path.Join(o2SnapDir, channelID))
   189  					Expect(err).NotTo(HaveOccurred())
   190  					return len(files)
   191  				}, network.EventuallyTimeout).Should(Equal(i)) // snapshot interval is 1 KB, every block triggers snapshot
   192  			}
   193  
   194  			By("Killing orderers so they don't have blocks prior to latest snapshot in the memory")
   195  			ordererProc.Signal(syscall.SIGKILL)
   196  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   197  
   198  			By("Starting lagged orderer and one of up-to-date orderers")
   199  			orderers = grouper.Members{
   200  				{Name: o1.ID(), Runner: network.OrdererRunner(o1)},
   201  				{Name: o2.ID(), Runner: network.OrdererRunner(o2)},
   202  			}
   203  			ordererGroup = grouper.NewParallel(syscall.SIGTERM, orderers)
   204  			ordererProc = ifrit.Invoke(ordererGroup)
   205  			Eventually(ordererProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   206  
   207  			o1SnapDir := path.Join(network.RootDir, "orderers", o1.ID(), "etcdraft", "snapshot")
   208  
   209  			By("Asserting that orderer1 has snapshot dir for both system and application channel")
   210  			Eventually(func() int {
   211  				files, err := ioutil.ReadDir(o1SnapDir)
   212  				Expect(err).NotTo(HaveOccurred())
   213  				return len(files)
   214  			}, network.EventuallyTimeout).Should(Equal(2))
   215  
   216  			By("Asserting that orderer1 receives and persists snapshot")
   217  			Eventually(func() int {
   218  				files, err := ioutil.ReadDir(path.Join(o1SnapDir, channelID))
   219  				Expect(err).NotTo(HaveOccurred())
   220  				return len(files)
   221  			}, network.EventuallyTimeout).Should(Equal(1))
   222  
   223  			By("Asserting cluster is still functional")
   224  			env = CreateBroadcastEnvelope(network, o1, channelID, make([]byte, 1000))
   225  			resp, err := nwo.Broadcast(network, o1, env)
   226  			Expect(err).NotTo(HaveOccurred())
   227  			Expect(resp.Status).To(Equal(common.Status_SUCCESS))
   228  
   229  			blko1 := FetchBlock(network, o1, 5, channelID)
   230  			blko2 := FetchBlock(network, o2, 5, channelID)
   231  
   232  			Expect(blko1.Header.DataHash).To(Equal(blko2.Header.DataHash))
   233  		})
   234  	})
   235  
   236  	When("The leader dies", func() {
   237  		It("Elects a new leader", func() {
   238  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   239  
   240  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   241  
   242  			network.GenerateConfigTree()
   243  			network.Bootstrap()
   244  
   245  			By("Running the orderer nodes")
   246  			o1Runner := network.OrdererRunner(o1)
   247  			o2Runner := network.OrdererRunner(o2)
   248  			o3Runner := network.OrdererRunner(o3)
   249  
   250  			o1Proc = ifrit.Invoke(o1Runner)
   251  			o2Proc = ifrit.Invoke(o2Runner)
   252  			o3Proc = ifrit.Invoke(o3Runner)
   253  
   254  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   255  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   256  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   257  
   258  			By("Waiting for them to elect a leader")
   259  			ordererProcesses := []ifrit.Process{o1Proc, o2Proc, o3Proc}
   260  			remainingAliveRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   261  			leader := findLeader(remainingAliveRunners)
   262  
   263  			leaderIndex := leader - 1
   264  			By(fmt.Sprintf("Killing the leader (%d)", leader))
   265  			ordererProcesses[leaderIndex].Signal(syscall.SIGTERM)
   266  			By("Waiting for it to die")
   267  			Eventually(ordererProcesses[leaderIndex].Wait(), network.EventuallyTimeout).Should(Receive())
   268  
   269  			// Remove the leader from the orderer runners
   270  			remainingAliveRunners = append(remainingAliveRunners[:leaderIndex], remainingAliveRunners[leaderIndex+1:]...)
   271  
   272  			By("Waiting for a new leader to be elected")
   273  			leader = findLeader(remainingAliveRunners)
   274  			By(fmt.Sprintf("Orderer %d took over as a leader", leader))
   275  		})
   276  	})
   277  
   278  	When("Leader cannot reach quorum", func() {
   279  		It("Steps down", func() {
   280  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   281  
   282  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   283  			orderers := []*nwo.Orderer{o1, o2, o3}
   284  			peer = network.Peer("Org1", "peer0")
   285  			network.GenerateConfigTree()
   286  			network.Bootstrap()
   287  
   288  			By("Running the orderer nodes")
   289  			o1Runner := network.OrdererRunner(o1)
   290  			o2Runner := network.OrdererRunner(o2)
   291  			o3Runner := network.OrdererRunner(o3)
   292  			oRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   293  
   294  			o1Proc = ifrit.Invoke(o1Runner)
   295  			o2Proc = ifrit.Invoke(o2Runner)
   296  			o3Proc = ifrit.Invoke(o3Runner)
   297  
   298  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   299  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   300  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   301  
   302  			By("Waiting for them to elect a leader")
   303  			ordererProcesses := []ifrit.Process{o1Proc, o2Proc, o3Proc}
   304  			remainingAliveRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
   305  			leaderID := findLeader(remainingAliveRunners)
   306  			leaderIndex := leaderID - 1
   307  			leader := orderers[leaderIndex]
   308  
   309  			followerIndices := func() []int {
   310  				var f []int
   311  				for i := range ordererProcesses {
   312  					if leaderIndex != i {
   313  						f = append(f, i)
   314  					}
   315  				}
   316  
   317  				return f
   318  			}()
   319  
   320  			By(fmt.Sprintf("Killing two followers (%d and %d)", followerIndices[0]+1, followerIndices[1]+1))
   321  			ordererProcesses[followerIndices[0]].Signal(syscall.SIGTERM)
   322  			ordererProcesses[followerIndices[1]].Signal(syscall.SIGTERM)
   323  
   324  			By("Waiting for followers to die")
   325  			// This significantly slows test (~10s). However, reducing ElectionTimeout
   326  			// would introduce some flakes when disk write is exceptionally slow.
   327  			Eventually(ordererProcesses[followerIndices[0]].Wait(), network.EventuallyTimeout).Should(Receive())
   328  			Eventually(ordererProcesses[followerIndices[1]].Wait(), network.EventuallyTimeout).Should(Receive())
   329  
   330  			By("Waiting for leader to step down")
   331  			Eventually(oRunners[leaderIndex].Err(), time.Minute, time.Second).Should(gbytes.Say(fmt.Sprintf("%d stepped down to follower since quorum is not active", leaderID)))
   332  
   333  			By("Submitting tx to leader")
   334  			// This should fail because current leader steps down
   335  			// and there is no leader at this point of time
   336  			env := CreateBroadcastEnvelope(network, leader, network.SystemChannel.Name, []byte("foo"))
   337  			resp, err := nwo.Broadcast(network, leader, env)
   338  			Expect(err).NotTo(HaveOccurred())
   339  			Expect(resp.Status).To(Equal(common.Status_SERVICE_UNAVAILABLE))
   340  		})
   341  	})
   342  
   343  	When("orderer TLS certificates expire", func() {
   344  		It("is still possible to recover", func() {
   345  			network = nwo.New(nwo.MultiNodeEtcdRaft(), testDir, client, StartPort(), components)
   346  
   347  			o1, o2, o3 := network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   348  			peer = network.Peer("Org1", "peer0")
   349  
   350  			network.GenerateConfigTree()
   351  			network.Bootstrap()
   352  
   353  			ordererDomain := network.Organization(o1.Organization).Domain
   354  			ordererTLSCAKeyPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   355  				ordererDomain, "tlsca", "priv_sk")
   356  
   357  			ordererTLSCAKey, err := ioutil.ReadFile(ordererTLSCAKeyPath)
   358  			Expect(err).NotTo(HaveOccurred())
   359  
   360  			ordererTLSCACertPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   361  				ordererDomain, "tlsca", fmt.Sprintf("tlsca.%s-cert.pem", ordererDomain))
   362  			ordererTLSCACert, err := ioutil.ReadFile(ordererTLSCACertPath)
   363  			Expect(err).NotTo(HaveOccurred())
   364  
   365  			serverTLSCerts := make(map[string][]byte)
   366  			for _, orderer := range []*nwo.Orderer{o1, o2, o3} {
   367  				tlsCertPath := filepath.Join(network.OrdererLocalTLSDir(orderer), "server.crt")
   368  				serverTLSCerts[tlsCertPath], err = ioutil.ReadFile(tlsCertPath)
   369  				Expect(err).NotTo(HaveOccurred())
   370  			}
   371  
   372  			By("Expiring orderer TLS certificates")
   373  			for filePath, certPEM := range serverTLSCerts {
   374  				expiredCert, earlyMadeCACert := expireCertificate(certPEM, ordererTLSCACert, ordererTLSCAKey)
   375  				err = ioutil.WriteFile(filePath, expiredCert, 600)
   376  				Expect(err).NotTo(HaveOccurred())
   377  
   378  				err = ioutil.WriteFile(ordererTLSCACertPath, earlyMadeCACert, 600)
   379  				Expect(err).NotTo(HaveOccurred())
   380  			}
   381  
   382  			By("Regenerating config")
   383  			sess, err := network.ConfigTxGen(commands.OutputBlock{
   384  				ChannelID:   network.SystemChannel.Name,
   385  				Profile:     network.SystemChannel.Profile,
   386  				ConfigPath:  network.RootDir,
   387  				OutputBlock: network.OutputBlockPath(network.SystemChannel.Name),
   388  			})
   389  			Expect(err).NotTo(HaveOccurred())
   390  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   391  
   392  			By("Running the orderer nodes")
   393  			o1Runner := network.OrdererRunner(o1)
   394  			o2Runner := network.OrdererRunner(o2)
   395  			o3Runner := network.OrdererRunner(o3)
   396  
   397  			o1Proc = ifrit.Invoke(o1Runner)
   398  			o2Proc = ifrit.Invoke(o2Runner)
   399  			o3Proc = ifrit.Invoke(o3Runner)
   400  
   401  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   402  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   403  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   404  
   405  			By("Waiting for TLS handshakes to fail")
   406  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   407  			Eventually(o2Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   408  			Eventually(o3Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   409  
   410  			By("Killing orderers")
   411  			o1Proc.Signal(syscall.SIGTERM)
   412  			o2Proc.Signal(syscall.SIGTERM)
   413  			o3Proc.Signal(syscall.SIGTERM)
   414  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   415  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   416  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   417  
   418  			o1Runner = network.OrdererRunner(o1)
   419  			o2Runner = network.OrdererRunner(o2)
   420  			o3Runner = network.OrdererRunner(o3)
   421  
   422  			By("Launching orderers with a clustered timeshift")
   423  			for _, orderer := range []*nwo.Orderer{o1, o2, o3} {
   424  				ordererConfig := network.ReadOrdererConfig(orderer)
   425  				ordererConfig.General.Cluster.TLSHandshakeTimeShift = 5 * time.Minute
   426  				network.WriteOrdererConfig(orderer, ordererConfig)
   427  			}
   428  
   429  			o1Proc = ifrit.Invoke(o1Runner)
   430  			o2Proc = ifrit.Invoke(o2Runner)
   431  			o3Proc = ifrit.Invoke(o3Runner)
   432  
   433  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   434  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   435  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   436  
   437  			By("Waiting for a leader to be elected")
   438  			findLeader([]*ginkgomon.Runner{o1Runner, o2Runner, o3Runner})
   439  
   440  			By("Killing orderers")
   441  			o1Proc.Signal(syscall.SIGTERM)
   442  			o2Proc.Signal(syscall.SIGTERM)
   443  			o3Proc.Signal(syscall.SIGTERM)
   444  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   445  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   446  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   447  
   448  			o1Runner = network.OrdererRunner(o1)
   449  			o2Runner = network.OrdererRunner(o2)
   450  			o3Runner = network.OrdererRunner(o3)
   451  
   452  			By("Launching orderers again without a general timeshift re-using the cluster port")
   453  			for _, orderer := range []*nwo.Orderer{o1, o2, o3} {
   454  				ordererConfig := network.ReadOrdererConfig(orderer)
   455  				ordererConfig.General.ListenPort = ordererConfig.General.Cluster.ListenPort
   456  				ordererConfig.General.TLS.Certificate = ordererConfig.General.Cluster.ServerCertificate
   457  				ordererConfig.General.TLS.PrivateKey = ordererConfig.General.Cluster.ServerPrivateKey
   458  				ordererConfig.General.Cluster.TLSHandshakeTimeShift = 0
   459  				ordererConfig.General.Cluster.ListenPort = 0
   460  				ordererConfig.General.Cluster.ListenAddress = ""
   461  				ordererConfig.General.Cluster.ServerCertificate = ""
   462  				ordererConfig.General.Cluster.ServerPrivateKey = ""
   463  				network.WriteOrdererConfig(orderer, ordererConfig)
   464  			}
   465  
   466  			o1Proc = ifrit.Invoke(o1Runner)
   467  			o2Proc = ifrit.Invoke(o2Runner)
   468  			o3Proc = ifrit.Invoke(o3Runner)
   469  
   470  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   471  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   472  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   473  
   474  			By("Waiting for TLS handshakes to fail")
   475  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   476  			Eventually(o2Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   477  			Eventually(o3Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("tls: bad certificate"))
   478  
   479  			By("Killing orderers")
   480  			o1Proc.Signal(syscall.SIGTERM)
   481  			o2Proc.Signal(syscall.SIGTERM)
   482  			o3Proc.Signal(syscall.SIGTERM)
   483  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   484  			Eventually(o2Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   485  			Eventually(o3Proc.Wait(), network.EventuallyTimeout).Should(Receive())
   486  
   487  			o1Runner = network.OrdererRunner(o1)
   488  			o2Runner = network.OrdererRunner(o2)
   489  			o3Runner = network.OrdererRunner(o3)
   490  
   491  			By("Launching orderers again with a general timeshift re-using the cluster port")
   492  			for _, orderer := range []*nwo.Orderer{o1, o2, o3} {
   493  				ordererConfig := network.ReadOrdererConfig(orderer)
   494  				ordererConfig.General.TLS.TLSHandshakeTimeShift = 5 * time.Minute
   495  				network.WriteOrdererConfig(orderer, ordererConfig)
   496  			}
   497  
   498  			o1Proc = ifrit.Invoke(o1Runner)
   499  			o2Proc = ifrit.Invoke(o2Runner)
   500  			o3Proc = ifrit.Invoke(o3Runner)
   501  
   502  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   503  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   504  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   505  
   506  			By("Waiting for a leader to be elected")
   507  			findLeader([]*ginkgomon.Runner{o1Runner, o2Runner, o3Runner})
   508  		})
   509  	})
   510  
   511  	When("admin certificate expires", func() {
   512  		It("is still possible to replace them", func() {
   513  			network = nwo.New(nwo.BasicEtcdRaft(), testDir, client, StartPort(), components)
   514  			network.GenerateConfigTree()
   515  			network.Bootstrap()
   516  
   517  			peer = network.Peer("Org1", "peer0")
   518  			orderer := network.Orderer("orderer")
   519  
   520  			ordererDomain := network.Organization(orderer.Organization).Domain
   521  			ordererCAKeyPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations", ordererDomain, "ca", "priv_sk")
   522  
   523  			ordererCAKey, err := ioutil.ReadFile(ordererCAKeyPath)
   524  			Expect(err).NotTo(HaveOccurred())
   525  
   526  			ordererCACertPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations", ordererDomain, "ca", fmt.Sprintf("ca.%s-cert.pem", ordererDomain))
   527  			ordererCACert, err := ioutil.ReadFile(ordererCACertPath)
   528  			Expect(err).NotTo(HaveOccurred())
   529  
   530  			adminCertPath := fmt.Sprintf("Admin@%s-cert.pem", ordererDomain)
   531  			adminCertPath = filepath.Join(network.OrdererUserMSPDir(orderer, "Admin"), "signcerts", adminCertPath)
   532  
   533  			originalAdminCert, err := ioutil.ReadFile(adminCertPath)
   534  			Expect(err).NotTo(HaveOccurred())
   535  
   536  			expiredAdminCert, earlyCACert := expireCertificate(originalAdminCert, ordererCACert, ordererCAKey)
   537  			err = ioutil.WriteFile(adminCertPath, expiredAdminCert, 600)
   538  			Expect(err).NotTo(HaveOccurred())
   539  
   540  			adminPath := filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   541  				ordererDomain, "msp", "admincerts", fmt.Sprintf("Admin@%s-cert.pem", ordererDomain))
   542  			err = ioutil.WriteFile(adminPath, expiredAdminCert, 600)
   543  			Expect(err).NotTo(HaveOccurred())
   544  
   545  			err = ioutil.WriteFile(ordererCACertPath, earlyCACert, 600)
   546  			Expect(err).NotTo(HaveOccurred())
   547  
   548  			ordererCACertPath = filepath.Join(network.RootDir, "crypto", "ordererOrganizations",
   549  				ordererDomain, "msp", "cacerts", fmt.Sprintf("ca.%s-cert.pem", ordererDomain))
   550  			err = ioutil.WriteFile(ordererCACertPath, earlyCACert, 600)
   551  			Expect(err).NotTo(HaveOccurred())
   552  
   553  			By("Regenerating config")
   554  			sess, err := network.ConfigTxGen(commands.OutputBlock{
   555  				ChannelID:   network.SystemChannel.Name,
   556  				Profile:     network.SystemChannel.Profile,
   557  				ConfigPath:  network.RootDir,
   558  				OutputBlock: network.OutputBlockPath(network.SystemChannel.Name),
   559  			})
   560  			Expect(err).NotTo(HaveOccurred())
   561  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   562  
   563  			runner := network.OrdererRunner(orderer)
   564  			runner.Command.Env = append(runner.Command.Env, "FABRIC_LOGGING_SPEC=debug")
   565  			ordererProc = ifrit.Invoke(runner)
   566  
   567  			By("Waiting for orderer to elect a leader")
   568  			findLeader([]*ginkgomon.Runner{runner})
   569  
   570  			By("Creating config update that adds another orderer admin")
   571  			bootBlockPath := filepath.Join(network.RootDir, fmt.Sprintf("%s_block.pb", network.SystemChannel.Name))
   572  			bootBlock, err := ioutil.ReadFile(bootBlockPath)
   573  			Expect(err).NotTo(HaveOccurred())
   574  
   575  			current := configFromBootstrapBlock(bootBlock)
   576  			updatedConfig := addAdminCertToConfig(current, originalAdminCert)
   577  
   578  			tempDir, err := ioutil.TempDir("", "adminExpirationTest")
   579  			Expect(err).NotTo(HaveOccurred())
   580  
   581  			configBlockFile := filepath.Join(tempDir, "update.pb")
   582  			defer os.RemoveAll(tempDir)
   583  			nwo.ComputeUpdateOrdererConfig(configBlockFile, network, network.SystemChannel.Name, current, updatedConfig, peer)
   584  
   585  			updateTransaction, err := ioutil.ReadFile(configBlockFile)
   586  			Expect(err).NotTo(HaveOccurred())
   587  
   588  			By("Creating config update")
   589  			channelCreateTxn := createConfigTx(updateTransaction, network.SystemChannel.Name, network, orderer, peer)
   590  
   591  			By("Updating channel config and failing")
   592  			p, err := nwo.Broadcast(network, orderer, channelCreateTxn)
   593  			Expect(err).NotTo(HaveOccurred())
   594  			Expect(p.Status).To(Equal(common.Status_BAD_REQUEST))
   595  			Expect(p.Info).To(ContainSubstring("identity expired"))
   596  
   597  			By("Attempting to fetch a block from orderer and failing")
   598  			denv := CreateDeliverEnvelope(network, orderer, 0, network.SystemChannel.Name)
   599  			Expect(denv).NotTo(BeNil())
   600  
   601  			block, err := nwo.Deliver(network, orderer, denv)
   602  			Expect(denv).NotTo(BeNil())
   603  			Expect(block).To(BeNil())
   604  			Eventually(runner.Err(), time.Minute, time.Second).Should(gbytes.Say("client identity expired"))
   605  
   606  			By("Killing orderer")
   607  			ordererProc.Signal(syscall.SIGTERM)
   608  			Eventually(ordererProc.Wait(), network.EventuallyTimeout).Should(Receive())
   609  
   610  			By("Launching orderers again")
   611  			runner = network.OrdererRunner(orderer)
   612  			runner.Command.Env = append(runner.Command.Env, "ORDERER_GENERAL_AUTHENTICATION_NOEXPIRATIONCHECKS=true")
   613  			ordererProc = ifrit.Invoke(runner)
   614  
   615  			By("Waiting for orderer to launch again")
   616  			findLeader([]*ginkgomon.Runner{runner})
   617  
   618  			By("Updating channel config and succeeding")
   619  			p, err = nwo.Broadcast(network, orderer, channelCreateTxn)
   620  			Expect(err).NotTo(HaveOccurred())
   621  			Expect(p.Status).To(Equal(common.Status_SUCCESS))
   622  
   623  			By("Fetching a block from the orderer and succeeding")
   624  			block = FetchBlock(network, orderer, 1, network.SystemChannel.Name)
   625  			Expect(block).NotTo(BeNil())
   626  
   627  			By("Restore the original admin cert")
   628  			err = ioutil.WriteFile(adminCertPath, originalAdminCert, 600)
   629  			Expect(err).NotTo(HaveOccurred())
   630  
   631  			By("Ensure we can fetch the block using our original un-expired admin cert")
   632  			ccb := func() uint64 {
   633  				return nwo.GetConfigBlock(network, peer, orderer, network.SystemChannel.Name).Header.Number
   634  			}
   635  			Eventually(ccb, network.EventuallyTimeout).Should(Equal(uint64(1)))
   636  		})
   637  	})
   638  })
   639  
   640  func findLeader(ordererRunners []*ginkgomon.Runner) int {
   641  	var wg sync.WaitGroup
   642  	wg.Add(len(ordererRunners))
   643  
   644  	findLeader := func(runner *ginkgomon.Runner) int {
   645  		Eventually(runner.Err(), time.Minute, time.Second).Should(gbytes.Say("Raft leader changed: [0-9] -> "))
   646  
   647  		idBuff := make([]byte, 1)
   648  		runner.Err().Read(idBuff)
   649  
   650  		newLeader, err := strconv.ParseInt(string(idBuff), 10, 32)
   651  		Expect(err).To(BeNil())
   652  		return int(newLeader)
   653  	}
   654  
   655  	leaders := make(chan int, len(ordererRunners))
   656  
   657  	for _, runner := range ordererRunners {
   658  		go func(runner *ginkgomon.Runner) {
   659  			defer GinkgoRecover()
   660  			defer wg.Done()
   661  
   662  			for {
   663  				leader := findLeader(runner)
   664  				if leader != 0 {
   665  					leaders <- leader
   666  					break
   667  				}
   668  			}
   669  		}(runner)
   670  	}
   671  
   672  	wg.Wait()
   673  
   674  	close(leaders)
   675  	firstLeader := <-leaders
   676  	for leader := range leaders {
   677  		if firstLeader != leader {
   678  			Fail(fmt.Sprintf("First leader is %d but saw %d also as a leader", firstLeader, leader))
   679  		}
   680  	}
   681  
   682  	return firstLeader
   683  }
   684  
   685  func expireCertificate(certPEM, caCertPEM, caKeyPEM []byte) (expiredcertPEM []byte, earlyMadeCACertPEM []byte) {
   686  	keyAsDER, _ := pem.Decode(caKeyPEM)
   687  	caKeyWithoutType, err := x509.ParsePKCS8PrivateKey(keyAsDER.Bytes)
   688  	Expect(err).NotTo(HaveOccurred())
   689  	caKey := caKeyWithoutType.(*ecdsa.PrivateKey)
   690  
   691  	caCertAsDER, _ := pem.Decode(caCertPEM)
   692  	caCert, err := x509.ParseCertificate(caCertAsDER.Bytes)
   693  	Expect(err).NotTo(HaveOccurred())
   694  
   695  	certAsDER, _ := pem.Decode(certPEM)
   696  	cert, err := x509.ParseCertificate(certAsDER.Bytes)
   697  	Expect(err).NotTo(HaveOccurred())
   698  
   699  	cert.Raw = nil
   700  	caCert.Raw = nil
   701  	// The certificate was made 1 hour ago
   702  	cert.NotBefore = time.Now().Add((-1) * time.Hour)
   703  	// As well as the CA certificate
   704  	caCert.NotBefore = time.Now().Add((-1) * time.Hour)
   705  	// The certificate expires now
   706  	cert.NotAfter = time.Now()
   707  
   708  	// The CA signs the certificate
   709  	certBytes, err := x509.CreateCertificate(rand.Reader, cert, caCert, cert.PublicKey, caKey)
   710  	Expect(err).NotTo(HaveOccurred())
   711  
   712  	// The CA signs its own certificate
   713  	caCertBytes, err := x509.CreateCertificate(rand.Reader, caCert, caCert, caCert.PublicKey, caKey)
   714  	Expect(err).NotTo(HaveOccurred())
   715  
   716  	expiredcertPEM = pem.EncodeToMemory(&pem.Block{Bytes: certBytes, Type: "CERTIFICATE"})
   717  	earlyMadeCACertPEM = pem.EncodeToMemory(&pem.Block{Bytes: caCertBytes, Type: "CERTIFICATE"})
   718  	return
   719  }
   720  
   721  func createConfigTx(txData []byte, channelName string, network *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer) *common.Envelope {
   722  	ctxEnv, err := protoutil.UnmarshalEnvelope(txData)
   723  	Expect(err).NotTo(HaveOccurred())
   724  
   725  	payload, err := protoutil.UnmarshalPayload(ctxEnv.Payload)
   726  	Expect(err).NotTo(HaveOccurred())
   727  
   728  	configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(payload.Data)
   729  	Expect(err).NotTo(HaveOccurred())
   730  
   731  	conf := signer.Config{
   732  		MSPID:        network.Organization(orderer.Organization).MSPID,
   733  		IdentityPath: network.OrdererUserCert(orderer, "Admin"),
   734  		KeyPath:      network.OrdererUserKey(orderer, "Admin"),
   735  	}
   736  
   737  	s, err := signer.NewSigner(conf)
   738  	Expect(err).NotTo(HaveOccurred())
   739  
   740  	signConfigUpdate(conf, configUpdateEnv)
   741  
   742  	env, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG_UPDATE, channelName, s, configUpdateEnv, 0, 0)
   743  	Expect(err).NotTo(HaveOccurred())
   744  
   745  	return env
   746  }
   747  
   748  func signConfigUpdate(conf signer.Config, configUpdateEnv *common.ConfigUpdateEnvelope) *common.ConfigUpdateEnvelope {
   749  	s, err := signer.NewSigner(conf)
   750  	Expect(err).NotTo(HaveOccurred())
   751  
   752  	sigHeader, err := protoutil.NewSignatureHeader(s)
   753  	Expect(err).NotTo(HaveOccurred())
   754  
   755  	configSig := &common.ConfigSignature{
   756  		SignatureHeader: protoutil.MarshalOrPanic(sigHeader),
   757  	}
   758  
   759  	configSig.Signature, err = s.Sign(util.ConcatenateBytes(configSig.SignatureHeader, configUpdateEnv.ConfigUpdate))
   760  	Expect(err).NotTo(HaveOccurred())
   761  
   762  	configUpdateEnv.Signatures = append(configUpdateEnv.Signatures, configSig)
   763  	return configUpdateEnv
   764  }
   765  
   766  func addAdminCertToConfig(originalConfig *common.Config, additionalAdmin []byte) *common.Config {
   767  	updatedConfig := proto.Clone(originalConfig).(*common.Config)
   768  
   769  	rawMSPConfig := updatedConfig.ChannelGroup.Groups["Orderer"].Groups["OrdererOrg"].Values["MSP"]
   770  	mspConfig := &msp.MSPConfig{}
   771  	err := proto.Unmarshal(rawMSPConfig.Value, mspConfig)
   772  	Expect(err).NotTo(HaveOccurred())
   773  
   774  	fabricConfig := &msp.FabricMSPConfig{}
   775  	err = proto.Unmarshal(mspConfig.Config, fabricConfig)
   776  	Expect(err).NotTo(HaveOccurred())
   777  
   778  	fabricConfig.Admins = append(fabricConfig.Admins, additionalAdmin)
   779  	mspConfig.Config = protoutil.MarshalOrPanic(fabricConfig)
   780  
   781  	rawMSPConfig.Value = protoutil.MarshalOrPanic(mspConfig)
   782  	return updatedConfig
   783  }
   784  
   785  func configFromBootstrapBlock(bootstrapBlock []byte) *common.Config {
   786  	block := &common.Block{}
   787  	err := proto.Unmarshal(bootstrapBlock, block)
   788  	Expect(err).NotTo(HaveOccurred())
   789  
   790  	envelope, err := protoutil.GetEnvelopeFromBlock(block.Data.Data[0])
   791  	Expect(err).NotTo(HaveOccurred())
   792  
   793  	payload, err := protoutil.UnmarshalPayload(envelope.Payload)
   794  	Expect(err).NotTo(HaveOccurred())
   795  
   796  	configEnv := &common.ConfigEnvelope{}
   797  	err = proto.Unmarshal(payload.Data, configEnv)
   798  	Expect(err).NotTo(HaveOccurred())
   799  
   800  	return configEnv.Config
   801  
   802  }