From fc0c4e912eed405f4f460b9872ec0436d5194014 Mon Sep 17 00:00:00 2001 From: Artem Barger Date: Thu, 18 Oct 2018 21:10:18 +0300 Subject: [PATCH] [FAB-12477]: add etcd/raft membership message This commit adds new message to hold information about mapping from consenters to theirs ids and to keep track on the next id to be assigned for new coming replica. Moreover update write block path to actually persist information about raft cluster membership mapping. Change-Id: I638b30fc5729a0d02f21a40989deb93e42b09836 Signed-off-by: Artem Barger --- orderer/consensus/etcdraft/chain.go | 58 +++------- orderer/consensus/etcdraft/chain_test.go | 57 ++++++--- orderer/consensus/etcdraft/consenter.go | 44 +++++-- orderer/consensus/etcdraft/util.go | 44 +++++++ protos/orderer/etcdraft/configuration.pb.go | 122 ++++++++++++++------ protos/orderer/etcdraft/configuration.proto | 34 ++++-- 6 files changed, 245 insertions(+), 114 deletions(-) diff --git a/orderer/consensus/etcdraft/chain.go b/orderer/consensus/etcdraft/chain.go index fc79cc1b7b3..5f242cebc0d 100644 --- a/orderer/consensus/etcdraft/chain.go +++ b/orderer/consensus/etcdraft/chain.go @@ -10,7 +10,6 @@ import ( "context" "encoding/pem" "fmt" - "reflect" "sync/atomic" "time" @@ -68,7 +67,7 @@ type Options struct { HeartbeatTick int MaxSizePerMsg uint64 MaxInflightMsgs int - Peers []raft.Peer + RaftMetadata *etcdraft.RaftMetadata } // Chain implements consensus.Chain interface. @@ -148,7 +147,10 @@ func (c *Chain) Start() { return } - c.node = raft.StartNode(config, c.opts.Peers) + raftPeers := RaftPeers(c.opts.RaftMetadata.Consenters) + + c.node = raft.StartNode(config, raftPeers) + close(c.startC) go c.serveRaft() @@ -371,12 +373,13 @@ func (c *Chain) serveRequest() { } func (c *Chain) writeBlock(b *common.Block) { + metadata := utils.MarshalOrPanic(c.opts.RaftMetadata) if utils.IsConfigBlock(b) { - c.support.WriteConfigBlock(b, nil) + c.support.WriteConfigBlock(b, metadata) return } - c.support.WriteBlock(b, nil) + c.support.WriteBlock(b, metadata) } // Orders the envelope in the `msg` content. SubmitRequest. @@ -425,12 +428,7 @@ func (c *Chain) commitBatches(batches ...[]*common.Envelope) error { select { case block := <-c.commitC: - if utils.IsConfigBlock(block) { - c.support.WriteConfigBlock(block, nil) - } else { - c.support.WriteBlock(block, nil) - } - + c.writeBlock(block) case <-c.resignC: return errors.Errorf("aborted block committing: lost leadership") @@ -555,7 +553,7 @@ func (c *Chain) isConfig(env *common.Envelope) bool { } func (c *Chain) configureComm() error { - nodes, err := c.nodeConfigFromMetadata() + nodes, err := c.remotePeers() if err != nil { return err } @@ -564,15 +562,9 @@ func (c *Chain) configureComm() error { return nil } -func (c *Chain) nodeConfigFromMetadata() ([]cluster.RemoteNode, error) { +func (c *Chain) remotePeers() ([]cluster.RemoteNode, error) { var nodes []cluster.RemoteNode - m := &etcdraft.Metadata{} - if err := proto.Unmarshal(c.support.SharedConfig().ConsensusMetadata(), m); err != nil { - return nil, errors.Wrap(err, "failed to extract consensus metadata") - } - - for id, consenter := range m.Consenters { - raftID := uint64(id + 1) + for raftID, consenter := range c.opts.RaftMetadata.Consenters { // No need to know yourself if raftID == c.raftID { continue @@ -615,33 +607,9 @@ func (c *Chain) checkConsentersSet(configValue *common.ConfigValue) error { return errors.Wrap(err, "failed to unmarshal updated (new) etcdraft metadata configuration") } - currentMetadata := &etcdraft.Metadata{} - if err := proto.Unmarshal(c.support.SharedConfig().ConsensusMetadata(), currentMetadata); err != nil { - return errors.Wrap(err, "failed to unmarshal current etcdraft metadata configuration") - } - - if !c.consentersSetEqual(currentMetadata.Consenters, updatedMetadata.Consenters) { + if !ConsentersChanged(c.opts.RaftMetadata.Consenters, updatedMetadata.Consenters) { return errors.New("update of consenters set is not supported yet") } return nil } - -func (c *Chain) consentersSetEqual(c1 []*etcdraft.Consenter, c2 []*etcdraft.Consenter) bool { - if len(c1) != len(c2) { - return false - } - - consentersSet1 := c.consentersToMap(c1) - consentersSet2 := c.consentersToMap(c2) - - return reflect.DeepEqual(consentersSet1, consentersSet2) -} - -func (c *Chain) consentersToMap(c1 []*etcdraft.Consenter) map[string]*etcdraft.Consenter { - set := map[string]*etcdraft.Consenter{} - for _, c := range c1 { - set[string(c.ClientTlsCert)] = c - } - return set -} diff --git a/orderer/consensus/etcdraft/chain_test.go b/orderer/consensus/etcdraft/chain_test.go index e7026926184..ba5899e0862 100644 --- a/orderer/consensus/etcdraft/chain_test.go +++ b/orderer/consensus/etcdraft/chain_test.go @@ -79,6 +79,27 @@ var _ = Describe("Chain", func() { clock = fakeclock.NewFakeClock(time.Now()) storage = raft.NewMemoryStorage() observeC = make(chan uint64, 1) + + support = &consensusmocks.FakeConsenterSupport{} + support.ChainIDReturns(channelID) + consenterMetadata = createMetadata(1, tlsCA) + support.SharedConfigReturns(&mockconfig.Orderer{ + BatchTimeoutVal: time.Hour, + ConsensusMetadataVal: marshalOrPanic(consenterMetadata), + }) + cutter = mockblockcutter.NewReceiver() + support.BlockCutterReturns(cutter) + + membership := &raftprotos.RaftMetadata{ + Consenters: map[uint64]*raftprotos.Consenter{}, + NextConsenterID: 1, + } + + for _, c := range consenterMetadata.Consenters { + membership.Consenters[membership.NextConsenterID] = c + membership.NextConsenterID++ + } + opts = etcdraft.Options{ RaftID: 1, Clock: clock, @@ -87,19 +108,10 @@ var _ = Describe("Chain", func() { HeartbeatTick: HEARTBEAT_TICK, MaxSizePerMsg: 1024 * 1024, MaxInflightMsgs: 256, - Peers: []raft.Peer{{ID: 1}}, + RaftMetadata: membership, Logger: logger, Storage: storage, } - support = &consensusmocks.FakeConsenterSupport{} - support.ChainIDReturns(channelID) - consenterMetadata = createMetadata(3, tlsCA) - support.SharedConfigReturns(&mockconfig.Orderer{ - BatchTimeoutVal: time.Hour, - ConsensusMetadataVal: marshalOrPanic(consenterMetadata), - }) - cutter = mockblockcutter.NewReceiver() - support.BlockCutterReturns(cutter) var err error chain, err = etcdraft.NewChain(support, opts, configurator, nil, observeC) @@ -487,7 +499,7 @@ var _ = Describe("Chain", func() { Context("when a type B config update comes", func() { - Context("for existing channel", func() { + Context("updating protocol values", func() { // use to prepare the Orderer Values BeforeEach(func() { values := map[string]*common.ConfigValue{ @@ -842,11 +854,25 @@ func newChain(timeout time.Duration, channel string, id uint64, all []uint64) *c rpc := &mocks.FakeRPC{} clock := fakeclock.NewFakeClock(time.Now()) storage := raft.NewMemoryStorage() + tlsCA, _ := tlsgen.NewCA() - peers := []raft.Peer{} - for _, i := range all { - peers = append(peers, raft.Peer{ID: i}) + membership := &raftprotos.RaftMetadata{ + Consenters: map[uint64]*raftprotos.Consenter{}, + NextConsenterID: 1, + } + + for _, raftID := range all { + membership.Consenters[uint64(raftID)] = &raftprotos.Consenter{ + Host: "localhost", + Port: 7051, + ClientTlsCert: clientTLSCert(tlsCA), + ServerTlsCert: serverTLSCert(tlsCA), + } + if uint64(raftID) > membership.NextConsenterID { + membership.NextConsenterID = uint64(raftID) + } } + membership.NextConsenterID++ opts := etcdraft.Options{ RaftID: uint64(id), @@ -856,7 +882,7 @@ func newChain(timeout time.Duration, channel string, id uint64, all []uint64) *c HeartbeatTick: HEARTBEAT_TICK, MaxSizePerMsg: 1024 * 1024, MaxInflightMsgs: 256, - Peers: peers, + RaftMetadata: membership, Logger: flogging.NewFabricLogger(zap.NewNop()), Storage: storage, } @@ -965,6 +991,7 @@ func (n *network) start(ids ...uint64) { wg.Add(len(nodes)) for _, i := range nodes { go func(id uint64) { + defer GinkgoRecover() n.chains[id].Start() n.chains[id].unstarted = nil diff --git a/orderer/consensus/etcdraft/consenter.go b/orderer/consensus/etcdraft/consenter.go index cf1e92b9050..4d3f282ae87 100644 --- a/orderer/consensus/etcdraft/consenter.go +++ b/orderer/consensus/etcdraft/consenter.go @@ -75,12 +75,12 @@ func (c *Consenter) ReceiverByChain(channelID string) MessageReceiver { return nil } -func (c *Consenter) detectSelfID(m *etcdraft.Metadata) (uint64, error) { +func (c *Consenter) detectSelfID(consenters map[uint64]*etcdraft.Consenter) (uint64, error) { var serverCertificates []string - for i, cst := range m.Consenters { + for nodeID, cst := range consenters { serverCertificates = append(serverCertificates, string(cst.ServerTlsCert)) if bytes.Equal(c.Cert, cst.ServerTlsCert) { - return uint64(i + 1), nil + return nodeID, nil } } @@ -99,16 +99,19 @@ func (c *Consenter) HandleChain(support consensus.ConsenterSupport, metadata *co return nil, errors.New("etcdraft options have not been provided") } - id, err := c.detectSelfID(m) + // determine raft replica set mapping for each node to its id + // for newly started chain we need to read and initialize raft + // metadata by creating mapping between conseter and its id. + // In case chain has been restarted we restore raft metadata + // information from the recently committed block meta data + // field. + raftMetadata, err := raftMetadata(metadata, m) + + id, err := c.detectSelfID(raftMetadata.Consenters) if err != nil { return nil, errors.WithStack(err) } - peers := make([]raft.Peer, len(m.Consenters)) - for i := range peers { - peers[i].ID = uint64(i + 1) - } - opts := Options{ RaftID: id, Clock: clock.NewClock(), @@ -121,13 +124,34 @@ func (c *Consenter) HandleChain(support consensus.ConsenterSupport, metadata *co MaxInflightMsgs: int(m.Options.MaxInflightMsgs), MaxSizePerMsg: m.Options.MaxSizePerMsg, - Peers: peers, + RaftMetadata: raftMetadata, } rpc := &cluster.RPC{Channel: support.ChainID(), Comm: c.Communication} return NewChain(support, opts, c.Communication, rpc, nil) } +func raftMetadata(blockMetadata *common.Metadata, configMetadata *etcdraft.Metadata) (*etcdraft.RaftMetadata, error) { + membership := &etcdraft.RaftMetadata{ + Consenters: map[uint64]*etcdraft.Consenter{}, + NextConsenterID: 1, + } + if blockMetadata != nil && len(blockMetadata.Value) != 0 { // we have consenters mapping from block + if err := proto.Unmarshal(blockMetadata.Value, membership); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal block's metadata") + } + return membership, nil + } + + // need to read consenters from the configuration + for _, consenter := range configMetadata.Consenters { + membership.Consenters[membership.NextConsenterID] = consenter + membership.NextConsenterID++ + } + + return membership, nil +} + func New(clusterDialer *cluster.PredicateDialer, conf *localconfig.TopLevel, srvConf comm.ServerConfig, srv *comm.GRPCServer, r *multichannel.Registrar) *Consenter { logger := flogging.MustGetLogger("orderer/consensus/etcdraft") diff --git a/orderer/consensus/etcdraft/util.go b/orderer/consensus/etcdraft/util.go index 56980685292..04ebb710e3c 100644 --- a/orderer/consensus/etcdraft/util.go +++ b/orderer/consensus/etcdraft/util.go @@ -8,12 +8,15 @@ package etcdraft import ( "encoding/pem" + "reflect" + "github.com/coreos/etcd/raft" "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/orderer/common/cluster" "github.com/hyperledger/fabric/orderer/common/localconfig" "github.com/hyperledger/fabric/orderer/consensus" "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/orderer/etcdraft" "github.com/hyperledger/fabric/protos/utils" "github.com/pkg/errors" ) @@ -111,3 +114,44 @@ func newBlockPuller(support consensus.ConsenterSupport, Dialer: stdDialer, }, nil } + +// RaftPeers maps consenters to slice of raft.Peer +func RaftPeers(consenters map[uint64]*etcdraft.Consenter) []raft.Peer { + var peers []raft.Peer + + for raftID := range consenters { + peers = append(peers, raft.Peer{ID: raftID}) + } + return peers +} + +// ConsentersToMap maps consenters into set where key is client TLS certificate +func ConsentersToMap(consenters []*etcdraft.Consenter) map[string]struct{} { + set := map[string]struct{}{} + for _, c := range consenters { + set[string(c.ClientTlsCert)] = struct{}{} + } + return set +} + +// MembershipByCert convert consenters map into set encapsulated by map +// where key is client TLS certificate +func MembershipByCert(consenters map[uint64]*etcdraft.Consenter) map[string]struct{} { + set := map[string]struct{}{} + for _, c := range consenters { + set[string(c.ClientTlsCert)] = struct{}{} + } + return set +} + +// ConsentersChanged cheks whenever slice of new consenters contains changes for consenters mapping +func ConsentersChanged(oldConsenters map[uint64]*etcdraft.Consenter, newConsenters []*etcdraft.Consenter) bool { + if len(oldConsenters) != len(newConsenters) { + return false + } + + consentersSet1 := MembershipByCert(oldConsenters) + consentersSet2 := ConsentersToMap(newConsenters) + + return reflect.DeepEqual(consentersSet1, consentersSet2) +} diff --git a/protos/orderer/etcdraft/configuration.pb.go b/protos/orderer/etcdraft/configuration.pb.go index 1400fade353..6c6354a69c8 100644 --- a/protos/orderer/etcdraft/configuration.pb.go +++ b/protos/orderer/etcdraft/configuration.pb.go @@ -32,7 +32,7 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_configuration_65c7ed1a646136e8, []int{0} + return fileDescriptor_configuration_868d446aa2970746, []int{0} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Metadata.Unmarshal(m, b) @@ -81,7 +81,7 @@ func (m *Consenter) Reset() { *m = Consenter{} } func (m *Consenter) String() string { return proto.CompactTextString(m) } func (*Consenter) ProtoMessage() {} func (*Consenter) Descriptor() ([]byte, []int) { - return fileDescriptor_configuration_65c7ed1a646136e8, []int{1} + return fileDescriptor_configuration_868d446aa2970746, []int{1} } func (m *Consenter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Consenter.Unmarshal(m, b) @@ -146,7 +146,7 @@ func (m *Options) Reset() { *m = Options{} } func (m *Options) String() string { return proto.CompactTextString(m) } func (*Options) ProtoMessage() {} func (*Options) Descriptor() ([]byte, []int) { - return fileDescriptor_configuration_65c7ed1a646136e8, []int{2} + return fileDescriptor_configuration_868d446aa2970746, []int{2} } func (m *Options) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Options.Unmarshal(m, b) @@ -201,41 +201,97 @@ func (m *Options) GetMaxSizePerMsg() uint64 { return 0 } +// Maps of the Raft consenters membership to +// cluster node ids to be stored in block metadata. +// Keeps track on conseters ids and the next id +type RaftMetadata struct { + Consenters map[uint64]*Consenter `protobuf:"bytes,1,rep,name=consenters,proto3" json:"consenters,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + NextConsenterID uint64 `protobuf:"varint,2,opt,name=nextConsenterID,proto3" json:"nextConsenterID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RaftMetadata) Reset() { *m = RaftMetadata{} } +func (m *RaftMetadata) String() string { return proto.CompactTextString(m) } +func (*RaftMetadata) ProtoMessage() {} +func (*RaftMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_configuration_868d446aa2970746, []int{3} +} +func (m *RaftMetadata) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RaftMetadata.Unmarshal(m, b) +} +func (m *RaftMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RaftMetadata.Marshal(b, m, deterministic) +} +func (dst *RaftMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_RaftMetadata.Merge(dst, src) +} +func (m *RaftMetadata) XXX_Size() int { + return xxx_messageInfo_RaftMetadata.Size(m) +} +func (m *RaftMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_RaftMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_RaftMetadata proto.InternalMessageInfo + +func (m *RaftMetadata) GetConsenters() map[uint64]*Consenter { + if m != nil { + return m.Consenters + } + return nil +} + +func (m *RaftMetadata) GetNextConsenterID() uint64 { + if m != nil { + return m.NextConsenterID + } + return 0 +} + func init() { proto.RegisterType((*Metadata)(nil), "etcdraft.Metadata") proto.RegisterType((*Consenter)(nil), "etcdraft.Consenter") proto.RegisterType((*Options)(nil), "etcdraft.Options") + proto.RegisterType((*RaftMetadata)(nil), "etcdraft.RaftMetadata") + proto.RegisterMapType((map[uint64]*Consenter)(nil), "etcdraft.RaftMetadata.ConsentersEntry") } func init() { - proto.RegisterFile("orderer/etcdraft/configuration.proto", fileDescriptor_configuration_65c7ed1a646136e8) -} - -var fileDescriptor_configuration_65c7ed1a646136e8 = []byte{ - // 387 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xcd, 0x6e, 0xdb, 0x30, - 0x10, 0x84, 0xa1, 0xda, 0x6d, 0x12, 0xc6, 0x6a, 0x1a, 0xf6, 0xa2, 0xa3, 0xe1, 0xfe, 0x19, 0x2d, - 0x40, 0x01, 0x09, 0xfa, 0x02, 0xcd, 0x29, 0x07, 0xa3, 0x85, 0x9a, 0x53, 0x2f, 0x02, 0x4d, 0xaf, - 0x28, 0x22, 0x94, 0x28, 0x2c, 0x37, 0x81, 0x9b, 0x6b, 0x1f, 0xb0, 0xaf, 0x54, 0x90, 0x94, 0x1c, - 0xa3, 0xb7, 0xc5, 0xcc, 0x37, 0x8b, 0x01, 0x76, 0xd9, 0x7b, 0x87, 0x3b, 0x40, 0xc0, 0x12, 0x48, - 0xed, 0x50, 0x36, 0x54, 0x2a, 0xd7, 0x37, 0x46, 0x3f, 0xa0, 0x24, 0xe3, 0x7a, 0x31, 0xa0, 0x23, - 0xc7, 0x4f, 0x27, 0x77, 0x65, 0xd9, 0xe9, 0x06, 0x48, 0xee, 0x24, 0x49, 0x7e, 0xcd, 0x98, 0x72, - 0xbd, 0x87, 0x9e, 0x00, 0x7d, 0x91, 0x2d, 0x67, 0xeb, 0xf3, 0xab, 0xb7, 0x62, 0x42, 0xc5, 0xcd, - 0xe4, 0x55, 0x47, 0x18, 0xff, 0xc2, 0x4e, 0xdc, 0x10, 0x56, 0xfb, 0xe2, 0xc5, 0x32, 0x5b, 0x9f, - 0x5f, 0x5d, 0x3e, 0x27, 0xbe, 0x27, 0xa3, 0x9a, 0x88, 0xd5, 0x9f, 0x8c, 0x9d, 0x1d, 0xd6, 0x70, - 0xce, 0xe6, 0xad, 0xf3, 0x54, 0x64, 0xcb, 0x6c, 0x7d, 0x56, 0xc5, 0x39, 0x68, 0x83, 0x43, 0x8a, - 0xbb, 0xf2, 0x2a, 0xce, 0xfc, 0x23, 0xbb, 0x50, 0xd6, 0x40, 0x4f, 0x35, 0x59, 0x5f, 0x2b, 0x40, - 0x2a, 0x66, 0xcb, 0x6c, 0xbd, 0xa8, 0xf2, 0x24, 0xdf, 0x59, 0x7f, 0x03, 0x89, 0xf3, 0x80, 0x8f, - 0x80, 0xcf, 0xdc, 0x3c, 0x71, 0x49, 0x1e, 0xb9, 0xd5, 0xdf, 0x8c, 0x9d, 0x8c, 0xd5, 0xf8, 0x3b, - 0x96, 0x93, 0x51, 0xf7, 0xb5, 0x09, 0x8d, 0x1e, 0xa5, 0x8d, 0x65, 0xe6, 0xd5, 0x22, 0x88, 0xb7, - 0xa3, 0x16, 0x20, 0xb0, 0xa0, 0x42, 0xa2, 0x0e, 0xc6, 0xd8, 0x6e, 0x31, 0x89, 0x77, 0x46, 0xdd, - 0xf3, 0x0f, 0xec, 0x75, 0x0b, 0x12, 0x69, 0x0b, 0x92, 0x12, 0x35, 0x8b, 0x54, 0x7e, 0x50, 0x23, - 0xf6, 0x99, 0x5d, 0x76, 0x72, 0x5f, 0x9b, 0xbe, 0xb1, 0x46, 0xb7, 0x54, 0x77, 0x5e, 0xfb, 0x58, - 0x33, 0xaf, 0x2e, 0x3a, 0xb9, 0xbf, 0x1d, 0xf5, 0x8d, 0xd7, 0x9e, 0x7f, 0x62, 0x6f, 0x02, 0xeb, - 0xcd, 0x13, 0xd4, 0x03, 0x60, 0x60, 0x8b, 0x97, 0xb1, 0x5f, 0xde, 0xc9, 0xfd, 0x4f, 0xf3, 0x04, - 0x3f, 0x00, 0x37, 0x5e, 0x7f, 0xd3, 0x4c, 0x38, 0xd4, 0xa2, 0xfd, 0x3d, 0x00, 0x5a, 0xd8, 0x69, - 0x40, 0xd1, 0xc8, 0x2d, 0x1a, 0x95, 0xee, 0xed, 0xc5, 0xf8, 0x15, 0x87, 0xd3, 0xfc, 0xfa, 0xaa, - 0x0d, 0xb5, 0x0f, 0x5b, 0xa1, 0x5c, 0x57, 0x1e, 0xc5, 0xca, 0x14, 0x2b, 0x53, 0xac, 0xfc, 0xff, - 0x99, 0xb6, 0xaf, 0xa2, 0x71, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xd4, 0x3d, 0xca, 0x67, - 0x02, 0x00, 0x00, + proto.RegisterFile("orderer/etcdraft/configuration.proto", fileDescriptor_configuration_868d446aa2970746) +} + +var fileDescriptor_configuration_868d446aa2970746 = []byte{ + // 469 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0x41, 0x6f, 0xd3, 0x4e, + 0x10, 0xc5, 0xe5, 0x26, 0xfd, 0xb7, 0xdd, 0xc6, 0xff, 0xb4, 0xcb, 0x25, 0xe2, 0x14, 0x05, 0x28, + 0x01, 0x24, 0x5b, 0x6a, 0x85, 0x84, 0x38, 0x52, 0x40, 0xca, 0x21, 0x02, 0x2d, 0x3d, 0x71, 0xb1, + 0x36, 0x9b, 0xb1, 0xbd, 0x8a, 0xed, 0xb5, 0x76, 0x27, 0x51, 0xd2, 0x2b, 0x1f, 0x90, 0x0b, 0x1f, + 0x08, 0xed, 0xae, 0xed, 0x84, 0xa8, 0xb7, 0xd1, 0x9b, 0xdf, 0x8c, 0x9e, 0xfd, 0x66, 0xc9, 0x4b, + 0xa5, 0x97, 0xa0, 0x41, 0xc7, 0x80, 0x62, 0xa9, 0x79, 0x8a, 0xb1, 0x50, 0x55, 0x2a, 0xb3, 0xb5, + 0xe6, 0x28, 0x55, 0x15, 0xd5, 0x5a, 0xa1, 0xa2, 0xe7, 0x6d, 0x77, 0x52, 0x90, 0xf3, 0x39, 0x20, + 0x5f, 0x72, 0xe4, 0xf4, 0x8e, 0x10, 0xa1, 0x2a, 0x03, 0x15, 0x82, 0x36, 0xa3, 0x60, 0xdc, 0x9b, + 0x5e, 0xde, 0x3e, 0x8b, 0x5a, 0x34, 0xba, 0x6f, 0x7b, 0xec, 0x00, 0xa3, 0xef, 0xc8, 0x99, 0xaa, + 0xed, 0x6a, 0x33, 0x3a, 0x19, 0x07, 0xd3, 0xcb, 0xdb, 0xeb, 0xfd, 0xc4, 0x37, 0xdf, 0x60, 0x2d, + 0x31, 0xf9, 0x15, 0x90, 0x8b, 0x6e, 0x0d, 0xa5, 0xa4, 0x9f, 0x2b, 0x83, 0xa3, 0x60, 0x1c, 0x4c, + 0x2f, 0x98, 0xab, 0xad, 0x56, 0x2b, 0x8d, 0x6e, 0x57, 0xc8, 0x5c, 0x4d, 0x6f, 0xc8, 0x50, 0x14, + 0x12, 0x2a, 0x4c, 0xb0, 0x30, 0x89, 0x00, 0x8d, 0xa3, 0xde, 0x38, 0x98, 0x0e, 0x58, 0xe8, 0xe5, + 0x87, 0xc2, 0xdc, 0x83, 0xe7, 0x0c, 0xe8, 0x0d, 0xe8, 0x3d, 0xd7, 0xf7, 0x9c, 0x97, 0x1b, 0x6e, + 0xf2, 0x3b, 0x20, 0x67, 0x8d, 0x35, 0xfa, 0x82, 0x84, 0x28, 0xc5, 0x2a, 0x91, 0xd6, 0xd1, 0x86, + 0x17, 0xce, 0x4c, 0x9f, 0x0d, 0xac, 0x38, 0x6b, 0x34, 0x0b, 0x41, 0x01, 0xc2, 0x4e, 0x24, 0xb6, + 0xd1, 0xb8, 0x1b, 0xb4, 0xe2, 0x83, 0x14, 0x2b, 0xfa, 0x8a, 0xfc, 0x9f, 0x03, 0xd7, 0xb8, 0x00, + 0x8e, 0x9e, 0xea, 0x39, 0x2a, 0xec, 0x54, 0x87, 0xbd, 0x25, 0xd7, 0x25, 0xdf, 0x26, 0xb2, 0x4a, + 0x0b, 0x99, 0xe5, 0x98, 0x94, 0x26, 0x33, 0xce, 0x66, 0xc8, 0x86, 0x25, 0xdf, 0xce, 0x1a, 0x7d, + 0x6e, 0x32, 0x43, 0x5f, 0x93, 0x2b, 0xcb, 0x1a, 0xf9, 0x08, 0x49, 0x0d, 0xda, 0xb2, 0xa3, 0x53, + 0xe7, 0x2f, 0x2c, 0xf9, 0xf6, 0x87, 0x7c, 0x84, 0xef, 0xa0, 0xe7, 0x26, 0x9b, 0xfc, 0x09, 0xc8, + 0x80, 0xf1, 0x14, 0xbb, 0x28, 0xbf, 0x3e, 0x11, 0xe5, 0xcd, 0x3e, 0x98, 0x43, 0x76, 0x9f, 0xab, + 0xf9, 0x52, 0xa1, 0xde, 0xfd, 0x93, 0xee, 0x94, 0x0c, 0x2b, 0xd8, 0x62, 0x87, 0xcc, 0x3e, 0xbb, + 0x6f, 0xef, 0xb3, 0x63, 0xf9, 0x39, 0x23, 0xc3, 0xa3, 0x45, 0xf4, 0x8a, 0xf4, 0x56, 0xb0, 0x6b, + 0xfe, 0xa8, 0x2d, 0xe9, 0x1b, 0x72, 0xba, 0xe1, 0xc5, 0x1a, 0x9a, 0x53, 0x79, 0xf2, 0xb8, 0x3c, + 0xf1, 0xf1, 0xe4, 0x43, 0xf0, 0x29, 0x23, 0x91, 0xd2, 0x59, 0x94, 0xef, 0x6a, 0xd0, 0x05, 0x2c, + 0x33, 0xd0, 0x51, 0xca, 0x17, 0x5a, 0x0a, 0x7f, 0xc6, 0x26, 0x6a, 0x8e, 0xbd, 0x5b, 0xf3, 0xf3, + 0x7d, 0x26, 0x31, 0x5f, 0x2f, 0x22, 0xa1, 0xca, 0xf8, 0x60, 0x2c, 0xf6, 0x63, 0xb1, 0x1f, 0x8b, + 0x8f, 0xdf, 0xc8, 0xe2, 0x3f, 0xd7, 0xb8, 0xfb, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xe5, 0x95, + 0x3a, 0x3e, 0x03, 0x00, 0x00, } diff --git a/protos/orderer/etcdraft/configuration.proto b/protos/orderer/etcdraft/configuration.proto index 5a00156f8a3..cfdb2745813 100644 --- a/protos/orderer/etcdraft/configuration.proto +++ b/protos/orderer/etcdraft/configuration.proto @@ -14,24 +14,36 @@ package etcdraft; // Metadata is serialized and set as the value of ConsensusType.Metadata in // a channel configuration when the ConsensusType.Type is set "etcdraft". message Metadata { - repeated Consenter consenters = 1; - Options options = 2; + repeated Consenter consenters = 1; + Options options = 2; } // Consenter represents a consenting node (i.e. replica). message Consenter { - string host = 1; - uint32 port = 2; - bytes client_tls_cert = 3; - bytes server_tls_cert = 4; + string host = 1; + uint32 port = 2; + bytes client_tls_cert = 3; + bytes server_tls_cert = 4; } // Options to be specified for all the etcd/raft nodes. These can be modified on a // per-channel basis. message Options { - uint64 tick_interval = 1; // specified in miliseconds - uint32 election_tick = 2; - uint32 heartbeat_tick = 3; - uint32 max_inflight_msgs = 4; - uint64 max_size_per_msg = 5; + uint64 tick_interval = 1; // specified in miliseconds + uint32 election_tick = 2; + uint32 heartbeat_tick = 3; + uint32 max_inflight_msgs = 4; + uint64 max_size_per_msg = 5; +} + +// RaftMetadata stores data used by the Raft OSNs when +// coordinating with each other, to be serialized into +// block meta dta field and used after failres and restarts +message RaftMetadata { + // Maintains a mapping between the cluster's OSNs + // and their Raft IDs. + map consenters = 1; + // Carries the Raft ID value that will be assigned + // to the next OSN that will join this cluster. + uint64 nextConsenterID = 2; }