Skip to content

Commit 0d2e187

Browse files
committed
added to OSN new handler for update config of channel
Signed-off-by: Fedor Partanskiy <[email protected]>
1 parent 118c432 commit 0d2e187

File tree

8 files changed

+213
-175
lines changed

8 files changed

+213
-175
lines changed

integration/nwo/channel_participation.go

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Join(n *Network, o *Orderer, channel string, block *common.Block, expectedC
4141
if n.TLSEnabled {
4242
client = authClient
4343
}
44-
body := doBody(client, req)
44+
body := doBody(client, req, http.StatusCreated)
4545
c := &ChannelInfo{}
4646
err = json.Unmarshal(body, c)
4747
Expect(err).NotTo(HaveOccurred())
@@ -64,14 +64,71 @@ func GenerateJoinRequest(url, channel string, blockBytes []byte) *http.Request {
6464
return req
6565
}
6666

67-
func doBody(client *http.Client, req *http.Request) []byte {
67+
func Update(n *Network, o *Orderer, channel string, envelope *common.Envelope) {
68+
UpdateTimeShift(n, o, channel, envelope, 0)
69+
}
70+
71+
func UpdateTimeShift(n *Network, o *Orderer, channel string, envelope *common.Envelope, timeShift time.Duration) {
72+
UpdateFull(n, o, channel, envelope, timeShift, http.StatusCreated, "")
73+
}
74+
75+
func UpdateWithStatus(n *Network, o *Orderer, channel string, envelope *common.Envelope, expectedStatus int, errStr string) {
76+
UpdateFull(n, o, channel, envelope, 0, expectedStatus, errStr)
77+
}
78+
79+
func UpdateFull(n *Network, o *Orderer, channel string, envelope *common.Envelope, timeShift time.Duration, expectedStatus int, errStr string) {
80+
envelopeBytes, err := proto.Marshal(envelope)
81+
Expect(err).NotTo(HaveOccurred())
82+
83+
protocol := "http"
84+
if n.TLSEnabled {
85+
protocol = "https"
86+
}
87+
url := fmt.Sprintf("%s://127.0.0.1:%d/participation/v1/channels", protocol, n.OrdererPort(o, AdminPort))
88+
req := GenerateUpdateRequest(url, channel, envelopeBytes)
89+
authClient, unauthClient := OrdererOperationalClientsTimeShift(n, o, timeShift)
90+
91+
client := unauthClient
92+
if n.TLSEnabled {
93+
client = authClient
94+
}
95+
body := doBody(client, req, expectedStatus)
96+
if errStr != "" {
97+
Expect(string(body)).To(ContainSubstring(errStr))
98+
99+
return
100+
}
101+
c := &ChannelInfo{}
102+
err = json.Unmarshal(body, c)
103+
Expect(err).NotTo(HaveOccurred())
104+
}
105+
106+
func GenerateUpdateRequest(url, channel string, envelopeBytes []byte) *http.Request {
107+
updateBody := new(bytes.Buffer)
108+
writer := multipart.NewWriter(updateBody)
109+
part, err := writer.CreateFormFile("config-update-envelope", fmt.Sprintf("%s-update.envelope", channel))
110+
Expect(err).NotTo(HaveOccurred())
111+
part.Write(envelopeBytes)
112+
err = writer.Close()
113+
Expect(err).NotTo(HaveOccurred())
114+
115+
req, err := http.NewRequest(http.MethodPut, url, updateBody)
116+
Expect(err).NotTo(HaveOccurred())
117+
req.Header.Set("Content-Type", writer.FormDataContentType())
118+
119+
return req
120+
}
121+
122+
func doBody(client *http.Client, req *http.Request, expectedStatus int) []byte {
68123
resp, err := client.Do(req)
69124
Expect(err).NotTo(HaveOccurred())
70-
Expect(resp.StatusCode).To(Equal(http.StatusCreated))
125+
71126
bodyBytes, err := io.ReadAll(resp.Body)
72127
Expect(err).NotTo(HaveOccurred())
73128
resp.Body.Close()
74129

130+
Expect(resp.StatusCode).To(Equal(expectedStatus), string(bodyBytes))
131+
75132
return bodyBytes
76133
}
77134

integration/nwo/commands/peer.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -646,32 +646,6 @@ func (s SignConfigTx) Args() []string {
646646
return args
647647
}
648648

649-
type ChannelUpdate struct {
650-
ChannelID string
651-
Orderer string
652-
File string
653-
ClientAuth bool
654-
TLSHandshakeTimeShift time.Duration
655-
}
656-
657-
func (c ChannelUpdate) SessionName() string {
658-
return "peer-channel-update"
659-
}
660-
661-
func (c ChannelUpdate) Args() []string {
662-
args := []string{
663-
"channel", "update",
664-
"--channelID", c.ChannelID,
665-
"--orderer", c.Orderer,
666-
"--file", c.File,
667-
"--tlsHandshakeTimeShift", c.TLSHandshakeTimeShift.String(),
668-
}
669-
if c.ClientAuth {
670-
args = append(args, "--clientauth")
671-
}
672-
return args
673-
}
674-
675649
type ChannelInfo struct {
676650
ChannelID string
677651
ClientAuth bool

integration/nwo/configblock.go

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ SPDX-License-Identifier: Apache-2.0
77
package nwo
88

99
import (
10+
"net/http"
1011
"os"
1112
"path/filepath"
12-
"strings"
13-
14-
"github.com/hyperledger/fabric/common/channelconfig"
15-
"github.com/hyperledger/fabric/common/policies"
1613

1714
"github.com/hyperledger/fabric-protos-go-apiv2/common"
1815
"github.com/hyperledger/fabric-protos-go-apiv2/msp"
1916
protosorderer "github.com/hyperledger/fabric-protos-go-apiv2/orderer"
17+
"github.com/hyperledger/fabric/common/channelconfig"
18+
"github.com/hyperledger/fabric/common/policies"
2019
"github.com/hyperledger/fabric/integration/nwo/commands"
2120
"github.com/hyperledger/fabric/internal/configtxlator/update"
2221
"github.com/hyperledger/fabric/protoutil"
22+
. "github.com/onsi/ginkgo/v2"
2323
. "github.com/onsi/gomega"
2424
"github.com/onsi/gomega/gbytes"
2525
"github.com/onsi/gomega/gexec"
@@ -126,6 +126,13 @@ func UpdateConfig(n *Network, orderer *Orderer, channel string, current, updated
126126
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
127127
}
128128

129+
sess, err := n.PeerAdminSession(submitter, commands.SignConfigTx{
130+
File: updateFile,
131+
ClientAuth: n.ClientAuthRequired,
132+
})
133+
Expect(err).NotTo(HaveOccurred())
134+
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
135+
129136
var currentBlockNumber uint64
130137
// get current configuration block number
131138
if getConfigBlockFromOrderer {
@@ -134,15 +141,20 @@ func UpdateConfig(n *Network, orderer *Orderer, channel string, current, updated
134141
currentBlockNumber = CurrentConfigBlockNumber(n, submitter, nil, channel)
135142
}
136143

137-
sess, err := n.PeerAdminSession(submitter, commands.ChannelUpdate{
138-
ChannelID: channel,
139-
Orderer: n.OrdererAddress(orderer, ListenPort),
140-
File: updateFile,
141-
ClientAuth: n.ClientAuthRequired,
142-
})
144+
updateEnvelopeBytes, err := os.ReadFile(updateFile)
145+
Expect(err).NotTo(HaveOccurred())
146+
147+
updateEnvelope := &common.Envelope{}
148+
err = proto.Unmarshal(updateEnvelopeBytes, updateEnvelope)
143149
Expect(err).NotTo(HaveOccurred())
144-
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
145-
Expect(sess.Err).To(gbytes.Say("Successfully submitted channel update"))
150+
151+
ready := make(chan struct{})
152+
go func() {
153+
defer GinkgoRecover()
154+
Update(n, orderer, channel, updateEnvelope)
155+
close(ready)
156+
}()
157+
Eventually(ready, n.EventuallyTimeout).Should(BeClosed())
146158

147159
if getConfigBlockFromOrderer {
148160
ccb := func() uint64 { return CurrentConfigBlockNumber(n, submitter, orderer, channel) }
@@ -209,47 +221,57 @@ func UpdateOrdererConfig(n *Network, orderer *Orderer, channel string, current,
209221
currentBlockNumber := CurrentConfigBlockNumber(n, submitter, orderer, channel)
210222
ComputeUpdateOrdererConfig(updateFile, n, channel, current, updated, submitter, additionalSigners...)
211223

212-
Eventually(func() bool {
213-
sess, err := n.OrdererAdminSession(orderer, submitter, commands.ChannelUpdate{
214-
ChannelID: channel,
215-
Orderer: n.OrdererAddress(orderer, ListenPort),
216-
File: updateFile,
217-
ClientAuth: n.ClientAuthRequired,
218-
})
219-
Expect(err).NotTo(HaveOccurred())
224+
updateEnvelopeBytes, err := os.ReadFile(updateFile)
225+
Expect(err).NotTo(HaveOccurred())
220226

221-
sess.Wait(n.EventuallyTimeout)
222-
if sess.ExitCode() != 0 {
223-
return false
224-
}
227+
updateEnvelope := &common.Envelope{}
228+
err = proto.Unmarshal(updateEnvelopeBytes, updateEnvelope)
229+
Expect(err).NotTo(HaveOccurred())
225230

226-
return strings.Contains(string(sess.Err.Contents()), "Successfully submitted channel update")
227-
}, n.EventuallyTimeout).Should(BeTrue())
231+
ready := make(chan struct{})
232+
go func() {
233+
defer GinkgoRecover()
234+
Update(n, orderer, channel, updateEnvelope)
235+
close(ready)
236+
}()
237+
Eventually(ready, n.EventuallyTimeout).Should(BeClosed())
228238

229239
// wait for the block to be committed
230240
ccb := func() uint64 { return CurrentConfigBlockNumber(n, submitter, orderer, channel) }
231241
Eventually(ccb, n.EventuallyTimeout).Should(BeNumerically(">", currentBlockNumber))
232242
}
233243

234-
// UpdateOrdererConfigSession computes, signs, and submits a configuration
244+
// UpdateOrdererConfigFails computes, signs, and submits a configuration
235245
// update which requires orderer signatures. The caller should wait on the
236246
// returned seession retrieve the exit code.
237-
func UpdateOrdererConfigSession(n *Network, orderer *Orderer, channel string, current, updated *common.Config, submitter *Peer, additionalSigners ...*Orderer) *gexec.Session {
247+
func UpdateOrdererConfigFails(n *Network, orderer *Orderer, channel string, current, updated *common.Config, errStr string, submitter *Peer, additionalSigners ...*Orderer) {
238248
tempDir, err := os.MkdirTemp(n.RootDir, "updateConfig")
239249
Expect(err).NotTo(HaveOccurred())
240250
updateFile := filepath.Join(tempDir, "update.pb")
241251

242252
ComputeUpdateOrdererConfig(updateFile, n, channel, current, updated, submitter, additionalSigners...)
243253

244-
// session should not return with a zero exit code nor with a success response
245-
sess, err := n.OrdererAdminSession(orderer, submitter, commands.ChannelUpdate{
246-
ChannelID: channel,
247-
Orderer: n.OrdererAddress(orderer, ListenPort),
254+
sess, err := n.OrdererAdminSession(orderer, submitter, commands.SignConfigTx{
248255
File: updateFile,
249256
ClientAuth: n.ClientAuthRequired,
250257
})
251258
Expect(err).NotTo(HaveOccurred())
252-
return sess
259+
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
260+
261+
updateEnvelopeBytes, err := os.ReadFile(updateFile)
262+
Expect(err).NotTo(HaveOccurred())
263+
264+
updateEnvelope := &common.Envelope{}
265+
err = proto.Unmarshal(updateEnvelopeBytes, updateEnvelope)
266+
Expect(err).NotTo(HaveOccurred())
267+
268+
ready := make(chan struct{})
269+
go func() {
270+
defer GinkgoRecover()
271+
UpdateWithStatus(n, orderer, channel, updateEnvelope, http.StatusBadRequest, errStr)
272+
close(ready)
273+
}()
274+
Eventually(ready, n.EventuallyTimeout).Should(BeClosed())
253275
}
254276

255277
func ComputeUpdateOrdererConfig(updateFile string, n *Network, channel string, current, updated *common.Config, submitter *Peer, additionalSigners ...*Orderer) {

integration/raft/cft_test.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"os"
1717
"path"
1818
"path/filepath"
19-
"strings"
2019
"sync"
2120
"syscall"
2221
"time"
@@ -347,6 +346,7 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
347346
Expect(err).NotTo(HaveOccurred())
348347

349348
By("Adding new ordering service node")
349+
Consistently(ordererRunners[0].Err(), 5*time.Second, time.Second).ShouldNot(gbytes.Say("active nodes store"))
350350
addConsenter(network, peer, orderers[0], "testchannel", &etcdraft.Consenter{
351351
ServerTlsCert: ordererCert,
352352
ClientTlsCert: ordererCert,
@@ -738,6 +738,7 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
738738
for _, orderer := range orderers {
739739
ordererConfig := network.ReadOrdererConfig(orderer)
740740
ordererConfig.General.Cluster.TLSHandshakeTimeShift = 5 * time.Minute
741+
ordererConfig.Admin.TLS.TLSHandshakeTimeShift = 5 * time.Minute
741742
network.WriteOrdererConfig(orderer, ordererConfig)
742743
}
743744

@@ -809,6 +810,8 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
809810
for _, orderer := range orderers {
810811
ordererConfig := network.ReadOrdererConfig(orderer)
811812
ordererConfig.General.TLS.TLSHandshakeTimeShift = 5 * time.Minute
813+
ordererConfig.Admin.TLS.TLSHandshakeTimeShift = 5 * time.Minute
814+
ordererConfig.Admin.TLS.Enabled = true
812815
network.WriteOrdererConfig(orderer, ordererConfig)
813816
}
814817

@@ -825,7 +828,8 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
825828

826829
By("submitting config updates to orderers with expired TLS certs to replace the expired certs")
827830
timeShift := 5 * time.Minute
828-
for _, o := range orderers {
831+
ordererRunners := []*ginkgomon.Runner{o1Runner, o2Runner, o3Runner}
832+
for i, o := range orderers {
829833
channelConfig := fetchConfig(network, peer, o, nwo.ClusterPort, "testchannel", timeShift)
830834
c := conftx.New(channelConfig)
831835
err = c.Orderer().RemoveConsenter(consenterChannelConfig(network, o))
@@ -837,7 +841,8 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
837841
Expect(err).NotTo(HaveOccurred())
838842

839843
By("updating the config for " + o.Name)
840-
updateOrdererConfig(network, o, nwo.ClusterPort, "testchannel", timeShift, c.OriginalConfig(), c.UpdatedConfig(), peer)
844+
Consistently(ordererRunners[i].Err(), 5*time.Second, time.Second).ShouldNot(gbytes.Say("active nodes store"))
845+
updateOrdererConfig(network, o, nwo.ClusterPort, "testchannel", timeShift, c.OriginalConfig(), c.UpdatedConfig(), peer, o)
841846
}
842847

843848
By("Killing orderers #5")
@@ -856,6 +861,7 @@ var _ = Describe("EndToEnd Crash Fault Tolerance", func() {
856861
for _, o := range orderers {
857862
ordererConfig := network.ReadOrdererConfig(o)
858863
ordererConfig.General.TLS.TLSHandshakeTimeShift = 0
864+
ordererConfig.Admin.TLS.TLSHandshakeTimeShift = 0
859865
network.WriteOrdererConfig(o, ordererConfig)
860866
}
861867

@@ -1324,23 +1330,20 @@ func updateOrdererConfig(n *nwo.Network, orderer *nwo.Orderer, port nwo.PortName
13241330
currentBlockNumber := currentConfigBlockNumber(n, submitter, orderer, port, channel, tlsHandshakeTimeShift)
13251331
nwo.ComputeUpdateOrdererConfig(updateFile, n, channel, current, updated, submitter, additionalSigners...)
13261332

1327-
Eventually(func() bool {
1328-
sess, err := n.OrdererAdminSession(orderer, submitter, commands.ChannelUpdate{
1329-
ChannelID: channel,
1330-
Orderer: n.OrdererAddress(orderer, port),
1331-
File: updateFile,
1332-
ClientAuth: n.ClientAuthRequired,
1333-
TLSHandshakeTimeShift: tlsHandshakeTimeShift,
1334-
})
1335-
Expect(err).NotTo(HaveOccurred())
1333+
updateEnvelopeBytes, err := os.ReadFile(updateFile)
1334+
Expect(err).NotTo(HaveOccurred())
13361335

1337-
sess.Wait(n.EventuallyTimeout)
1338-
if sess.ExitCode() != 0 {
1339-
return false
1340-
}
1336+
updateEnvelope := &common.Envelope{}
1337+
err = proto.Unmarshal(updateEnvelopeBytes, updateEnvelope)
1338+
Expect(err).NotTo(HaveOccurred())
13411339

1342-
return strings.Contains(string(sess.Err.Contents()), "Successfully submitted channel update")
1343-
}, n.EventuallyTimeout).Should(BeTrue())
1340+
ready := make(chan struct{})
1341+
go func() {
1342+
defer GinkgoRecover()
1343+
nwo.UpdateTimeShift(n, orderer, channel, updateEnvelope, tlsHandshakeTimeShift)
1344+
close(ready)
1345+
}()
1346+
Eventually(ready, n.EventuallyTimeout).Should(BeClosed())
13441347

13451348
ccb := func() uint64 {
13461349
return currentConfigBlockNumber(n, submitter, orderer, port, channel, tlsHandshakeTimeShift)

0 commit comments

Comments
 (0)