diff --git a/integration/raft/channel_participation_test.go b/integration/raft/channel_participation_test.go index 7eb88fc421c..ba993c1ef9e 100644 --- a/integration/raft/channel_participation_test.go +++ b/integration/raft/channel_participation_test.go @@ -517,10 +517,11 @@ var _ = Describe("ChannelParticipation", func() { }) }) - It("creates the system channel with a genesis block", func() { + It("creates the system channel on two orderers with a genesis block and joins a third using a config block", func() { orderer1 := network.Orderer("orderer1") orderer2 := network.Orderer("orderer2") orderer3 := network.Orderer("orderer3") + orderers1and2 := []*nwo.Orderer{orderer1, orderer2} orderers := []*nwo.Orderer{orderer1, orderer2, orderer3} org1peer0 := network.Peer("Org1", "peer0") org2peer0 := network.Peer("Org2", "peer0") @@ -530,7 +531,7 @@ var _ = Describe("ChannelParticipation", func() { startOrderer(o) } - systemChannelGenesisBlock := systemChannelGenesisBlock(network, orderers, peers, network.SystemChannel.Name) + systemChannelGenesisBlock := systemChannelGenesisBlock(network, orderers1and2, peers, network.SystemChannel.Name) expectedChannelInfo := channelparticipation.ChannelInfo{ Name: "systemchannel", @@ -541,7 +542,7 @@ var _ = Describe("ChannelParticipation", func() { } By("joining orderers to systemchannel") - for _, o := range orderers { + for _, o := range orderers1and2 { channelparticipation.Join(network, o, "systemchannel", systemChannelGenesisBlock, expectedChannelInfo) } @@ -549,14 +550,14 @@ var _ = Describe("ChannelParticipation", func() { channelparticipationJoinFailure(network, orderer1, "systemchannel", systemChannelGenesisBlock, http.StatusMethodNotAllowed, "cannot join: system channel exists") By("ensuring the system channel is unusable before restarting by attempting to submit a transaction") - for _, o := range orderers { + for _, o := range orderers1and2 { By("submitting transaction to " + o.Name) env := CreateBroadcastEnvelope(network, org1peer0, "systemchannel", []byte("hello")) Expect(broadcastTransactionFunc(network, o, env)()).To(Equal(common.Status_FORBIDDEN)) } - By("restarting all orderers") - for i, o := range orderers { + By("restarting all orderers in the system channel") + for i, o := range orderers1and2 { restartOrderer(o, i) } @@ -570,14 +571,14 @@ var _ = Describe("ChannelParticipation", func() { ConsensusRelation: "consenter", Height: 1, } - for _, o := range orderers { + for _, o := range orderers1and2 { By("listing single channel for " + o.Name) Eventually(func() channelparticipation.ChannelInfo { return channelparticipation.ListOne(network, o, "testchannel") }, network.EventuallyTimeout).Should(Equal(expectedChannelInfo)) } - for _, o := range orderers { + for _, o := range orderers1and2 { By("listing the channels for " + o.Name) cl := channelparticipation.List(network, o) channelparticipation.ChannelListMatcher(cl, []string{"testchannel"}, []string{"systemchannel"}...) @@ -590,6 +591,87 @@ var _ = Describe("ChannelParticipation", func() { ConsensusRelation: "consenter", Height: 2, } + for _, o := range orderers1and2 { + By("listing single channel for " + o.Name) + Eventually(func() channelparticipation.ChannelInfo { + return channelparticipation.ListOne(network, o, "systemchannel") + }, network.EventuallyTimeout).Should(Equal(expectedChannelInfo)) + } + + By("submitting transaction to each active orderer to confirm channel is usable") + submitPeerTxn(orderer1, org1peer0, network, orderers1and2, 4, channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 2, + }) + + submitPeerTxn(orderer2, org1peer0, network, orderers1and2, 4, channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 3, + }) + + By("submitting a channel config update for the system channel") + channelConfig := nwo.GetConfig(network, org1peer0, orderer1, "systemchannel") + c := configtx.New(channelConfig) + err := c.Orderer().SetBatchTimeout(4 * time.Second) + Expect(err).NotTo(HaveOccurred()) + err = c.Orderer().AddConsenter(consenterChannelConfig(network, orderer3)) + Expect(err).NotTo(HaveOccurred()) + computeSignSubmitConfigUpdate(network, orderer1, org1peer0, c, "systemchannel") + currentBlockNumber := nwo.CurrentConfigBlockNumber(network, org1peer0, orderer1, "systemchannel") + Expect(currentBlockNumber).To(BeNumerically(">", 1)) + + By("joining orderer3 to the system channel") + // make sure we can join using a config block from one of the other orderers + configBlockSC := nwo.GetConfigBlock(network, org1peer0, orderer2, "systemchannel") + expectedChannelInfo = channelparticipation.ChannelInfo{ + Name: "systemchannel", + URL: "/participation/v1/channels/systemchannel", + Status: "inactive", + ClusterRelation: "consenter", + Height: 0, + } + channelparticipation.Join(network, orderer3, "systemchannel", configBlockSC, expectedChannelInfo) + + By("restarting orderer3") + restartOrderer(orderer3, 2) + + By("listing the channels for " + orderer3.Name) + channelparticipation.List(network, orderer3, []string{"testchannel"}, "systemchannel") + + By("ensuring orderer3 catches up to the latest height as an active consenter") + expectedChannelInfo.Status = "active" + expectedChannelInfo.Height = 3 + Eventually(func() channelparticipation.ChannelInfo { + return channelparticipation.ListOne(network, orderer3, "systemchannel") + }, network.EventuallyTimeout).Should(Equal(expectedChannelInfo)) + + By("submitting a channel config update to add orderer3 to the endpoints") + channelConfig = nwo.GetConfig(network, org1peer0, orderer1, "systemchannel") + c = configtx.New(channelConfig) + host, port := conftx.OrdererHostPort(network, orderer3) + err = c.Orderer().Organization(orderer3.Organization).SetEndpoint( + configtx.Address{ + Host: host, + Port: port, + }, + ) + Expect(err).NotTo(HaveOccurred()) + computeSignSubmitConfigUpdate(network, orderer2, org1peer0, c, "systemchannel") + + By("ensuring all orderers are active consenters for the system channel") + expectedChannelInfo = channelparticipation.ChannelInfo{ + Name: "systemchannel", + URL: "/participation/v1/channels/systemchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 4, + } for _, o := range orderers { By("listing single channel for " + o.Name) Eventually(func() channelparticipation.ChannelInfo { @@ -597,9 +679,56 @@ var _ = Describe("ChannelParticipation", func() { }, network.EventuallyTimeout).Should(Equal(expectedChannelInfo)) } - By("submitting transaction to orderer to confirm channel is usable") - env := CreateBroadcastEnvelope(network, org1peer0, "testchannel", []byte("hello")) - Eventually(broadcastTransactionFunc(network, orderer1, env), network.EventuallyTimeout).Should(Equal(common.Status_SUCCESS)) + By("adding orderer3 to the consenters set and endpoints of the application channel") + channelConfig = nwo.GetConfig(network, org1peer0, orderer1, "testchannel") + c = configtx.New(channelConfig) + err = c.Orderer().AddConsenter(consenterChannelConfig(network, orderer3)) + Expect(err).NotTo(HaveOccurred()) + err = c.Orderer().Organization(orderer3.Organization).SetEndpoint( + configtx.Address{ + Host: host, + Port: port, + }, + ) + Expect(err).NotTo(HaveOccurred()) + computeSignSubmitConfigUpdate(network, orderer1, org1peer0, c, "testchannel") + + By("ensuring orderer3 becomes an active consenter for the application channel") + expectedChannelInfo = channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 4, + } + Eventually(func() channelparticipation.ChannelInfo { + return channelparticipation.ListOne(network, orderer3, "testchannel") + }, network.EventuallyTimeout).Should(Equal(expectedChannelInfo)) + + By("submitting transactions to ensure the application channel is usable") + submitPeerTxn(orderer3, org1peer0, network, orderers1and2, 4, channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 5, + }) + + submitPeerTxn(orderer2, org1peer0, network, orderers1and2, 4, channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 6, + }) + + submitPeerTxn(orderer1, org1peer0, network, orderers1and2, 4, channelparticipation.ChannelInfo{ + Name: "testchannel", + URL: "/participation/v1/channels/testchannel", + Status: "active", + ClusterRelation: "consenter", + Height: 7, + }) }) })