github.com/lzy4123/fabric@v2.1.1+incompatible/integration/raft/migration_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  	"errors"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"path/filepath"
    15  	"strings"
    16  	"syscall"
    17  	"time"
    18  
    19  	docker "github.com/fsouza/go-dockerclient"
    20  	"github.com/golang/protobuf/proto"
    21  	"github.com/hyperledger/fabric-protos-go/common"
    22  	protosorderer "github.com/hyperledger/fabric-protos-go/orderer"
    23  	"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    24  	protosraft "github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    25  	"github.com/hyperledger/fabric/integration/nwo"
    26  	"github.com/hyperledger/fabric/integration/nwo/commands"
    27  	"github.com/hyperledger/fabric/protoutil"
    28  	. "github.com/onsi/ginkgo"
    29  	. "github.com/onsi/gomega"
    30  	"github.com/onsi/gomega/gbytes"
    31  	"github.com/onsi/gomega/gexec"
    32  	"github.com/tedsuo/ifrit"
    33  	"github.com/tedsuo/ifrit/ginkgomon"
    34  	"github.com/tedsuo/ifrit/grouper"
    35  )
    36  
    37  var _ = Describe("Kafka2RaftMigration", func() {
    38  	var (
    39  		testDir string
    40  		client  *docker.Client
    41  		network *nwo.Network
    42  
    43  		process                ifrit.Process
    44  		brokerProc             ifrit.Process
    45  		o1Proc, o2Proc, o3Proc ifrit.Process
    46  
    47  		o1Runner, o2Runner, o3Runner *ginkgomon.Runner
    48  	)
    49  
    50  	BeforeEach(func() {
    51  		var err error
    52  		testDir, err = ioutil.TempDir("", "kafka2raft-migration")
    53  		Expect(err).NotTo(HaveOccurred())
    54  
    55  		client, err = docker.NewClientFromEnv()
    56  		Expect(err).NotTo(HaveOccurred())
    57  	})
    58  
    59  	AfterEach(func() {
    60  		if process != nil {
    61  			process.Signal(syscall.SIGTERM)
    62  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
    63  		}
    64  
    65  		for _, oProc := range []ifrit.Process{o1Proc, o2Proc, o3Proc} {
    66  			if oProc != nil {
    67  				oProc.Signal(syscall.SIGTERM)
    68  				Eventually(oProc.Wait(), network.EventuallyTimeout).Should(Receive())
    69  			}
    70  		}
    71  
    72  		if brokerProc != nil {
    73  			brokerProc.Signal(syscall.SIGTERM)
    74  			Eventually(brokerProc.Wait(), network.EventuallyTimeout).Should(Receive())
    75  		}
    76  
    77  		if network != nil {
    78  			network.Cleanup()
    79  		}
    80  
    81  		_ = os.RemoveAll(testDir)
    82  	})
    83  
    84  	// These tests execute the migration config updates on Kafka based system, and verify that these config update
    85  	// have the desired effect. They focus on testing that filtering and the blocking of transitions into, in, and
    86  	// out-of maintenance mode are enforced. These tests use a single node.
    87  	Describe("Kafka to Raft migration kafka side", func() {
    88  		var (
    89  			orderer                                  *nwo.Orderer
    90  			peer                                     *nwo.Peer
    91  			syschannel, channel1, channel2, channel3 string
    92  			raftMetadata                             []byte
    93  		)
    94  
    95  		BeforeEach(func() {
    96  			network = nwo.New(kafka2RaftMultiChannel(), testDir, client, StartPort(), components)
    97  			network.GenerateConfigTree()
    98  			network.Bootstrap()
    99  
   100  			networkRunner := network.NetworkGroupRunner()
   101  			process = ifrit.Invoke(networkRunner)
   102  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   103  
   104  			orderer = network.Orderer("orderer")
   105  			peer = network.Peer("Org1", "peer0")
   106  
   107  			syschannel = network.SystemChannel.Name
   108  			channel1 = "testchannel1"
   109  			channel2 = "testchannel2"
   110  			channel3 = "testchannel3"
   111  
   112  			raftMetadata = prepareRaftMetadata(network)
   113  
   114  			By("Create & join first channel, deploy and invoke chaincode")
   115  			network.CreateChannel(channel1, orderer, peer)
   116  		})
   117  
   118  		// This test executes the "green path" migration config updates on Kafka based system with a system channel
   119  		// and a standard channel, and verifies that these config updates have the desired effect.
   120  		//
   121  		// The green path is entering maintenance mode, and then changing the consensus type.
   122  		// In maintenance mode we check that channel creation is blocked and that normal transactions are blocked.
   123  		//
   124  		// We also check that after entering maintenance mode, we can exit it without making any
   125  		// changes - the "abort path".
   126  		It("executes kafka2raft green path", func() {
   127  			//=== The abort path ======================================================================================
   128  			//=== Step 1: Config update on system channel, MAINTENANCE ===
   129  			By("1) Config update on system channel, State=MAINTENANCE, enter maintenance-mode")
   130  			config, updatedConfig := prepareTransition(network, peer, orderer, syschannel,
   131  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   132  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   133  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   134  
   135  			By("1) Verify: system channel1 config changed")
   136  			sysStartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   137  			Expect(sysStartBlockNum).ToNot(Equal(0))
   138  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   139  			updatedConfig, consensusTypeValue, err := extractOrdererConsensusType(config)
   140  			Expect(err).NotTo(HaveOccurred())
   141  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   142  
   143  			By("1) Verify: new channels cannot be created")
   144  			exitCode := network.CreateChannelExitCode(channel2, orderer, peer)
   145  			Expect(exitCode).ToNot(Equal(0))
   146  
   147  			//=== Step 2: Config update on standard channel, MAINTENANCE ===
   148  			By("2) Config update on standard channel, State=MAINTENANCE, enter maintenance-mode")
   149  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   150  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   151  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   152  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   153  
   154  			By("2) Verify: standard channel config changed")
   155  			std1EntryBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   156  			Expect(std1EntryBlockNum).ToNot(Equal(0))
   157  			config = nwo.GetConfig(network, peer, orderer, channel1)
   158  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   159  			Expect(err).NotTo(HaveOccurred())
   160  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   161  
   162  			By("2) Verify: Normal TX's on standard channel are blocked")
   163  			assertTxFailed(network, orderer, channel1)
   164  
   165  			//In maintenance mode deliver requests are open to those entities that satisfy the /Channel/Orderer/Readers policy
   166  			By("2) Verify: delivery request from peer is blocked")
   167  			err = checkPeerDeliverRequest(orderer, peer, network, channel1)
   168  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   169  
   170  			//=== Step 3: config update on system channel, State=NORMAL, abort ===
   171  			By("3) Config update on system channel, State=NORMAL, exit maintenance-mode - abort path")
   172  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   173  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   174  				"kafka", nil, protosorderer.ConsensusType_STATE_NORMAL)
   175  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   176  
   177  			By("3) Verify: system channel config changed")
   178  			sysBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   179  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 1))
   180  
   181  			By("3) Verify: create new channel, executing transaction")
   182  			network.CreateChannel(channel2, orderer, peer)
   183  
   184  			assertBlockCreation(network, orderer, peer, channel2, 1)
   185  
   186  			By("3) Verify: delivery request from peer is not blocked on new channel")
   187  			err = checkPeerDeliverRequest(orderer, peer, network, channel2)
   188  			Expect(err).NotTo(HaveOccurred())
   189  
   190  			//=== Step 4: config update on standard channel, State=NORMAL, abort ===
   191  			By("4) Config update on standard channel, State=NORMAL, exit maintenance-mode - abort path")
   192  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   193  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   194  				"kafka", nil, protosorderer.ConsensusType_STATE_NORMAL)
   195  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   196  
   197  			By("4) Verify: standard channel config changed")
   198  			std1BlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   199  			Expect(std1BlockNum).To(Equal(std1EntryBlockNum + 1))
   200  
   201  			By("4) Verify: standard channel delivery requests from peer unblocked")
   202  			err = checkPeerDeliverRequest(orderer, peer, network, channel1)
   203  			Expect(err).NotTo(HaveOccurred())
   204  
   205  			By("4) Verify: Normal TX's on standard channel are permitted again")
   206  			assertBlockCreation(network, orderer, nil, channel1, 3)
   207  
   208  			//=== The green path ======================================================================================
   209  			//=== Step 5: Config update on system channel, MAINTENANCE, again ===
   210  			By("5) Config update on system channel, State=MAINTENANCE, enter maintenance-mode again")
   211  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   212  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   213  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   214  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   215  
   216  			By("5) Verify: system channel config changed")
   217  			sysStartBlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   218  			Expect(sysStartBlockNum).ToNot(Equal(0))
   219  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   220  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   221  			Expect(err).NotTo(HaveOccurred())
   222  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   223  
   224  			//=== Step 6: Config update on standard channel1, MAINTENANCE, again ===
   225  			By("6) Config update on standard channel1, State=MAINTENANCE, enter maintenance-mode again")
   226  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   227  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   228  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   229  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   230  
   231  			By("6) Verify: standard channel config changed")
   232  			std1EntryBlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   233  			Expect(std1EntryBlockNum).ToNot(Equal(0))
   234  
   235  			config = nwo.GetConfig(network, peer, orderer, channel1)
   236  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   237  			Expect(err).NotTo(HaveOccurred())
   238  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   239  
   240  			By("6) Verify: delivery request from peer is blocked")
   241  			err = checkPeerDeliverRequest(orderer, peer, network, channel1)
   242  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   243  
   244  			By("6) Verify: Normal TX's on standard channel are blocked")
   245  			assertTxFailed(network, orderer, channel1)
   246  
   247  			//=== Step 7: Config update on standard channel2, MAINTENANCE ===
   248  			By("7) Config update on standard channel2, State=MAINTENANCE, enter maintenance-mode again")
   249  			config, updatedConfig = prepareTransition(network, peer, orderer, channel2,
   250  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   251  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   252  			nwo.UpdateOrdererConfig(network, orderer, channel2, config, updatedConfig, peer, orderer)
   253  
   254  			By("7) Verify: standard channel config changed")
   255  			std2EntryBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel2)
   256  			Expect(std2EntryBlockNum).ToNot(Equal(0))
   257  
   258  			config = nwo.GetConfig(network, peer, orderer, channel2)
   259  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   260  			Expect(err).NotTo(HaveOccurred())
   261  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   262  
   263  			By("7) Verify: delivery request from peer is blocked")
   264  			err = checkPeerDeliverRequest(orderer, peer, network, channel2)
   265  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   266  
   267  			By("7) Verify: Normal TX's on standard channel are blocked")
   268  			assertTxFailed(network, orderer, channel2)
   269  
   270  			//=== Step 8: config update on system channel, State=MAINTENANCE, type=etcdraft ===
   271  			By("8) Config update on system channel, State=MAINTENANCE, type=etcdraft")
   272  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   273  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   274  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   275  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   276  
   277  			By("8) Verify: system channel config changed")
   278  			sysBlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   279  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 1))
   280  
   281  			By("8) Verify: new channels cannot be created")
   282  			exitCode = network.CreateChannelExitCode(channel3, orderer, peer)
   283  			Expect(exitCode).ToNot(Equal(0))
   284  
   285  			//=== Step 9: config update on standard channel1, State=MAINTENANCE, type=etcdraft ===
   286  			By("9) Config update on standard channel1, State=MAINTENANCE, type=etcdraft")
   287  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   288  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   289  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   290  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   291  
   292  			By("9) Verify: standard channel config changed")
   293  			std1BlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   294  			Expect(std1BlockNum).To(Equal(std1EntryBlockNum + 1))
   295  
   296  			By("9) Verify: delivery request from peer is blocked")
   297  			err = checkPeerDeliverRequest(orderer, peer, network, channel1)
   298  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   299  
   300  			By("9) Verify: Normal TX's on standard channel are blocked")
   301  			assertTxFailed(network, orderer, channel1)
   302  
   303  			//=== Step 10: config update on standard channel2, State=MAINTENANCE, type=etcdraft ===
   304  			By("10) Config update on standard channel2, State=MAINTENANCE, type=etcdraft")
   305  			config, updatedConfig = prepareTransition(network, peer, orderer, channel2,
   306  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   307  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   308  			nwo.UpdateOrdererConfig(network, orderer, channel2, config, updatedConfig, peer, orderer)
   309  
   310  			By("10) Verify: standard channel config changed")
   311  			std2BlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel2)
   312  			Expect(std2BlockNum).To(Equal(std2EntryBlockNum + 1))
   313  
   314  			By("10) Verify: delivery request from peer is blocked")
   315  			err = checkPeerDeliverRequest(orderer, peer, network, channel2)
   316  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   317  
   318  			By("10) Verify: Normal TX's on standard channel are blocked")
   319  			assertTxFailed(network, orderer, channel2)
   320  		})
   321  
   322  		// This test executes the migration flow and checks that forbidden transitions are rejected.
   323  		// These transitions are enforced by the maintenance filter:
   324  		// - Entry to & exit from maintenance mode can only change ConsensusType.State.
   325  		// - In maintenance mode one can only change ConsensusType.Type & ConsensusType.Metadata.
   326  		// - ConsensusType.Type can only change from "kafka" to "etcdraft", and only in maintenance mode.
   327  		It("executes kafka2raft forbidden transitions", func() {
   328  			//=== Step 1: ===
   329  			By("1) Config update on system channel, changing both ConsensusType State & Type is forbidden")
   330  			assertTransitionFailed(network, peer, orderer, syschannel,
   331  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   332  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   333  
   334  			//=== Step 2: ===
   335  			By("2) Config update on standard channel, changing both ConsensusType State & Type is forbidden")
   336  			assertTransitionFailed(network, peer, orderer, channel1,
   337  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   338  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   339  
   340  			//=== Step 3: ===
   341  			By("3) Config update on system channel, changing both ConsensusType State & some other value is forbidden")
   342  			config, updatedConfig := prepareTransition(network, peer, orderer, syschannel,
   343  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   344  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   345  			updateConfigWithBatchTimeout(updatedConfig)
   346  			updateOrdererConfigFailed(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   347  
   348  			//=== Step 4: ===
   349  			By("4) Config update on standard channel, both ConsensusType State & some other value is forbidden")
   350  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   351  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   352  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   353  			updateConfigWithBatchTimeout(updatedConfig)
   354  			updateOrdererConfigFailed(network, orderer, channel1, config, updatedConfig, peer, orderer)
   355  
   356  			//=== Step 5: ===
   357  			By("5) Config update on system channel, State=MAINTENANCE, enter maintenance-mode")
   358  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   359  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   360  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   361  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   362  
   363  			By("5) Verify: system channel config changed")
   364  			sysStartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   365  			Expect(sysStartBlockNum).ToNot(Equal(0))
   366  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   367  			updatedConfig, consensusTypeValue, err := extractOrdererConsensusType(config)
   368  			Expect(err).NotTo(HaveOccurred())
   369  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   370  
   371  			//=== Step 6: ===
   372  			By("6) Config update on standard channel, State=MAINTENANCE, enter maintenance-mode")
   373  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   374  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   375  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   376  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   377  
   378  			By("6) Verify: standard channel config changed")
   379  			std1StartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   380  			Expect(std1StartBlockNum).ToNot(Equal(0))
   381  			config = nwo.GetConfig(network, peer, orderer, channel1)
   382  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   383  			Expect(err).NotTo(HaveOccurred())
   384  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   385  
   386  			//=== Step 7: ===
   387  			By("7) Config update on system channel, change ConsensusType.Type to unsupported type, forbidden")
   388  			assertTransitionFailed(network, peer, orderer, syschannel,
   389  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   390  				"melville", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   391  
   392  			//=== Step 8: ===
   393  			By("8) Config update on standard channel, change ConsensusType.Type to unsupported type, forbidden")
   394  			assertTransitionFailed(network, peer, orderer, channel1,
   395  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   396  				"hesse", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   397  
   398  			//=== Step 9: ===
   399  			By("9) Config update on system channel, change ConsensusType.Type and State, forbidden")
   400  			assertTransitionFailed(network, peer, orderer, syschannel,
   401  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   402  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   403  
   404  			//=== Step 10: ===
   405  			By("10) Config update on standard channel, change ConsensusType.Type and State, forbidden")
   406  			assertTransitionFailed(network, peer, orderer, channel1,
   407  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   408  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   409  
   410  			//=== Step 11: ===
   411  			By("11) Config update on system channel, changing both ConsensusType.Type and other value is permitted")
   412  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   413  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   414  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   415  			updateConfigWithBatchTimeout(updatedConfig)
   416  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   417  
   418  			By("11) Verify: system channel config changed")
   419  			sysBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   420  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 1))
   421  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   422  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   423  			Expect(err).NotTo(HaveOccurred())
   424  			validateConsensusTypeValue(consensusTypeValue, "etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE)
   425  
   426  			//=== Step 12: ===
   427  			By("12) Config update on standard channel, changing both ConsensusType.Type and other value is permitted")
   428  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   429  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   430  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   431  			updateConfigWithBatchTimeout(updatedConfig)
   432  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   433  
   434  			By("12) Verify: standard channel config changed")
   435  			std1BlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   436  			Expect(std1BlockNum).To(Equal(std1StartBlockNum + 1))
   437  			config = nwo.GetConfig(network, peer, orderer, channel1)
   438  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   439  			Expect(err).NotTo(HaveOccurred())
   440  			validateConsensusTypeValue(consensusTypeValue, "etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE)
   441  
   442  			//=== Step 13: ===
   443  			By("13) Config update on system channel, changing value other than ConsensusType.Type is permitted")
   444  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   445  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   446  			Expect(err).NotTo(HaveOccurred())
   447  			validateConsensusTypeValue(consensusTypeValue, "etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE)
   448  			updateConfigWithBatchTimeout(updatedConfig)
   449  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   450  
   451  			By("13) Verify: system channel config changed")
   452  			sysBlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   453  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 2))
   454  
   455  			//=== Step 14: ===
   456  			By("14) Config update on standard channel, changing value other than ConsensusType.Type is permitted")
   457  			config = nwo.GetConfig(network, peer, orderer, channel1)
   458  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   459  			Expect(err).NotTo(HaveOccurred())
   460  			validateConsensusTypeValue(consensusTypeValue, "etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE)
   461  			updateConfigWithBatchTimeout(updatedConfig)
   462  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   463  
   464  			By("14) Verify: standard channel config changed")
   465  			std1BlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   466  			Expect(std1BlockNum).To(Equal(std1StartBlockNum + 2))
   467  
   468  			//=== Step 15: ===
   469  			By("15) Config update on system channel, changing both ConsensusType State & some other value is forbidden")
   470  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   471  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   472  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   473  			updateConfigWithBatchTimeout(updatedConfig)
   474  			updateOrdererConfigFailed(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   475  
   476  			//=== Step 16: ===
   477  			By("16) Config update on standard channel, both ConsensusType State & some other value is forbidden")
   478  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   479  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   480  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   481  			updateConfigWithBatchTimeout(updatedConfig)
   482  			updateOrdererConfigFailed(network, orderer, channel1, config, updatedConfig, peer, orderer)
   483  		})
   484  	})
   485  
   486  	// These tests execute the migration config updates on Kafka based system, restart the orderer onto a Raft-based
   487  	// system, and verifies that the newly restarted orderer cluster performs as expected.
   488  	Describe("Kafka to Raft migration raft side", func() {
   489  		var (
   490  			o1, o2, o3                     *nwo.Orderer
   491  			peer                           *nwo.Peer
   492  			syschannel, channel1, channel2 string
   493  			raftMetadata                   []byte
   494  		)
   495  
   496  		BeforeEach(func() {
   497  			network = nwo.New(kafka2RaftMultiNode(), testDir, client, StartPort(), components)
   498  			network.GenerateConfigTree()
   499  			network.Bootstrap()
   500  
   501  			o1, o2, o3 = network.Orderer("orderer1"), network.Orderer("orderer2"), network.Orderer("orderer3")
   502  			peer = network.Peer("Org1", "peer0")
   503  
   504  			brokerGroup := network.BrokerGroupRunner()
   505  			brokerProc = ifrit.Invoke(brokerGroup)
   506  			Eventually(brokerProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   507  
   508  			o1Runner = network.OrdererRunner(o1)
   509  			o2Runner = network.OrdererRunner(o2)
   510  			o3Runner = network.OrdererRunner(o3)
   511  
   512  			o1Proc = ifrit.Invoke(o1Runner)
   513  			o2Proc = ifrit.Invoke(o2Runner)
   514  			o3Proc = ifrit.Invoke(o3Runner)
   515  
   516  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   517  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   518  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   519  
   520  			raftMetadata = prepareRaftMetadata(network)
   521  
   522  			syschannel = network.SystemChannel.Name
   523  			channel1 = "testchannel1"
   524  			channel2 = "testchannel2"
   525  
   526  			By("Create & join first channel, deploy and invoke chaincode")
   527  			network.CreateChannel(channel1, o1, peer)
   528  		})
   529  
   530  		// This test executes the "green path" migration config updates on Kafka based system
   531  		// with a three orderers, a system channel and two standard channels.
   532  		// It then restarts the orderers onto a Raft-based system, and verifies that the
   533  		// newly restarted orderers perform as expected.
   534  		It("executes bootstrap to raft - multi node", func() {
   535  			//=== Step 1: Config update on system channel, MAINTENANCE ===
   536  			By("1) Config update on system channel, State=MAINTENANCE")
   537  			config, updatedConfig := prepareTransition(network, peer, o1, syschannel,
   538  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   539  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   540  			nwo.UpdateOrdererConfig(network, o1, syschannel, config, updatedConfig, peer, o1)
   541  
   542  			By("1) Verify: system channel config changed")
   543  			sysStartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, o1, syschannel)
   544  			Expect(sysStartBlockNum).ToNot(Equal(0))
   545  
   546  			config = nwo.GetConfig(network, peer, o1, syschannel)
   547  			updatedConfig, consensusTypeValue, err := extractOrdererConsensusType(config)
   548  			Expect(err).NotTo(HaveOccurred())
   549  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   550  
   551  			//=== Step 2: Config update on standard channel, MAINTENANCE ===
   552  			By("2) Config update on standard channel, State=MAINTENANCE")
   553  			config, updatedConfig = prepareTransition(network, peer, o1, channel1,
   554  				"kafka", protosorderer.ConsensusType_STATE_NORMAL,
   555  				"kafka", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   556  			nwo.UpdateOrdererConfig(network, o1, channel1, config, updatedConfig, peer, o1)
   557  
   558  			By("2) Verify: standard channel config changed")
   559  			chan1StartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, o1, channel1)
   560  			Expect(chan1StartBlockNum).ToNot(Equal(0))
   561  
   562  			config = nwo.GetConfig(network, peer, o1, channel1)
   563  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   564  			Expect(err).NotTo(HaveOccurred())
   565  			validateConsensusTypeValue(consensusTypeValue, "kafka", protosorderer.ConsensusType_STATE_MAINTENANCE)
   566  
   567  			//=== Step 3: config update on system channel, State=MAINTENANCE, type=etcdraft ===
   568  			By("3) Config update on system channel, State=MAINTENANCE, type=etcdraft")
   569  			config, updatedConfig = prepareTransition(network, peer, o1, syschannel,
   570  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   571  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   572  			nwo.UpdateOrdererConfig(network, o1, syschannel, config, updatedConfig, peer, o1)
   573  
   574  			By("3) Verify: system channel config changed")
   575  			sysBlockNum := nwo.CurrentConfigBlockNumber(network, peer, o1, syschannel)
   576  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 1))
   577  
   578  			//=== Step 4: config update on standard channel, State=MAINTENANCE, type=etcdraft ===
   579  			By("4) Config update on standard channel, State=MAINTENANCE, type=etcdraft")
   580  			config, updatedConfig = prepareTransition(network, peer, o1, channel1,
   581  				"kafka", protosorderer.ConsensusType_STATE_MAINTENANCE,
   582  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   583  			nwo.UpdateOrdererConfig(network, o1, channel1, config, updatedConfig, peer, o1)
   584  
   585  			By("4) Verify: standard channel config changed")
   586  			chan1BlockNum := nwo.CurrentConfigBlockNumber(network, peer, o1, channel1)
   587  			Expect(chan1BlockNum).To(Equal(chan1StartBlockNum + 1))
   588  
   589  			//=== Step 5: kill ===
   590  			By("5) killing orderer1,2,3")
   591  			for _, oProc := range []ifrit.Process{o1Proc, o2Proc, o3Proc} {
   592  				if oProc != nil {
   593  					oProc.Signal(syscall.SIGKILL)
   594  					Eventually(oProc.Wait(), network.EventuallyTimeout).Should(Receive(MatchError("exit status 137")))
   595  				}
   596  			}
   597  
   598  			//=== Step 6: restart ===
   599  			By("6) restarting orderer1,2,3")
   600  			network.Consensus.Type = "etcdraft"
   601  			o1Runner = network.OrdererRunner(o1)
   602  			o2Runner = network.OrdererRunner(o2)
   603  			o3Runner = network.OrdererRunner(o3)
   604  
   605  			o1Proc = ifrit.Invoke(o1Runner)
   606  			o2Proc = ifrit.Invoke(o2Runner)
   607  			o3Proc = ifrit.Invoke(o3Runner)
   608  
   609  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   610  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   611  			Eventually(o3Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   612  
   613  			assertBlockReception(
   614  				map[string]int{
   615  					syschannel: int(sysBlockNum),
   616  					channel1:   int(chan1BlockNum),
   617  				},
   618  				[]*nwo.Orderer{o1, o2, o3},
   619  				peer,
   620  				network,
   621  			)
   622  
   623  			Eventually(o1Runner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Raft leader changed: 0 -> "))
   624  			Eventually(o2Runner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Raft leader changed: 0 -> "))
   625  			Eventually(o3Runner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Raft leader changed: 0 -> "))
   626  
   627  			By("7) System channel still in maintenance, State=MAINTENANCE, cannot create new channels")
   628  			exitCode := network.CreateChannelExitCode(channel2, o1, peer)
   629  			Expect(exitCode).ToNot(Equal(0))
   630  
   631  			By("8) Standard channel still in maintenance, State=MAINTENANCE, normal TX's blocked, delivery to peers blocked")
   632  			assertTxFailed(network, o1, channel1)
   633  
   634  			err = checkPeerDeliverRequest(o1, peer, network, channel1)
   635  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   636  
   637  			By("9) Release - executing config transaction on system channel with restarted orderer")
   638  			config, updatedConfig = prepareTransition(network, peer, o1, syschannel,
   639  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   640  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   641  			nwo.UpdateOrdererConfig(network, o1, syschannel, config, updatedConfig, peer, o1)
   642  
   643  			By("9) Verify: system channel config changed")
   644  			sysBlockNum = nwo.CurrentConfigBlockNumber(network, peer, o1, syschannel)
   645  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 2))
   646  
   647  			By("10) Release - executing config transaction on standard channel with restarted orderer")
   648  			config, updatedConfig = prepareTransition(network, peer, o1, channel1,
   649  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   650  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   651  			nwo.UpdateOrdererConfig(network, o1, channel1, config, updatedConfig, peer, o1)
   652  
   653  			By("10) Verify: standard channel config changed")
   654  			chan1BlockNum = nwo.CurrentConfigBlockNumber(network, peer, o1, channel1)
   655  			Expect(chan1BlockNum).To(Equal(chan1StartBlockNum + 2))
   656  
   657  			By("11) Executing transaction on standard channel with restarted orderer")
   658  			assertBlockCreation(network, o1, peer, channel1, chan1StartBlockNum+3)
   659  			assertBlockCreation(network, o1, nil, channel1, chan1StartBlockNum+4)
   660  
   661  			By("12) Create new channel, executing transaction with restarted orderer")
   662  			network.CreateChannel(channel2, o1, peer)
   663  
   664  			chan2StartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, o1, channel2)
   665  			Expect(chan2StartBlockNum).ToNot(Equal(0))
   666  
   667  			assertBlockCreation(network, o1, peer, channel2, chan2StartBlockNum+1)
   668  			assertBlockCreation(network, o1, nil, channel2, chan2StartBlockNum+2)
   669  
   670  			By("Extending the network configuration to add a new orderer")
   671  			o4 := &nwo.Orderer{
   672  				Name:         "orderer4",
   673  				Organization: "OrdererOrg",
   674  			}
   675  			ports := nwo.Ports{}
   676  			for _, portName := range nwo.OrdererPortNames() {
   677  				ports[portName] = network.ReservePort()
   678  			}
   679  			network.PortsByOrdererID[o4.ID()] = ports
   680  			network.Orderers = append(network.Orderers, o4)
   681  			network.GenerateOrdererConfig(o4)
   682  			extendNetwork(network)
   683  
   684  			fourthOrdererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(o4), "server.crt")
   685  			fourthOrdererCertificate, err := ioutil.ReadFile(fourthOrdererCertificatePath)
   686  			Expect(err).NotTo(HaveOccurred())
   687  
   688  			By("Adding the fourth orderer to the system channel")
   689  			addConsenter(network, peer, o1, "systemchannel", protosraft.Consenter{
   690  				ServerTlsCert: fourthOrdererCertificate,
   691  				ClientTlsCert: fourthOrdererCertificate,
   692  				Host:          "127.0.0.1",
   693  				Port:          uint32(network.OrdererPort(o4, nwo.ClusterPort)),
   694  			})
   695  
   696  			By("Obtaining the last config block from an orderer")
   697  			// Get the last config block of the system channel
   698  			configBlock := nwo.GetConfigBlock(network, peer, o1, "systemchannel")
   699  			// Plant it in the file system of orderer4, the new node to be onboarded.
   700  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
   701  			Expect(err).NotTo(HaveOccurred())
   702  
   703  			By("Launching the fourth orderer")
   704  			o4Runner := network.OrdererRunner(o4)
   705  			o4Process := ifrit.Invoke(grouper.Member{Name: o4.ID(), Runner: o4Runner})
   706  
   707  			defer func() {
   708  				o4Process.Signal(syscall.SIGTERM)
   709  				Eventually(o4Process.Wait(), network.EventuallyTimeout).Should(Receive())
   710  			}()
   711  
   712  			Eventually(o4Process.Ready()).Should(BeClosed())
   713  
   714  			By("Waiting for the orderer to figure out it was migrated")
   715  			Eventually(o4Runner.Err(), time.Minute, time.Second).Should(gbytes.Say("This node was migrated from Kafka to Raft, skipping activation of Kafka chain"))
   716  
   717  			By("Adding the fourth orderer to the application channel")
   718  			addConsenter(network, peer, o1, channel1, protosraft.Consenter{
   719  				ServerTlsCert: fourthOrdererCertificate,
   720  				ClientTlsCert: fourthOrdererCertificate,
   721  				Host:          "127.0.0.1",
   722  				Port:          uint32(network.OrdererPort(o4, nwo.ClusterPort)),
   723  			})
   724  
   725  			chan1BlockNum = nwo.CurrentConfigBlockNumber(network, peer, o1, channel1)
   726  
   727  			By("Ensuring the added orderer has synced the application channel")
   728  			assertBlockReception(
   729  				map[string]int{
   730  					channel1: int(chan1BlockNum),
   731  				},
   732  				[]*nwo.Orderer{o4},
   733  				peer,
   734  				network,
   735  			)
   736  		})
   737  	})
   738  
   739  	// These tests execute the migration config updates on a solo based system, restart the orderer onto a Raft-based
   740  	// system, and verifies that the newly restarted orderer (single node) cluster performs as expected.
   741  	Describe("Solo to Raft migration", func() {
   742  		var (
   743  			orderer                        *nwo.Orderer
   744  			peer                           *nwo.Peer
   745  			syschannel, channel1, channel2 string
   746  			raftMetadata                   []byte
   747  		)
   748  
   749  		BeforeEach(func() {
   750  			network = nwo.New(solo2RaftMultiChannel(), testDir, client, StartPort(), components)
   751  			network.GenerateConfigTree()
   752  			network.Bootstrap()
   753  
   754  			orderer = network.Orderer("orderer")
   755  			peer = network.Peer("Org1", "peer0")
   756  
   757  			brokerGroup := network.BrokerGroupRunner()
   758  			brokerProc = ifrit.Invoke(brokerGroup)
   759  			Eventually(brokerProc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   760  
   761  			o1Runner = network.OrdererRunner(orderer)
   762  
   763  			o1Proc = ifrit.Invoke(o1Runner)
   764  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   765  
   766  			raftMetadata = prepareRaftMetadata(network)
   767  
   768  			syschannel = network.SystemChannel.Name
   769  			channel1 = "testchannel1"
   770  			channel2 = "testchannel2"
   771  
   772  			By("Create & join first channel, deploy and invoke chaincode")
   773  			network.CreateChannel(channel1, orderer, peer)
   774  		})
   775  
   776  		It("executes bootstrap to raft - single node", func() {
   777  			//=== Step 1: Config update on system channel, MAINTENANCE ===
   778  			By("1) Config update on system channel, State=MAINTENANCE")
   779  			config, updatedConfig := prepareTransition(network, peer, orderer, syschannel,
   780  				"solo", protosorderer.ConsensusType_STATE_NORMAL,
   781  				"solo", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   782  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   783  
   784  			By("1) Verify: system channel config changed")
   785  			sysStartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   786  			Expect(sysStartBlockNum).ToNot(Equal(0))
   787  
   788  			config = nwo.GetConfig(network, peer, orderer, syschannel)
   789  			updatedConfig, consensusTypeValue, err := extractOrdererConsensusType(config)
   790  			Expect(err).NotTo(HaveOccurred())
   791  			validateConsensusTypeValue(consensusTypeValue, "solo", protosorderer.ConsensusType_STATE_MAINTENANCE)
   792  
   793  			//=== Step 2: Config update on standard channel, MAINTENANCE ===
   794  			By("2) Config update on standard channel, State=MAINTENANCE")
   795  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   796  				"solo", protosorderer.ConsensusType_STATE_NORMAL,
   797  				"solo", nil, protosorderer.ConsensusType_STATE_MAINTENANCE)
   798  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   799  
   800  			By("2) Verify: standard channel config changed")
   801  			chan1StartBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   802  			Expect(chan1StartBlockNum).ToNot(Equal(0))
   803  
   804  			config = nwo.GetConfig(network, peer, orderer, channel1)
   805  			updatedConfig, consensusTypeValue, err = extractOrdererConsensusType(config)
   806  			Expect(err).NotTo(HaveOccurred())
   807  			validateConsensusTypeValue(consensusTypeValue, "solo", protosorderer.ConsensusType_STATE_MAINTENANCE)
   808  
   809  			//=== Step 3: config update on system channel, State=MAINTENANCE, type=etcdraft ===
   810  			By("3) Config update on system channel, State=MAINTENANCE, type=etcdraft")
   811  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   812  				"solo", protosorderer.ConsensusType_STATE_MAINTENANCE,
   813  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   814  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   815  
   816  			By("3) Verify: system channel config changed")
   817  			sysBlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   818  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 1))
   819  
   820  			//=== Step 4: config update on standard channel, State=MAINTENANCE, type=etcdraft ===
   821  			By("4) Config update on standard channel, State=MAINTENANCE, type=etcdraft")
   822  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   823  				"solo", protosorderer.ConsensusType_STATE_MAINTENANCE,
   824  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_MAINTENANCE)
   825  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   826  
   827  			By("4) Verify: standard channel config changed")
   828  			chan1BlockNum := nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   829  			Expect(chan1BlockNum).To(Equal(chan1StartBlockNum + 1))
   830  
   831  			//=== Step 5: kill ===
   832  			By("5) killing orderer1")
   833  			o1Proc.Signal(syscall.SIGKILL)
   834  			Eventually(o1Proc.Wait(), network.EventuallyTimeout).Should(Receive(MatchError("exit status 137")))
   835  
   836  			//=== Step 6: restart ===
   837  			By("6) restarting orderer1")
   838  			network.Consensus.Type = "etcdraft"
   839  
   840  			o1Runner = network.OrdererRunner(orderer)
   841  			o1Proc = ifrit.Invoke(o1Runner)
   842  
   843  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   844  
   845  			assertBlockReception(
   846  				map[string]int{
   847  					syschannel: int(sysBlockNum),
   848  					channel1:   int(chan1BlockNum),
   849  				},
   850  				[]*nwo.Orderer{orderer},
   851  				peer,
   852  				network,
   853  			)
   854  
   855  			Eventually(o1Runner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Raft leader changed: 0 -> "))
   856  			Eventually(o1Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   857  
   858  			By("7) System channel still in maintenance, State=MAINTENANCE, cannot create new channels")
   859  			exitCode := network.CreateChannelExitCode(channel2, orderer, peer)
   860  			Expect(exitCode).ToNot(Equal(0))
   861  
   862  			By("8) Standard channel still in maintenance, State=MAINTENANCE, normal TX's blocked, delivery to peers blocked")
   863  			assertTxFailed(network, orderer, channel1)
   864  
   865  			err = checkPeerDeliverRequest(orderer, peer, network, channel1)
   866  			Expect(err).To(MatchError(errors.New("FORBIDDEN")))
   867  
   868  			By("9) Release - executing config transaction on system channel with restarted orderer")
   869  			config, updatedConfig = prepareTransition(network, peer, orderer, syschannel,
   870  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   871  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   872  			nwo.UpdateOrdererConfig(network, orderer, syschannel, config, updatedConfig, peer, orderer)
   873  
   874  			By("9) Verify: system channel config changed")
   875  			sysBlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, syschannel)
   876  			Expect(sysBlockNum).To(Equal(sysStartBlockNum + 2))
   877  
   878  			By("10) Release - executing config transaction on standard channel with restarted orderer")
   879  			config, updatedConfig = prepareTransition(network, peer, orderer, channel1,
   880  				"etcdraft", protosorderer.ConsensusType_STATE_MAINTENANCE,
   881  				"etcdraft", raftMetadata, protosorderer.ConsensusType_STATE_NORMAL)
   882  			nwo.UpdateOrdererConfig(network, orderer, channel1, config, updatedConfig, peer, orderer)
   883  
   884  			By("10) Verify: standard channel config changed")
   885  			chan1BlockNum = nwo.CurrentConfigBlockNumber(network, peer, orderer, channel1)
   886  			Expect(chan1BlockNum).To(Equal(chan1StartBlockNum + 2))
   887  
   888  			By("11) Executing transaction on standard channel with restarted orderer")
   889  			assertBlockCreation(network, orderer, peer, channel1, chan1StartBlockNum+3)
   890  			assertBlockCreation(network, orderer, nil, channel1, chan1StartBlockNum+4)
   891  
   892  			By("12) Create new channel, executing transaction with restarted orderer")
   893  			network.CreateChannel(channel2, orderer, peer)
   894  
   895  			assertBlockCreation(network, orderer, peer, channel2, 1)
   896  			assertBlockCreation(network, orderer, nil, channel2, 2)
   897  
   898  			By("13) Extending the network configuration to add a new orderer")
   899  			// Add another orderer
   900  			orderer2 := &nwo.Orderer{
   901  				Name:         "orderer2",
   902  				Organization: "OrdererOrg",
   903  			}
   904  			ports := nwo.Ports{}
   905  			for _, portName := range nwo.OrdererPortNames() {
   906  				ports[portName] = network.ReservePort()
   907  			}
   908  			network.PortsByOrdererID[orderer2.ID()] = ports
   909  			network.Orderers = append(network.Orderers, orderer2)
   910  			network.GenerateOrdererConfig(orderer2)
   911  			extendNetwork(network)
   912  
   913  			secondOrdererCertificatePath := filepath.Join(network.OrdererLocalTLSDir(orderer2), "server.crt")
   914  			secondOrdererCertificate, err := ioutil.ReadFile(secondOrdererCertificatePath)
   915  			Expect(err).NotTo(HaveOccurred())
   916  
   917  			By("14) Adding the second orderer to system channel")
   918  			addConsenter(network, peer, orderer, syschannel, etcdraft.Consenter{
   919  				ServerTlsCert: secondOrdererCertificate,
   920  				ClientTlsCert: secondOrdererCertificate,
   921  				Host:          "127.0.0.1",
   922  				Port:          uint32(network.OrdererPort(orderer2, nwo.ClusterPort)),
   923  			})
   924  
   925  			By("15) Obtaining the last config block from the orderer")
   926  			configBlock := nwo.GetConfigBlock(network, peer, orderer, syschannel)
   927  			err = ioutil.WriteFile(filepath.Join(testDir, "systemchannel_block.pb"), protoutil.MarshalOrPanic(configBlock), 0644)
   928  			Expect(err).NotTo(HaveOccurred())
   929  
   930  			By("16) Waiting for the existing orderer to relinquish its leadership")
   931  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("1 stepped down to follower since quorum is not active"))
   932  			Eventually(o1Runner.Err(), network.EventuallyTimeout).Should(gbytes.Say("No leader is present, cluster size is 2"))
   933  
   934  			By("17) Launching the second orderer")
   935  			o2Runner = network.OrdererRunner(orderer2)
   936  			o2Proc = ifrit.Invoke(o2Runner)
   937  			Eventually(o2Proc.Ready(), network.EventuallyTimeout).Should(BeClosed())
   938  			Eventually(o2Runner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Raft leader changed: 0 -> "))
   939  
   940  			By("18) Adding orderer2 to channel2")
   941  			addConsenter(network, peer, orderer, channel2, etcdraft.Consenter{
   942  				ServerTlsCert: secondOrdererCertificate,
   943  				ClientTlsCert: secondOrdererCertificate,
   944  				Host:          "127.0.0.1",
   945  				Port:          uint32(network.OrdererPort(orderer2, nwo.ClusterPort)),
   946  			})
   947  
   948  			assertBlockReception(map[string]int{
   949  				syschannel: int(sysBlockNum + 2),
   950  				channel2:   int(nwo.CurrentConfigBlockNumber(network, peer, orderer, channel2)),
   951  			}, []*nwo.Orderer{orderer2}, peer, network)
   952  
   953  			By("19) Executing transaction against second orderer on channel2")
   954  			assertBlockCreation(network, orderer2, nil, channel2, 3)
   955  		})
   956  	})
   957  })
   958  
   959  func validateConsensusTypeValue(value *protosorderer.ConsensusType, cType string, state protosorderer.ConsensusType_State) {
   960  	Expect(value.Type).To(Equal(cType))
   961  	Expect(value.State).To(Equal(state))
   962  }
   963  
   964  func extractOrdererConsensusType(config *common.Config) (*common.Config, *protosorderer.ConsensusType, error) {
   965  	updatedConfig := proto.Clone(config).(*common.Config)
   966  	consensusTypeConfigValue := updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"]
   967  	consensusTypeValue := new(protosorderer.ConsensusType)
   968  	err := proto.Unmarshal(consensusTypeConfigValue.Value, consensusTypeValue)
   969  	return updatedConfig, consensusTypeValue, err
   970  }
   971  
   972  func updateConfigWithConsensusType(
   973  	consensusType string,
   974  	consensusMetadata []byte,
   975  	migState protosorderer.ConsensusType_State,
   976  	updatedConfig *common.Config,
   977  	consensusTypeValue *protosorderer.ConsensusType,
   978  ) {
   979  	consensusTypeValue.Type = consensusType
   980  	consensusTypeValue.Metadata = consensusMetadata
   981  	consensusTypeValue.State = migState
   982  	updatedConfig.ChannelGroup.Groups["Orderer"].Values["ConsensusType"] = &common.ConfigValue{
   983  		ModPolicy: "Admins",
   984  		Value:     protoutil.MarshalOrPanic(consensusTypeValue),
   985  	}
   986  }
   987  
   988  func updateConfigWithBatchTimeout(updatedConfig *common.Config) {
   989  	batchTimeoutConfigValue := updatedConfig.ChannelGroup.Groups["Orderer"].Values["BatchTimeout"]
   990  	batchTimeoutValue := new(protosorderer.BatchTimeout)
   991  	err := proto.Unmarshal(batchTimeoutConfigValue.Value, batchTimeoutValue)
   992  	Expect(err).NotTo(HaveOccurred())
   993  	toDur, err := time.ParseDuration(batchTimeoutValue.Timeout)
   994  	Expect(err).NotTo(HaveOccurred())
   995  	toDur = toDur + time.Duration(100000000)
   996  	batchTimeoutValue.Timeout = toDur.String()
   997  	By(fmt.Sprintf("Increasing BatchTimeout to %s", batchTimeoutValue.Timeout))
   998  	updatedConfig.ChannelGroup.Groups["Orderer"].Values["BatchTimeout"] = &common.ConfigValue{
   999  		ModPolicy: "Admins",
  1000  		Value:     protoutil.MarshalOrPanic(batchTimeoutValue),
  1001  	}
  1002  }
  1003  
  1004  func kafka2RaftMultiChannel() *nwo.Config {
  1005  	config := nwo.BasicKafka()
  1006  	config.Channels = []*nwo.Channel{
  1007  		{Name: "testchannel1", Profile: "TwoOrgsChannel"},
  1008  		{Name: "testchannel2", Profile: "TwoOrgsChannel"},
  1009  		{Name: "testchannel3", Profile: "TwoOrgsChannel"},
  1010  	}
  1011  
  1012  	for _, peer := range config.Peers {
  1013  		peer.Channels = []*nwo.PeerChannel{
  1014  			{Name: "testchannel1", Anchor: true},
  1015  			{Name: "testchannel2", Anchor: true},
  1016  			{Name: "testchannel3", Anchor: true},
  1017  		}
  1018  	}
  1019  	return config
  1020  }
  1021  
  1022  func solo2RaftMultiChannel() *nwo.Config {
  1023  	config := nwo.BasicSolo()
  1024  	config.Channels = []*nwo.Channel{
  1025  		{Name: "testchannel1", Profile: "TwoOrgsChannel"},
  1026  		{Name: "testchannel2", Profile: "TwoOrgsChannel"},
  1027  	}
  1028  
  1029  	for _, peer := range config.Peers {
  1030  		peer.Channels = []*nwo.PeerChannel{
  1031  			{Name: "testchannel1", Anchor: true},
  1032  			{Name: "testchannel2", Anchor: true},
  1033  		}
  1034  	}
  1035  	return config
  1036  }
  1037  
  1038  func kafka2RaftMultiNode() *nwo.Config {
  1039  	config := nwo.BasicKafka()
  1040  	config.Orderers = []*nwo.Orderer{
  1041  		{Name: "orderer1", Organization: "OrdererOrg"},
  1042  		{Name: "orderer2", Organization: "OrdererOrg"},
  1043  		{Name: "orderer3", Organization: "OrdererOrg"},
  1044  	}
  1045  
  1046  	config.Profiles = []*nwo.Profile{{
  1047  		Name:     "TwoOrgsOrdererGenesis",
  1048  		Orderers: []string{"orderer1", "orderer2", "orderer3"},
  1049  	}, {
  1050  		Name:          "TwoOrgsChannel",
  1051  		Consortium:    "SampleConsortium",
  1052  		Organizations: []string{"Org1", "Org2"},
  1053  	}}
  1054  
  1055  	config.Channels = []*nwo.Channel{
  1056  		{Name: "testchannel1", Profile: "TwoOrgsChannel"},
  1057  		{Name: "testchannel2", Profile: "TwoOrgsChannel"},
  1058  		{Name: "testchannel3", Profile: "TwoOrgsChannel"},
  1059  	}
  1060  
  1061  	for _, peer := range config.Peers {
  1062  		peer.Channels = []*nwo.PeerChannel{
  1063  			{Name: "testchannel1", Anchor: true},
  1064  			{Name: "testchannel2", Anchor: true},
  1065  			{Name: "testchannel3", Anchor: true},
  1066  		}
  1067  	}
  1068  	return config
  1069  }
  1070  
  1071  func prepareRaftMetadata(network *nwo.Network) []byte {
  1072  	var consenters []*protosraft.Consenter
  1073  	for _, o := range network.Orderers {
  1074  		fullTlsPath := network.OrdererLocalTLSDir(o)
  1075  		certBytes, err := ioutil.ReadFile(filepath.Join(fullTlsPath, "server.crt"))
  1076  		Expect(err).NotTo(HaveOccurred())
  1077  		port := network.OrdererPort(o, nwo.ClusterPort)
  1078  
  1079  		consenter := &protosraft.Consenter{
  1080  			ClientTlsCert: certBytes,
  1081  			ServerTlsCert: certBytes,
  1082  			Host:          "127.0.0.1",
  1083  			Port:          uint32(port),
  1084  		}
  1085  		consenters = append(consenters, consenter)
  1086  	}
  1087  
  1088  	raftMetadata := &protosraft.ConfigMetadata{
  1089  		Consenters: consenters,
  1090  		Options: &protosraft.Options{
  1091  			TickInterval:         "500ms",
  1092  			ElectionTick:         10,
  1093  			HeartbeatTick:        1,
  1094  			MaxInflightBlocks:    5,
  1095  			SnapshotIntervalSize: 10 * 1024 * 1024,
  1096  		},
  1097  	}
  1098  
  1099  	raftMetadataBytes := protoutil.MarshalOrPanic(raftMetadata)
  1100  
  1101  	return raftMetadataBytes
  1102  }
  1103  
  1104  func checkPeerDeliverRequest(o *nwo.Orderer, submitter *nwo.Peer, network *nwo.Network, channelName string) error {
  1105  	c := commands.ChannelFetch{
  1106  		ChannelID:  channelName,
  1107  		Block:      "newest",
  1108  		OutputFile: "/dev/null",
  1109  		Orderer:    network.OrdererAddress(o, nwo.ListenPort),
  1110  	}
  1111  
  1112  	sess, err := network.PeerUserSession(submitter, "User1", c)
  1113  	Expect(err).NotTo(HaveOccurred())
  1114  	Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit())
  1115  	sessErr := string(sess.Err.Contents())
  1116  	sessExitCode := sess.ExitCode()
  1117  	if sessExitCode != 0 && strings.Contains(sessErr, "FORBIDDEN") {
  1118  		return errors.New("FORBIDDEN")
  1119  	}
  1120  	if sessExitCode == 0 && strings.Contains(sessErr, "Received block: ") {
  1121  		return nil
  1122  	}
  1123  
  1124  	return fmt.Errorf("Unexpected result: ExitCode=%d, Err=%s", sessExitCode, sessErr)
  1125  }
  1126  
  1127  func updateOrdererConfigFailed(n *nwo.Network, orderer *nwo.Orderer, channel string, current, updated *common.Config, peer *nwo.Peer, additionalSigners ...*nwo.Orderer) {
  1128  	sess := nwo.UpdateOrdererConfigSession(n, orderer, channel, current, updated, peer, additionalSigners...)
  1129  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(1))
  1130  	Expect(sess.Err).NotTo(gbytes.Say("Successfully submitted channel update"))
  1131  }
  1132  
  1133  func prepareTransition(
  1134  	network *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, // Auxiliary
  1135  	fromConsensusType string, fromMigState protosorderer.ConsensusType_State, // From
  1136  	toConsensusType string, toConsensusMetadata []byte, toMigState protosorderer.ConsensusType_State, // To
  1137  ) (current, updated *common.Config) {
  1138  	current = nwo.GetConfig(network, peer, orderer, channel)
  1139  	updated, consensusTypeValue, err := extractOrdererConsensusType(current)
  1140  	Expect(err).NotTo(HaveOccurred())
  1141  	validateConsensusTypeValue(consensusTypeValue, fromConsensusType, fromMigState)
  1142  	updateConfigWithConsensusType(toConsensusType, toConsensusMetadata, toMigState, updated, consensusTypeValue)
  1143  	return current, updated
  1144  }
  1145  
  1146  func assertTransitionFailed(
  1147  	network *nwo.Network, peer *nwo.Peer, orderer *nwo.Orderer, channel string, // Auxiliary
  1148  	fromConsensusType string, fromMigState protosorderer.ConsensusType_State, // From
  1149  	toConsensusType string, toConsensusMetadata []byte, toMigState protosorderer.ConsensusType_State, // To
  1150  ) {
  1151  	current, updated := prepareTransition(
  1152  		network, peer, orderer, channel,
  1153  		fromConsensusType, fromMigState,
  1154  		toConsensusType, toConsensusMetadata, toMigState)
  1155  	updateOrdererConfigFailed(network, orderer, channel, current, updated, peer, orderer)
  1156  }
  1157  
  1158  func assertBlockCreation(network *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer,
  1159  	channelID string, blkNum uint64) {
  1160  	var signer interface{}
  1161  	signer = orderer
  1162  	if peer != nil {
  1163  		signer = peer
  1164  	}
  1165  	env := CreateBroadcastEnvelope(network, signer, channelID, []byte("hola"))
  1166  	resp, err := nwo.Broadcast(network, orderer, env)
  1167  	Expect(err).NotTo(HaveOccurred())
  1168  	Expect(resp.Status).To(Equal(common.Status_SUCCESS))
  1169  
  1170  	denv := CreateDeliverEnvelope(network, orderer, blkNum, channelID)
  1171  	blk, err := nwo.Deliver(network, orderer, denv)
  1172  	Expect(err).NotTo(HaveOccurred())
  1173  	Expect(blk).ToNot(BeNil())
  1174  }
  1175  
  1176  func assertTxFailed(network *nwo.Network, orderer *nwo.Orderer, channelID string) {
  1177  	env := CreateBroadcastEnvelope(network, orderer, channelID, []byte("hola"))
  1178  	resp, err := nwo.Broadcast(network, orderer, env)
  1179  	Expect(err).NotTo(HaveOccurred())
  1180  	Expect(resp.Status).To(Equal(common.Status_SERVICE_UNAVAILABLE))
  1181  	Expect(resp.Info).To(Equal("normal transactions are rejected: maintenance mode"))
  1182  }