Skip to content

Commit 635cd8c

Browse files
[FAB-11897] Enable Type A etcd/raft config updates
This CR Allows Type A config updates while rejecting the type B ones for the etcd/raft consenter. For definition of Type A and Type B config updates please refer to the JIRA. Change-Id: If7351eb28fe66ff7ca31e45206ed044ee2937051 Signed-off-by: Adarsh Saraf <adarshsaraf123@gmail.com>
1 parent 96735d2 commit 635cd8c

File tree

6 files changed

+416
-63
lines changed

6 files changed

+416
-63
lines changed

common/configtx/update.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"github.com/hyperledger/fabric/common/policies"
1313
cb "github.com/hyperledger/fabric/protos/common"
14-
"github.com/hyperledger/fabric/protos/utils"
1514

1615
"github.com/pkg/errors"
1716
)
@@ -202,12 +201,3 @@ func (vi *ValidatorImpl) computeUpdateResult(updatedConfig map[string]comparable
202201
}
203202
return newConfigMap
204203
}
205-
206-
func envelopeToConfigUpdate(configtx *cb.Envelope) (*cb.ConfigUpdateEnvelope, error) {
207-
configUpdateEnv := &cb.ConfigUpdateEnvelope{}
208-
_, err := utils.UnmarshalEnvelopeOfType(configtx, cb.HeaderType_CONFIG_UPDATE, configUpdateEnv)
209-
if err != nil {
210-
return nil, err
211-
}
212-
return configUpdateEnv, nil
213-
}

common/configtx/validator.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/hyperledger/fabric/common/flogging"
1313
"github.com/hyperledger/fabric/common/policies"
1414
cb "github.com/hyperledger/fabric/protos/common"
15+
"github.com/hyperledger/fabric/protos/utils"
1516

1617
"github.com/golang/protobuf/proto"
1718
"github.com/pkg/errors"
@@ -132,7 +133,7 @@ func (vi *ValidatorImpl) ProposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigE
132133
}
133134

134135
func (vi *ValidatorImpl) proposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error) {
135-
configUpdateEnv, err := envelopeToConfigUpdate(configtx)
136+
configUpdateEnv, err := utils.EnvelopeToConfigUpdate(configtx)
136137
if err != nil {
137138
return nil, errors.Errorf("error converting envelope to config update: %s", err)
138139
}
@@ -170,7 +171,7 @@ func (vi *ValidatorImpl) Validate(configEnv *cb.ConfigEnvelope) error {
170171
return errors.Errorf("config currently at sequence %d, cannot validate config at sequence %d", vi.sequence, configEnv.Config.Sequence)
171172
}
172173

173-
configUpdateEnv, err := envelopeToConfigUpdate(configEnv.LastUpdate)
174+
configUpdateEnv, err := utils.EnvelopeToConfigUpdate(configEnv.LastUpdate)
174175
if err != nil {
175176
return err
176177
}

orderer/consensus/etcdraft/chain.go

Lines changed: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/coreos/etcd/raft"
1919
"github.com/coreos/etcd/raft/raftpb"
2020
"github.com/golang/protobuf/proto"
21+
"github.com/hyperledger/fabric/common/configtx"
2122
"github.com/hyperledger/fabric/common/flogging"
2223
"github.com/hyperledger/fabric/orderer/common/cluster"
2324
"github.com/hyperledger/fabric/orderer/consensus"
@@ -129,8 +130,53 @@ func (c *Chain) Order(env *common.Envelope, configSeq uint64) error {
129130

130131
// Configure submits config type transactions for ordering.
131132
func (c *Chain) Configure(env *common.Envelope, configSeq uint64) error {
132-
c.logger.Panicf("Configure not implemented yet")
133-
return nil
133+
if err := c.checkConfigUpdateValidity(env); err != nil {
134+
return err
135+
}
136+
return c.Submit(&orderer.SubmitRequest{LastValidationSeq: configSeq, Content: env}, 0)
137+
}
138+
139+
// validate the config update for being of Type A or Type B as described in the design doc.
140+
func (c *Chain) checkConfigUpdateValidity(ctx *common.Envelope) error {
141+
var err error
142+
payload, err := utils.UnmarshalPayload(ctx.Payload)
143+
if err != nil {
144+
return err
145+
}
146+
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
147+
if err != nil {
148+
return err
149+
}
150+
151+
switch chdr.Type {
152+
case int32(common.HeaderType_ORDERER_TRANSACTION):
153+
return errors.Errorf("channel creation requests not supported yet")
154+
case int32(common.HeaderType_CONFIG):
155+
configEnv, err := configtx.UnmarshalConfigEnvelope(payload.Data)
156+
if err != nil {
157+
return err
158+
}
159+
configUpdateEnv, err := utils.EnvelopeToConfigUpdate(configEnv.LastUpdate)
160+
if err != nil {
161+
return err
162+
}
163+
configUpdate, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
164+
if err != nil {
165+
return err
166+
}
167+
168+
// ignoring the read set for now
169+
// check only if the ConsensusType is updated in the write set
170+
if ordererConfigGroup, ok := configUpdate.WriteSet.Groups["Orderer"]; ok {
171+
if _, ok := ordererConfigGroup.Values["ConsensusType"]; ok {
172+
return errors.Errorf("updates to ConsensusType not supported currently")
173+
}
174+
}
175+
return nil
176+
177+
default:
178+
return errors.Errorf("config transaction has unknown header type")
179+
}
134180
}
135181

136182
// WaitReady is currently a no-op.
@@ -209,29 +255,19 @@ func (c *Chain) serveRequest() {
209255
}
210256

211257
for {
212-
seq := c.support.Sequence()
213258

214259
select {
215260
case msg := <-c.submitC:
216-
if c.isConfig(msg.Content) {
217-
c.logger.Panicf("Processing config envelope is not implemented yet")
218-
}
219-
220-
if msg.LastValidationSeq < seq {
221-
if _, err := c.support.ProcessNormalMsg(msg.Content); err != nil {
222-
c.logger.Warningf("Discarding bad normal message: %s", err)
223-
continue
224-
}
261+
batches, pending, err := c.ordered(msg)
262+
if err != nil {
263+
c.logger.Errorf("Failed to order message: %s", err)
225264
}
226-
227-
batches, _ := c.support.BlockCutter().Ordered(msg.Content)
228-
if len(batches) == 0 {
229-
start()
230-
continue
265+
if pending {
266+
start() // no-op if timer is already started
267+
} else {
268+
stop()
231269
}
232270

233-
stop()
234-
235271
if err := c.commitBatches(batches...); err != nil {
236272
c.logger.Errorf("Failed to commit block: %s", err)
237273
}
@@ -257,6 +293,42 @@ func (c *Chain) serveRequest() {
257293
}
258294
}
259295

296+
// Orders the envelope in the `msg` content. SubmitRequest.
297+
// Returns
298+
// -- batches [][]*common.Envelope; the batches cut,
299+
// -- pending bool; if there are envelopes pending to be ordered,
300+
// -- err error; the error encountered, if any.
301+
// It takes care of config messages as well as the revalidation of messages if the config sequence has advanced.
302+
func (c *Chain) ordered(msg *orderer.SubmitRequest) (batches [][]*common.Envelope, pending bool, err error) {
303+
seq := c.support.Sequence()
304+
305+
if c.isConfig(msg.Content) {
306+
// ConfigMsg
307+
if msg.LastValidationSeq < seq {
308+
msg.Content, _, err = c.support.ProcessConfigMsg(msg.Content)
309+
if err != nil {
310+
return nil, true, errors.Errorf("bad config message: %s", err)
311+
}
312+
}
313+
batch := c.support.BlockCutter().Cut()
314+
batches = [][]*common.Envelope{}
315+
if len(batch) != 0 {
316+
batches = append(batches, batch)
317+
}
318+
batches = append(batches, []*common.Envelope{msg.Content})
319+
return batches, false, nil
320+
}
321+
// it is a normal message
322+
if msg.LastValidationSeq < seq {
323+
if _, err := c.support.ProcessNormalMsg(msg.Content); err != nil {
324+
return nil, true, errors.Errorf("bad normal message: %s", err)
325+
}
326+
}
327+
batches, pending = c.support.BlockCutter().Ordered(msg.Content)
328+
return batches, pending, nil
329+
330+
}
331+
260332
func (c *Chain) commitBatches(batches ...[]*common.Envelope) error {
261333
for _, batch := range batches {
262334
b := c.support.CreateNextBlock(batch)
@@ -268,9 +340,10 @@ func (c *Chain) commitBatches(batches ...[]*common.Envelope) error {
268340
select {
269341
case block := <-c.commitC:
270342
if utils.IsConfigBlock(block) {
271-
c.logger.Panicf("Config block is not supported yet")
343+
c.support.WriteConfigBlock(block, nil)
344+
} else {
345+
c.support.WriteBlock(block, nil)
272346
}
273-
c.support.WriteBlock(block, nil)
274347

275348
case <-c.doneC:
276349
return nil

0 commit comments

Comments
 (0)