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 }