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