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