From 3f92a9f58af33a2cdd59eb47d58cf7b52e45c2c9 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Wed, 11 Oct 2023 17:30:32 +0200 Subject: [PATCH 1/6] Add support for ConsensusTypeBFT in the orderer.go Signed-off-by: David VIEJO --- configtx/orderer.go | 92 +++++++++++++++++++++++++++++++++++++ configtx/orderer/orderer.go | 3 ++ 2 files changed, 95 insertions(+) diff --git a/configtx/orderer.go b/configtx/orderer.go index 650e91e..885e907 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -16,10 +16,14 @@ import ( "time" "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-config/configtx/internal/policydsl" "github.com/hyperledger/fabric-config/configtx/orderer" + "github.com/hyperledger/fabric-protos-go/common" cb "github.com/hyperledger/fabric-protos-go/common" + mspa "github.com/hyperledger/fabric-protos-go/msp" ob "github.com/hyperledger/fabric-protos-go/orderer" eb "github.com/hyperledger/fabric-protos-go/orderer/etcdraft" + sb "github.com/hyperledger/fabric-protos-go/orderer/smartbft" ) const ( @@ -38,6 +42,9 @@ type Orderer struct { Kafka orderer.Kafka EtcdRaft orderer.EtcdRaft Organizations []Organization + + SmartBFT *sb.Options + ConsenterMapping []common.Consenter // MaxChannels is the maximum count of channels an orderer supports. MaxChannels uint64 // Capabilities is a map of the capabilities the orderer supports. @@ -821,6 +828,36 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { if consensusMetadata, err = marshalEtcdRaftMetadata(o.EtcdRaft); err != nil { return fmt.Errorf("marshaling etcdraft metadata for orderer type '%s': %v", orderer.ConsensusTypeEtcdRaft, err) } + case orderer.ConsensusTypeBFT: + consenterMapping := []*cb.Consenter{} + for _, consenter := range o.ConsenterMapping { + consenterMapping = append(consenterMapping, &cb.Consenter{ + Id: consenter.Id, + Host: consenter.Host, + Port: consenter.Port, + MspId: consenter.MspId, + Identity: consenter.Identity, + ClientTlsCert: consenter.ClientTlsCert, + ServerTlsCert: consenter.ServerTlsCert, + }) + } + consentersProto, err := proto.Marshal(&cb.Orderers{ + ConsenterMapping: consenterMapping, + }) + if err != nil { + return fmt.Errorf("marshaling consenters for orderer type '%s': %v", orderer.ConsensusTypeBFT, err) + } + + ordererGroup.Values["Orderers"] = &cb.ConfigValue{ + Value: consentersProto, + ModPolicy: "Admins", + } + // addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey) + if consensusMetadata, err = MarshalBFTOptions(o.SmartBFT); err != nil { + return fmt.Errorf("consenter options read failed with error %s for orderer type %s", err, orderer.ConsensusTypeBFT) + } + // Overwrite policy manually by computing it from the consenters + EncodeBFTBlockVerificationPolicy(o.ConsenterMapping, ordererGroup) default: return fmt.Errorf("unknown orderer type '%s'", o.OrdererType) } @@ -838,6 +875,15 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { return nil } +// MarshalBFTOptions serializes smartbft options. +func MarshalBFTOptions(op *sb.Options) ([]byte, error) { + if copyMd, ok := proto.Clone(op).(*sb.Options); ok { + return proto.Marshal(copyMd) + } else { + return nil, errors.New("consenter options type mismatch") + } +} + // setOrdererPolicies adds *cb.ConfigPolicies to the passed Orderer *cb.ConfigGroup's Policies map. // It checks that the BlockValidation policy is defined alongside the standard policy checks. func setOrdererPolicies(cg *cb.ConfigGroup, policyMap map[string]Policy, modPolicy string) error { @@ -1060,3 +1106,49 @@ func blockDataHashingStructureValue() *standardConfigValue { }, } } + +func EncodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordererGroup *cb.ConfigGroup) error { + n := len(consenterProtos) + f := (n - 1) / 3 + + var identities []*mspa.MSPPrincipal + var pols []*cb.SignaturePolicy + for i, consenter := range consenterProtos { + pols = append(pols, &cb.SignaturePolicy{ + Type: &cb.SignaturePolicy_SignedBy{ + SignedBy: int32(i), + }, + }) + principalBytes, err := proto.Marshal(&mspa.SerializedIdentity{Mspid: consenter.MspId, IdBytes: consenter.Identity}) + if err != nil { + return err + } + identities = append(identities, &mspa.MSPPrincipal{ + PrincipalClassification: mspa.MSPPrincipal_IDENTITY, + Principal: principalBytes, + }) + } + + quorumSize := ComputeBFTQuorum(n, f) + sp := &cb.SignaturePolicyEnvelope{ + Rule: policydsl.NOutOf(int32(quorumSize), pols), + Identities: identities, + } + policyValue, err := proto.Marshal(sp) + if err != nil { + return err + } + ordererGroup.Policies[BlockValidationPolicyKey] = &cb.ConfigPolicy{ + // Inherit modification policy + ModPolicy: ordererGroup.Policies[BlockValidationPolicyKey].ModPolicy, + Policy: &cb.Policy{ + Type: int32(cb.Policy_SIGNATURE), + Value: policyValue, + }, + } + return nil +} + +func ComputeBFTQuorum(totalNodes, faultyNodes int) int { + return int(math.Ceil(float64(totalNodes+faultyNodes+1) / 2)) +} diff --git a/configtx/orderer/orderer.go b/configtx/orderer/orderer.go index 5ece74c..252c3db 100644 --- a/configtx/orderer/orderer.go +++ b/configtx/orderer/orderer.go @@ -28,6 +28,9 @@ const ( // ConsensusTypeEtcdRaft identifies the Raft-based consensus implementation. ConsensusTypeEtcdRaft = "etcdraft" + // ConsensusTypeBFT identifies the SmartBFT-based consensus implementation. + ConsensusTypeBFT = "BFT" + // KafkaBrokersKey is the common.ConfigValue type key name for the KafkaBrokers message. // Deprecated: the kafka consensus type is no longer supported KafkaBrokersKey = "KafkaBrokers" From 023c0b6bf07b27ad002118df5b8a7d12ffa656db Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Wed, 11 Oct 2023 17:42:51 +0200 Subject: [PATCH 2/6] fix lint errors Signed-off-by: David VIEJO --- configtx/orderer.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/configtx/orderer.go b/configtx/orderer.go index 885e907..a5c3333 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -857,7 +857,7 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { return fmt.Errorf("consenter options read failed with error %s for orderer type %s", err, orderer.ConsensusTypeBFT) } // Overwrite policy manually by computing it from the consenters - EncodeBFTBlockVerificationPolicy(o.ConsenterMapping, ordererGroup) + encodeBFTBlockVerificationPolicy(o.ConsenterMapping, ordererGroup) default: return fmt.Errorf("unknown orderer type '%s'", o.OrdererType) } @@ -879,9 +879,8 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { func MarshalBFTOptions(op *sb.Options) ([]byte, error) { if copyMd, ok := proto.Clone(op).(*sb.Options); ok { return proto.Marshal(copyMd) - } else { - return nil, errors.New("consenter options type mismatch") } + return nil, errors.New("consenter options type mismatch") } // setOrdererPolicies adds *cb.ConfigPolicies to the passed Orderer *cb.ConfigGroup's Policies map. @@ -1107,7 +1106,7 @@ func blockDataHashingStructureValue() *standardConfigValue { } } -func EncodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordererGroup *cb.ConfigGroup) error { +func encodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordererGroup *cb.ConfigGroup) error { n := len(consenterProtos) f := (n - 1) / 3 @@ -1129,7 +1128,7 @@ func EncodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordere }) } - quorumSize := ComputeBFTQuorum(n, f) + quorumSize := computeBFTQuorum(n, f) sp := &cb.SignaturePolicyEnvelope{ Rule: policydsl.NOutOf(int32(quorumSize), pols), Identities: identities, @@ -1149,6 +1148,6 @@ func EncodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordere return nil } -func ComputeBFTQuorum(totalNodes, faultyNodes int) int { +func computeBFTQuorum(totalNodes, faultyNodes int) int { return int(math.Ceil(float64(totalNodes+faultyNodes+1) / 2)) } From a7e02f73ec582a9d52c4d23db93f5e9118114106 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Thu, 18 Jan 2024 18:35:42 +0100 Subject: [PATCH 3/6] Unmarshall metadata Signed-off-by: David VIEJO --- configtx/orderer.go | 66 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/configtx/orderer.go b/configtx/orderer.go index a5c3333..9c44178 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -108,6 +108,7 @@ func (o *OrdererGroup) Organization(name string) *OrdererOrg { func (o *OrdererGroup) Configuration() (Orderer, error) { // CONSENSUS TYPE, STATE, AND METADATA var etcdRaft orderer.EtcdRaft + var smartBFT *sb.Options kafkaBrokers := orderer.Kafka{} consensusTypeProto := &ob.ConsensusType{} @@ -139,6 +140,11 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { if err != nil { return Orderer{}, fmt.Errorf("unmarshaling etcd raft metadata: %v", err) } + case orderer.ConsensusTypeBFT: + smartBFT, err = unmarshalSmartBFTOptions(consensusTypeProto.Metadata) + if err != nil { + return Orderer{}, fmt.Errorf("unmarshaling smart BFT options: %v", err) + } default: return Orderer{}, fmt.Errorf("config contains unknown consensus type '%s'", consensusTypeProto.Type) } @@ -160,6 +166,27 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { if err != nil { return Orderer{}, fmt.Errorf("batch timeout configuration '%s' is not a duration string", batchTimeoutProto.Timeout) } + orderersConfigValue, ok := o.ordererGroup.Values["Orderers"] + if !ok { + return Orderer{}, errors.New("unable to find orderers for orderer org") + } + orderers := cb.Orderers{} + err = proto.Unmarshal(orderersConfigValue.Value, &orderers) + if err != nil { + return Orderer{}, fmt.Errorf("unmarshaling orderers: %v", err) + } + var consenterMapping []common.Consenter + for _, consenterItem := range orderers.ConsenterMapping { + consenterMapping = append(consenterMapping, common.Consenter{ + Id: consenterItem.Id, + Host: consenterItem.Host, + Port: consenterItem.Port, + MspId: consenterItem.MspId, + Identity: consenterItem.Identity, + ClientTlsCert: consenterItem.ClientTlsCert, + ServerTlsCert: consenterItem.ServerTlsCert, + }) + } // ORDERER ORGS var ordererOrgs []Organization @@ -199,14 +226,16 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { AbsoluteMaxBytes: batchSize.AbsoluteMaxBytes, PreferredMaxBytes: batchSize.PreferredMaxBytes, }, - Kafka: kafkaBrokers, - EtcdRaft: etcdRaft, - Organizations: ordererOrgs, - MaxChannels: channelRestrictions.MaxCount, - Capabilities: capabilities, - Policies: policies, - State: state, - ModPolicy: o.ordererGroup.GetModPolicy(), + Kafka: kafkaBrokers, + EtcdRaft: etcdRaft, + ConsenterMapping: consenterMapping, + SmartBFT: smartBFT, + Organizations: ordererOrgs, + MaxChannels: channelRestrictions.MaxCount, + Capabilities: capabilities, + Policies: policies, + State: state, + ModPolicy: o.ordererGroup.GetModPolicy(), }, nil } @@ -853,11 +882,14 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { ModPolicy: "Admins", } // addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey) - if consensusMetadata, err = MarshalBFTOptions(o.SmartBFT); err != nil { + if consensusMetadata, err = marshalBFTOptions(o.SmartBFT); err != nil { return fmt.Errorf("consenter options read failed with error %s for orderer type %s", err, orderer.ConsensusTypeBFT) } // Overwrite policy manually by computing it from the consenters - encodeBFTBlockVerificationPolicy(o.ConsenterMapping, ordererGroup) + err = encodeBFTBlockVerificationPolicy(o.ConsenterMapping, ordererGroup) + if err != nil { + return fmt.Errorf("failed to encode BFT block verification policy: %v", err) + } default: return fmt.Errorf("unknown orderer type '%s'", o.OrdererType) } @@ -875,8 +907,8 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { return nil } -// MarshalBFTOptions serializes smartbft options. -func MarshalBFTOptions(op *sb.Options) ([]byte, error) { +// marshalBFTOptions serializes smartbft options. +func marshalBFTOptions(op *sb.Options) ([]byte, error) { if copyMd, ok := proto.Clone(op).(*sb.Options); ok { return proto.Marshal(copyMd) } @@ -1078,6 +1110,16 @@ func unmarshalEtcdRaftMetadata(mdBytes []byte) (orderer.EtcdRaft, error) { }, nil } +// unmarshalSmartBFTOptions deserializes . +func unmarshalSmartBFTOptions(optsBytes []byte) (*sb.Options, error) { + smartBFTOptions := &sb.Options{} + err := proto.Unmarshal(optsBytes, smartBFTOptions) + if err != nil { + return nil, err + } + return smartBFTOptions, nil +} + // getOrdererOrg returns the organization config group for an orderer org in the // provided config. It returns nil if the org doesn't exist in the config. func getOrdererOrg(config *cb.Config, orgName string) *cb.ConfigGroup { From d0ca879ab321e8f4e74647ac40f5bf5ee129503e Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Thu, 18 Jan 2024 18:43:40 +0100 Subject: [PATCH 4/6] Fix orderer tests Signed-off-by: David VIEJO --- configtx/orderer.go | 53 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/configtx/orderer.go b/configtx/orderer.go index 9c44178..34dd8e9 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -18,7 +18,6 @@ import ( "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric-config/configtx/internal/policydsl" "github.com/hyperledger/fabric-config/configtx/orderer" - "github.com/hyperledger/fabric-protos-go/common" cb "github.com/hyperledger/fabric-protos-go/common" mspa "github.com/hyperledger/fabric-protos-go/msp" ob "github.com/hyperledger/fabric-protos-go/orderer" @@ -44,7 +43,7 @@ type Orderer struct { Organizations []Organization SmartBFT *sb.Options - ConsenterMapping []common.Consenter + ConsenterMapping []cb.Consenter // MaxChannels is the maximum count of channels an orderer supports. MaxChannels uint64 // Capabilities is a map of the capabilities the orderer supports. @@ -109,6 +108,7 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { // CONSENSUS TYPE, STATE, AND METADATA var etcdRaft orderer.EtcdRaft var smartBFT *sb.Options + var consenterMapping []cb.Consenter kafkaBrokers := orderer.Kafka{} consensusTypeProto := &ob.ConsensusType{} @@ -145,6 +145,27 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { if err != nil { return Orderer{}, fmt.Errorf("unmarshaling smart BFT options: %v", err) } + + orderersConfigValue, ok := o.ordererGroup.Values["Orderers"] + if !ok { + return Orderer{}, errors.New("unable to find orderers for orderer org") + } + orderers := cb.Orderers{} + err = proto.Unmarshal(orderersConfigValue.Value, &orderers) + if err != nil { + return Orderer{}, fmt.Errorf("unmarshaling orderers: %v", err) + } + for _, consenterItem := range orderers.ConsenterMapping { + consenterMapping = append(consenterMapping, cb.Consenter{ + Id: consenterItem.Id, + Host: consenterItem.Host, + Port: consenterItem.Port, + MspId: consenterItem.MspId, + Identity: consenterItem.Identity, + ClientTlsCert: consenterItem.ClientTlsCert, + ServerTlsCert: consenterItem.ServerTlsCert, + }) + } default: return Orderer{}, fmt.Errorf("config contains unknown consensus type '%s'", consensusTypeProto.Type) } @@ -166,27 +187,6 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { if err != nil { return Orderer{}, fmt.Errorf("batch timeout configuration '%s' is not a duration string", batchTimeoutProto.Timeout) } - orderersConfigValue, ok := o.ordererGroup.Values["Orderers"] - if !ok { - return Orderer{}, errors.New("unable to find orderers for orderer org") - } - orderers := cb.Orderers{} - err = proto.Unmarshal(orderersConfigValue.Value, &orderers) - if err != nil { - return Orderer{}, fmt.Errorf("unmarshaling orderers: %v", err) - } - var consenterMapping []common.Consenter - for _, consenterItem := range orderers.ConsenterMapping { - consenterMapping = append(consenterMapping, common.Consenter{ - Id: consenterItem.Id, - Host: consenterItem.Host, - Port: consenterItem.Port, - MspId: consenterItem.MspId, - Identity: consenterItem.Identity, - ClientTlsCert: consenterItem.ClientTlsCert, - ServerTlsCert: consenterItem.ServerTlsCert, - }) - } // ORDERER ORGS var ordererOrgs []Organization @@ -909,10 +909,7 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { // marshalBFTOptions serializes smartbft options. func marshalBFTOptions(op *sb.Options) ([]byte, error) { - if copyMd, ok := proto.Clone(op).(*sb.Options); ok { - return proto.Marshal(copyMd) - } - return nil, errors.New("consenter options type mismatch") + return proto.Marshal(op) } // setOrdererPolicies adds *cb.ConfigPolicies to the passed Orderer *cb.ConfigGroup's Policies map. @@ -1148,7 +1145,7 @@ func blockDataHashingStructureValue() *standardConfigValue { } } -func encodeBFTBlockVerificationPolicy(consenterProtos []common.Consenter, ordererGroup *cb.ConfigGroup) error { +func encodeBFTBlockVerificationPolicy(consenterProtos []cb.Consenter, ordererGroup *cb.ConfigGroup) error { n := len(consenterProtos) f := (n - 1) / 3 From b397f0346372a7526ba089f8333cb604bb750a03 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Thu, 18 Jan 2024 18:48:23 +0100 Subject: [PATCH 5/6] SmartBFT -> SmartBFTOptions Signed-off-by: David VIEJO --- configtx/constants.go | 3 +++ configtx/orderer.go | 10 +++++----- configtx/orderer/orderer.go | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/configtx/constants.go b/configtx/constants.go index 4addb35..ca585c6 100644 --- a/configtx/constants.go +++ b/configtx/constants.go @@ -68,6 +68,9 @@ const ( // OrdererGroupKey is the group name for the orderer config. OrdererGroupKey = "Orderer" + // OrderersGroupKey is the group name for the orderer config. + OrderersGroupKey = "Orderers" + // ApplicationGroupKey is the group name for the Application config. ApplicationGroupKey = "Application" diff --git a/configtx/orderer.go b/configtx/orderer.go index 34dd8e9..d316b33 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -42,7 +42,7 @@ type Orderer struct { EtcdRaft orderer.EtcdRaft Organizations []Organization - SmartBFT *sb.Options + SmartBFTOptions *sb.Options ConsenterMapping []cb.Consenter // MaxChannels is the maximum count of channels an orderer supports. MaxChannels uint64 @@ -146,7 +146,7 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { return Orderer{}, fmt.Errorf("unmarshaling smart BFT options: %v", err) } - orderersConfigValue, ok := o.ordererGroup.Values["Orderers"] + orderersConfigValue, ok := o.ordererGroup.Values[OrderersGroupKey] if !ok { return Orderer{}, errors.New("unable to find orderers for orderer org") } @@ -229,7 +229,7 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { Kafka: kafkaBrokers, EtcdRaft: etcdRaft, ConsenterMapping: consenterMapping, - SmartBFT: smartBFT, + SmartBFTOptions: smartBFT, Organizations: ordererOrgs, MaxChannels: channelRestrictions.MaxCount, Capabilities: capabilities, @@ -877,12 +877,12 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { return fmt.Errorf("marshaling consenters for orderer type '%s': %v", orderer.ConsensusTypeBFT, err) } - ordererGroup.Values["Orderers"] = &cb.ConfigValue{ + ordererGroup.Values[OrderersGroupKey] = &cb.ConfigValue{ Value: consentersProto, ModPolicy: "Admins", } // addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey) - if consensusMetadata, err = marshalBFTOptions(o.SmartBFT); err != nil { + if consensusMetadata, err = marshalBFTOptions(o.SmartBFTOptions); err != nil { return fmt.Errorf("consenter options read failed with error %s for orderer type %s", err, orderer.ConsensusTypeBFT) } // Overwrite policy manually by computing it from the consenters diff --git a/configtx/orderer/orderer.go b/configtx/orderer/orderer.go index 252c3db..9ffecb4 100644 --- a/configtx/orderer/orderer.go +++ b/configtx/orderer/orderer.go @@ -28,7 +28,7 @@ const ( // ConsensusTypeEtcdRaft identifies the Raft-based consensus implementation. ConsensusTypeEtcdRaft = "etcdraft" - // ConsensusTypeBFT identifies the SmartBFT-based consensus implementation. + // ConsensusTypeBFT identifies the SmartBFTOptions-based consensus implementation. ConsensusTypeBFT = "BFT" // KafkaBrokersKey is the common.ConfigValue type key name for the KafkaBrokers message. From ef1a1564900ae1375dc57684e203f6270c9cfc36 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Thu, 18 Jan 2024 18:58:15 +0100 Subject: [PATCH 6/6] Revert SmartBFTOptions -> SmartBFT to be consistent with Fabric Signed-off-by: David VIEJO --- configtx/orderer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configtx/orderer.go b/configtx/orderer.go index d316b33..a25612b 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -42,7 +42,7 @@ type Orderer struct { EtcdRaft orderer.EtcdRaft Organizations []Organization - SmartBFTOptions *sb.Options + SmartBFT *sb.Options ConsenterMapping []cb.Consenter // MaxChannels is the maximum count of channels an orderer supports. MaxChannels uint64 @@ -229,7 +229,7 @@ func (o *OrdererGroup) Configuration() (Orderer, error) { Kafka: kafkaBrokers, EtcdRaft: etcdRaft, ConsenterMapping: consenterMapping, - SmartBFTOptions: smartBFT, + SmartBFT: smartBFT, Organizations: ordererOrgs, MaxChannels: channelRestrictions.MaxCount, Capabilities: capabilities, @@ -882,7 +882,7 @@ func addOrdererValues(ordererGroup *cb.ConfigGroup, o Orderer) error { ModPolicy: "Admins", } // addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey) - if consensusMetadata, err = marshalBFTOptions(o.SmartBFTOptions); err != nil { + if consensusMetadata, err = marshalBFTOptions(o.SmartBFT); err != nil { return fmt.Errorf("consenter options read failed with error %s for orderer type %s", err, orderer.ConsensusTypeBFT) } // Overwrite policy manually by computing it from the consenters