Skip to content

Commit

Permalink
[FAB-2396] Move orderer config to common Proposer
Browse files Browse the repository at this point in the history
https://jira.hyperledger.org/browse/FAB-2396

This is the second in a series of CRs which will migrate the config
value handlers off of their own custom transaction handling code and
onto the common Proposer code.  This will not only reduce the amount of
reimplimented logic (and corresponding bugs) and will also facilitate
the two-way config translation for the configtxgen tool.

Change-Id: I0e4bd1228c12b02fbf074b05379e917d463bf877
Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
Jason Yellick committed Mar 7, 2017
1 parent 8b20459 commit c8ff4b1
Showing 14 changed files with 366 additions and 677 deletions.
19 changes: 5 additions & 14 deletions common/configtx/template.go
Original file line number Diff line number Diff line change
@@ -19,13 +19,14 @@ package configtx
import (
"fmt"

"github.com/golang/protobuf/proto"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
config "github.com/hyperledger/fabric/common/configvalues/root"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/msp"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
"github.com/hyperledger/fabric/protos/utils"

"github.com/golang/protobuf/proto"
)

const (
@@ -34,16 +35,6 @@ const (
CreationPolicyKey = "CreationPolicy"
msgVersion = int32(0)
epoch = 0

// ApplicationGroup identifies the `groups` map key in the channel
// config, under which the application-related config group is set.
ApplicationGroup = "Application"
// OrdererGroup identifies the `groups` map key in the channel
// config, under which the orderer-related config group is set.
OrdererGroup = "Orderer"
// MSPKey identifies the config key in the channel config,
// under which the application-related config group is set.
MSPKey = "MSP"
)

// Template can be used to faciliate creation of config transactions
@@ -157,8 +148,8 @@ func (ct *compositeTemplate) Envelope(chainID string) (*cb.ConfigUpdateEnvelope,
// Template which outputs an appropriately constructed list of ConfigUpdateEnvelopes.
func NewChainCreationTemplate(creationPolicy string, template Template) Template {
result := cb.NewConfigGroup()
result.Groups[configtxorderer.GroupKey] = cb.NewConfigGroup()
result.Groups[configtxorderer.GroupKey].Values[CreationPolicyKey] = &cb.ConfigValue{
result.Groups[config.OrdererGroupKey] = cb.NewConfigGroup()
result.Groups[config.OrdererGroupKey].Values[CreationPolicyKey] = &cb.ConfigValue{
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
Policy: creationPolicy,
}),
4 changes: 2 additions & 2 deletions common/configtx/template_test.go
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ import (
"testing"

"github.com/golang/protobuf/proto"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
config "github.com/hyperledger/fabric/common/configvalues/root"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"

@@ -104,7 +104,7 @@ func TestNewChainTemplate(t *testing.T) {
assert.True(t, ok, "Expected to find %d but did not", i)
}

configValue, ok := configNext.WriteSet.Groups[configtxorderer.GroupKey].Values[CreationPolicyKey]
configValue, ok := configNext.WriteSet.Groups[config.OrdererGroupKey].Values[CreationPolicyKey]
assert.True(t, ok, "Did not find creation policy")

creationPolicyMessage := new(ab.CreationPolicy)
4 changes: 2 additions & 2 deletions common/configtx/test/helper.go
Original file line number Diff line number Diff line change
@@ -24,8 +24,8 @@ import (
genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
configtxapplication "github.com/hyperledger/fabric/common/configvalues/channel/application"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
configtxmsp "github.com/hyperledger/fabric/common/configvalues/msp"
config "github.com/hyperledger/fabric/common/configvalues/root"
"github.com/hyperledger/fabric/common/genesis"
"github.com/hyperledger/fabric/msp"
cb "github.com/hyperledger/fabric/protos/common"
@@ -104,7 +104,7 @@ func OrdererOrgTemplate() configtx.Template {
if err != nil {
logger.Panicf("Could not load sample MSP config: %s", err)
}
return configtx.NewSimpleTemplate(configtxmsp.TemplateGroupMSP([]string{configtxorderer.GroupKey, sampleOrgID}, mspConf))
return configtx.NewSimpleTemplate(configtxmsp.TemplateGroupMSP([]string{config.OrdererGroupKey, sampleOrgID}, mspConf))
}

// CompositeTemplate returns the composite template of peer, orderer, and MSP
21 changes: 10 additions & 11 deletions common/configtx/tool/provisional/provisional.go
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ import (
"github.com/hyperledger/fabric/common/configtx"
genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
configtxapplication "github.com/hyperledger/fabric/common/configvalues/channel/application"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
configvaluesmsp "github.com/hyperledger/fabric/common/configvalues/msp"
config "github.com/hyperledger/fabric/common/configvalues/root"
"github.com/hyperledger/fabric/common/genesis"
@@ -100,40 +99,40 @@ func New(conf *genesisconfig.Profile) Generator {
if conf.Orderer != nil {
bs.ordererGroups = []*cb.ConfigGroup{
// Orderer Config Types
configtxorderer.TemplateConsensusType(conf.Orderer.OrdererType),
configtxorderer.TemplateBatchSize(&ab.BatchSize{
config.TemplateConsensusType(conf.Orderer.OrdererType),
config.TemplateBatchSize(&ab.BatchSize{
MaxMessageCount: conf.Orderer.BatchSize.MaxMessageCount,
AbsoluteMaxBytes: conf.Orderer.BatchSize.AbsoluteMaxBytes,
PreferredMaxBytes: conf.Orderer.BatchSize.PreferredMaxBytes,
}),
configtxorderer.TemplateBatchTimeout(conf.Orderer.BatchTimeout.String()),
config.TemplateBatchTimeout(conf.Orderer.BatchTimeout.String()),

// Initialize the default Reader/Writer/Admins orderer policies, as well as block validation policy
policies.TemplateImplicitMetaPolicyWithSubPolicy([]string{configtxorderer.GroupKey}, BlockValidationPolicyKey, configvaluesmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY),
policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.ReadersPolicyKey),
policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.WritersPolicyKey),
policies.TemplateImplicitMetaMajorityPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.AdminsPolicyKey),
policies.TemplateImplicitMetaPolicyWithSubPolicy([]string{config.OrdererGroupKey}, BlockValidationPolicyKey, configvaluesmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY),
policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.ReadersPolicyKey),
policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.WritersPolicyKey),
policies.TemplateImplicitMetaMajorityPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.AdminsPolicyKey),
}

for _, org := range conf.Orderer.Organizations {
mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID)
if err != nil {
logger.Panicf("Error loading MSP configuration for org %s: %s", org.Name, err)
}
bs.ordererGroups = append(bs.ordererGroups, configvaluesmsp.TemplateGroupMSP([]string{configtxorderer.GroupKey, org.Name}, mspConfig))
bs.ordererGroups = append(bs.ordererGroups, configvaluesmsp.TemplateGroupMSP([]string{config.OrdererGroupKey, org.Name}, mspConfig))
}

switch conf.Orderer.OrdererType {
case ConsensusTypeSolo, ConsensusTypeSbft:
case ConsensusTypeKafka:
bs.ordererGroups = append(bs.ordererGroups, configtxorderer.TemplateKafkaBrokers(conf.Orderer.Kafka.Brokers))
bs.ordererGroups = append(bs.ordererGroups, config.TemplateKafkaBrokers(conf.Orderer.Kafka.Brokers))
default:
panic(fmt.Errorf("Wrong consenter type value given: %s", conf.Orderer.OrdererType))
}

bs.ordererSystemChannelGroups = []*cb.ConfigGroup{
// Policies
configtxorderer.TemplateChainCreationPolicyNames(DefaultChainCreationPolicyNames),
config.TemplateChainCreationPolicyNames(DefaultChainCreationPolicyNames),
}
}

288 changes: 0 additions & 288 deletions common/configvalues/channel/orderer/sharedconfig.go

This file was deleted.

333 changes: 0 additions & 333 deletions common/configvalues/channel/orderer/sharedconfig_test.go

This file was deleted.

13 changes: 6 additions & 7 deletions common/configvalues/root/channel.go
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ import (
"github.com/hyperledger/fabric/bccsp"
api "github.com/hyperledger/fabric/common/configvalues"
"github.com/hyperledger/fabric/common/configvalues/channel/application"
"github.com/hyperledger/fabric/common/configvalues/channel/orderer"
"github.com/hyperledger/fabric/common/configvalues/msp"
"github.com/hyperledger/fabric/common/util"
cb "github.com/hyperledger/fabric/protos/common"
@@ -99,7 +98,7 @@ func (cg *ChannelGroup) Allocate() Values {
}

// OrdererConfig returns the orderer config associated with this channel
func (cg *ChannelGroup) OrdererConfig() *orderer.ManagerImpl {
func (cg *ChannelGroup) OrdererConfig() *OrdererGroup {
return cg.ChannelConfig.ordererConfig
}

@@ -113,8 +112,8 @@ func (cg *ChannelGroup) NewGroup(group string) (api.ValueProposer, error) {
switch group {
case application.GroupKey:
return application.NewSharedConfigImpl(cg.mspConfigHandler), nil
case orderer.GroupKey:
return orderer.NewManagerImpl(cg.mspConfigHandler), nil
case OrdererGroupKey:
return NewOrdererGroup(cg.mspConfigHandler), nil
default:
return nil, fmt.Errorf("Disallowed channel group: %s", group)
}
@@ -128,7 +127,7 @@ type ChannelConfig struct {
hashingAlgorithm func(input []byte) []byte

appConfig *application.SharedConfigImpl
ordererConfig *orderer.ManagerImpl
ordererConfig *OrdererGroup
}

// NewChannelConfig creates a new ChannelConfig
@@ -181,8 +180,8 @@ func (cc *ChannelConfig) Validate(groups map[string]api.ValueProposer) error {
if !ok {
return fmt.Errorf("Application group was not Application config")
}
case orderer.GroupKey:
cc.ordererConfig, ok = value.(*orderer.ManagerImpl)
case OrdererGroupKey:
cc.ordererConfig, ok = value.(*OrdererGroup)
if !ok {
return fmt.Errorf("Orderer group was not Orderer config")
}
236 changes: 236 additions & 0 deletions common/configvalues/root/orderer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"fmt"
"regexp"
"strconv"
"strings"
"time"

api "github.com/hyperledger/fabric/common/configvalues"
"github.com/hyperledger/fabric/common/configvalues/channel/common/organization"
"github.com/hyperledger/fabric/common/configvalues/msp"
ab "github.com/hyperledger/fabric/protos/orderer"
)

const (
// OrdererGroupKey is the group name for the orderer config
OrdererGroupKey = "Orderer"
)

const (
// ConsensusTypeKey is the cb.ConfigItem type key name for the ConsensusType message
ConsensusTypeKey = "ConsensusType"

// BatchSizeKey is the cb.ConfigItem type key name for the BatchSize message
BatchSizeKey = "BatchSize"

// BatchTimeoutKey is the cb.ConfigItem type key name for the BatchTimeout message
BatchTimeoutKey = "BatchTimeout"

// ChainCreationPolicyNamesKey is the cb.ConfigItem type key name for the ChainCreationPolicyNames message
ChainCreationPolicyNamesKey = "ChainCreationPolicyNames"

// KafkaBrokersKey is the cb.ConfigItem type key name for the KafkaBrokers message
KafkaBrokersKey = "KafkaBrokers"
)

// OrdererProtos is used as the source of the OrdererConfig
type OrdererProtos struct {
ConsensusType *ab.ConsensusType
BatchSize *ab.BatchSize
BatchTimeout *ab.BatchTimeout
ChainCreationPolicyNames *ab.ChainCreationPolicyNames
KafkaBrokers *ab.KafkaBrokers
CreationPolicy *ab.CreationPolicy
}

// Config is stores the orderer component configuration
type OrdererGroup struct {
*Proposer
*OrdererConfig

mspConfig *msp.MSPConfigHandler
}

// NewConfig creates a new *OrdererConfig
func NewOrdererGroup(mspConfig *msp.MSPConfigHandler) *OrdererGroup {
og := &OrdererGroup{
mspConfig: mspConfig,
}
og.Proposer = NewProposer(og)
return og
}

// NewGroup returns an Org instance
func (og *OrdererGroup) NewGroup(name string) (api.ValueProposer, error) {
return organization.NewOrgConfig(name, og.mspConfig), nil
}

func (og *OrdererGroup) Allocate() Values {
return NewOrdererConfig(og)
}

// OrdererConfig holds the orderer configuration information
type OrdererConfig struct {
*standardValues
protos *OrdererProtos
ordererGroup *OrdererGroup

batchTimeout time.Duration
}

// NewOrdererConfig creates a new instance of the orderer config
func NewOrdererConfig(og *OrdererGroup) *OrdererConfig {
oc := &OrdererConfig{
protos: &OrdererProtos{},
ordererGroup: og,
}

var err error
oc.standardValues, err = NewStandardValues(oc.protos)
if err != nil {
logger.Panicf("Programming error: %s", err)
}
return oc
}

// Commit writes the orderer config back to the orderer config group
func (oc *OrdererConfig) Commit() {
oc.ordererGroup.OrdererConfig = oc
}

// ConsensusType returns the configured consensus type
func (oc *OrdererConfig) ConsensusType() string {
return oc.protos.ConsensusType.Type
}

// BatchSize returns the maximum number of messages to include in a block
func (oc *OrdererConfig) BatchSize() *ab.BatchSize {
return oc.protos.BatchSize
}

// BatchTimeout returns the amount of time to wait before creating a batch
func (oc *OrdererConfig) BatchTimeout() time.Duration {
return oc.batchTimeout
}

// ChainCreationPolicyNames returns the policy names which are allowed for chain creation
// This field is only set for the system ordering chain
func (oc *OrdererConfig) ChainCreationPolicyNames() []string {
return oc.protos.ChainCreationPolicyNames.Names
}

// KafkaBrokers returns the addresses (IP:port notation) of a set of "bootstrap"
// Kafka brokers, i.e. this is not necessarily the entire set of Kafka brokers
// used for ordering
func (oc *OrdererConfig) KafkaBrokers() []string {
return oc.protos.KafkaBrokers.Brokers
}

func (oc *OrdererConfig) Validate(groups map[string]api.ValueProposer) error {
for _, validator := range []func() error{
oc.validateConsensusType,
oc.validateBatchSize,
oc.validateBatchTimeout,
oc.validateKafkaBrokers,
} {
if err := validator(); err != nil {
return err
}
}

return nil
}

func (oc *OrdererConfig) validateConsensusType() error {
if oc.ordererGroup.OrdererConfig != nil && oc.ordererGroup.ConsensusType() != oc.protos.ConsensusType.Type {
// The first config we accept the consensus type regardless
return fmt.Errorf("Attempted to change the consensus type from %s to %s after init", oc.ordererGroup.ConsensusType(), oc.protos.ConsensusType.Type)
}
return nil
}

func (oc *OrdererConfig) validateBatchSize() error {
if oc.protos.BatchSize.MaxMessageCount == 0 {
return fmt.Errorf("Attempted to set the batch size max message count to an invalid value: 0")
}
if oc.protos.BatchSize.AbsoluteMaxBytes == 0 {
return fmt.Errorf("Attempted to set the batch size absolute max bytes to an invalid value: 0")
}
if oc.protos.BatchSize.PreferredMaxBytes == 0 {
return fmt.Errorf("Attempted to set the batch size preferred max bytes to an invalid value: 0")
}
if oc.protos.BatchSize.PreferredMaxBytes > oc.protos.BatchSize.AbsoluteMaxBytes {
return fmt.Errorf("Attempted to set the batch size preferred max bytes (%v) greater than the absolute max bytes (%v).", oc.protos.BatchSize.PreferredMaxBytes, oc.protos.BatchSize.AbsoluteMaxBytes)
}
return nil
}

func (oc *OrdererConfig) validateBatchTimeout() error {
var err error
oc.batchTimeout, err = time.ParseDuration(oc.protos.BatchTimeout.Timeout)
if err != nil {
return fmt.Errorf("Attempted to set the batch timeout to a invalid value: %s", err)
}
if oc.batchTimeout <= 0 {
return fmt.Errorf("Attempted to set the batch timeout to a non-positive value: %s", oc.batchTimeout)
}
return nil
}

func (oc *OrdererConfig) validateKafkaBrokers() error {
for _, broker := range oc.protos.KafkaBrokers.Brokers {
if !brokerEntrySeemsValid(broker) {
return fmt.Errorf("Invalid broker entry: %s", broker)
}
}
return nil
}

// This does just a barebones sanity check.
func brokerEntrySeemsValid(broker string) bool {
if !strings.Contains(broker, ":") {
return false
}

parts := strings.Split(broker, ":")
if len(parts) > 2 {
return false
}

host := parts[0]
port := parts[1]

if _, err := strconv.ParseUint(port, 10, 16); err != nil {
return false
}

// Valid hostnames may contain only the ASCII letters 'a' through 'z' (in a
// case-insensitive manner), the digits '0' through '9', and the hyphen. IP
// v4 addresses are represented in dot-decimal notation, which consists of
// four decimal numbers, each ranging from 0 to 255, separated by dots,
// e.g., 172.16.254.1
// The following regular expression:
// 1. allows just a-z (case-insensitive), 0-9, and the dot and hyphen characters
// 2. does not allow leading trailing dots or hyphens
re, _ := regexp.Compile("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9])$")
matched := re.FindString(host)
return len(matched) == len(host)
}
85 changes: 85 additions & 0 deletions common/configvalues/root/orderer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"testing"

ab "github.com/hyperledger/fabric/protos/orderer"

logging "github.com/op/go-logging"
"github.com/stretchr/testify/assert"
)

func init() {
logging.SetLevel(logging.DEBUG, "")
}

func TestConsensusType(t *testing.T) {
oc := &OrdererConfig{ordererGroup: &OrdererGroup{}, protos: &OrdererProtos{ConsensusType: &ab.ConsensusType{Type: "foo"}}}
assert.NoError(t, oc.validateConsensusType(), "Should have validly set new consensus type")

oc = &OrdererConfig{
ordererGroup: &OrdererGroup{OrdererConfig: &OrdererConfig{protos: &OrdererProtos{ConsensusType: &ab.ConsensusType{Type: "foo"}}}},
protos: &OrdererProtos{ConsensusType: &ab.ConsensusType{Type: "foo"}},
}
assert.NoError(t, oc.validateConsensusType(), "Should have kept consensus type")

oc = &OrdererConfig{
ordererGroup: &OrdererGroup{OrdererConfig: &OrdererConfig{protos: &OrdererProtos{ConsensusType: &ab.ConsensusType{Type: "bar"}}}},
protos: &OrdererProtos{ConsensusType: &ab.ConsensusType{Type: "foo"}},
}
assert.Error(t, oc.validateConsensusType(), "Should have failed to change consensus type")
}

func TestBatchSize(t *testing.T) {

validMaxMessageCount := uint32(10)
validAbsoluteMaxBytes := uint32(1000)
validPreferredMaxBytes := uint32(500)

oc := &OrdererConfig{protos: &OrdererProtos{BatchSize: &ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}}}
assert.NoError(t, oc.validateBatchSize(), "BatchSize was valid")

oc = &OrdererConfig{protos: &OrdererProtos{BatchSize: &ab.BatchSize{MaxMessageCount: 0, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}}}
assert.Error(t, oc.validateBatchSize(), "MaxMessageCount was zero")

oc = &OrdererConfig{protos: &OrdererProtos{BatchSize: &ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: 0, PreferredMaxBytes: validPreferredMaxBytes}}}
assert.Error(t, oc.validateBatchSize(), "AbsoluteMaxBytes was zero")

oc = &OrdererConfig{protos: &OrdererProtos{BatchSize: &ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validAbsoluteMaxBytes + 1}}}
assert.Error(t, oc.validateBatchSize(), "PreferredMaxBytes larger to AbsoluteMaxBytes")
}

func TestBatchTimeout(t *testing.T) {
oc := &OrdererConfig{protos: &OrdererProtos{BatchTimeout: &ab.BatchTimeout{Timeout: "1s"}}}
assert.NoError(t, oc.validateBatchTimeout(), "Valid batch timeout")

oc = &OrdererConfig{protos: &OrdererProtos{BatchTimeout: &ab.BatchTimeout{Timeout: "-1s"}}}
assert.Error(t, oc.validateBatchTimeout(), "Negative batch timeout")

oc = &OrdererConfig{protos: &OrdererProtos{BatchTimeout: &ab.BatchTimeout{Timeout: "0s"}}}
assert.Error(t, oc.validateBatchTimeout(), "Zero batch timeout")
}

func TestKafkaBrokers(t *testing.T) {
oc := &OrdererConfig{protos: &OrdererProtos{KafkaBrokers: &ab.KafkaBrokers{Brokers: []string{"127.0.0.1:9092", "foo.bar:9092"}}}}
assert.NoError(t, oc.validateKafkaBrokers(), "Valid kafka brokers")

oc = &OrdererConfig{protos: &OrdererProtos{KafkaBrokers: &ab.KafkaBrokers{Brokers: []string{"127.0.0.1", "foo.bar", "127.0.0.1:-1", "localhost:65536", "foo.bar.:9092", ".127.0.0.1:9092", "-foo.bar:9092"}}}}
assert.Error(t, oc.validateKafkaBrokers(), "Invalid kafka brokers")
}
Original file line number Diff line number Diff line change
@@ -14,44 +14,44 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package orderer
package config

import (
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
"github.com/hyperledger/fabric/protos/utils"
)

func configGroup(key string, value []byte) *cb.ConfigGroup {
func ordererConfigGroup(key string, value []byte) *cb.ConfigGroup {
result := cb.NewConfigGroup()
result.Groups[GroupKey] = cb.NewConfigGroup()
result.Groups[GroupKey].Values[key] = &cb.ConfigValue{
result.Groups[OrdererGroupKey] = cb.NewConfigGroup()
result.Groups[OrdererGroupKey].Values[key] = &cb.ConfigValue{
Value: value,
}
return result
}

// TemplateConsensusType creates a headerless config item representing the consensus type
func TemplateConsensusType(typeValue string) *cb.ConfigGroup {
return configGroup(ConsensusTypeKey, utils.MarshalOrPanic(&ab.ConsensusType{Type: typeValue}))
return ordererConfigGroup(ConsensusTypeKey, utils.MarshalOrPanic(&ab.ConsensusType{Type: typeValue}))
}

// TemplateBatchSize creates a headerless config item representing the batch size
func TemplateBatchSize(batchSize *ab.BatchSize) *cb.ConfigGroup {
return configGroup(BatchSizeKey, utils.MarshalOrPanic(batchSize))
return ordererConfigGroup(BatchSizeKey, utils.MarshalOrPanic(batchSize))
}

// TemplateBatchTimeout creates a headerless config item representing the batch timeout
func TemplateBatchTimeout(batchTimeout string) *cb.ConfigGroup {
return configGroup(BatchTimeoutKey, utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: batchTimeout}))
return ordererConfigGroup(BatchTimeoutKey, utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: batchTimeout}))
}

// TemplateChainCreationPolicyNames creates a headerless configuraiton item representing the chain creation policy names
func TemplateChainCreationPolicyNames(names []string) *cb.ConfigGroup {
return configGroup(ChainCreationPolicyNamesKey, utils.MarshalOrPanic(&ab.ChainCreationPolicyNames{Names: names}))
return ordererConfigGroup(ChainCreationPolicyNamesKey, utils.MarshalOrPanic(&ab.ChainCreationPolicyNames{Names: names}))
}

// TemplateKafkaBrokers creates a headerless config item representing the kafka brokers
func TemplateKafkaBrokers(brokers []string) *cb.ConfigGroup {
return configGroup(KafkaBrokersKey, utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: brokers}))
return ordererConfigGroup(KafkaBrokersKey, utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: brokers}))
}
5 changes: 3 additions & 2 deletions common/configvalues/root/proposer.go
Original file line number Diff line number Diff line change
@@ -61,7 +61,8 @@ type Proposer struct {

func NewProposer(vh Handler) *Proposer {
return &Proposer{
vh: vh,
vh: vh,
current: &config{},
}
}

@@ -108,7 +109,7 @@ func (p *Proposer) BeginValueProposals(groups []string) ([]api.ValueProposer, er
func (p *Proposer) ProposeValue(key string, configValue *cb.ConfigValue) error {
msg, ok := p.pending.allocated.ProtoMsg(key)
if !ok {
return fmt.Errorf("Unknown value key: %s", key)
return fmt.Errorf("Unknown value key %s for %T", key, p.vh)
}

if err := proto.Unmarshal(configValue.Value, msg); err != nil {
3 changes: 1 addition & 2 deletions common/configvalues/root/root.go
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ import (

configvaluesapi "github.com/hyperledger/fabric/common/configvalues"
"github.com/hyperledger/fabric/common/configvalues/channel/application"
"github.com/hyperledger/fabric/common/configvalues/channel/orderer"
"github.com/hyperledger/fabric/common/configvalues/msp"
cb "github.com/hyperledger/fabric/protos/common"
)
@@ -80,7 +79,7 @@ func (r *Root) Channel() *ChannelGroup {
}

// Orderer returns the associated Orderer level config
func (r *Root) Orderer() *orderer.ManagerImpl {
func (r *Root) Orderer() *OrdererGroup {
return r.channel.OrdererConfig()
}

8 changes: 4 additions & 4 deletions orderer/multichain/systemchain.go
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ import (
"github.com/hyperledger/fabric/common/configtx"
configtxapi "github.com/hyperledger/fabric/common/configtx/api"
configvaluesapi "github.com/hyperledger/fabric/common/configvalues"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
config "github.com/hyperledger/fabric/common/configvalues/root"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/orderer/common/filter"
cb "github.com/hyperledger/fabric/protos/common"
@@ -121,16 +121,16 @@ func (scf *systemChainFilter) authorize(configEnvelope *cb.ConfigEnvelope) error
return fmt.Errorf("Failing to validate chain creation because of config update envelope unmarshaling error: %s", err)
}

config, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
configMsg, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
if err != nil {
return fmt.Errorf("Failing to validate chain creation because of unmarshaling error: %s", err)
}

if config.WriteSet == nil {
if configMsg.WriteSet == nil {
return fmt.Errorf("Failing to validate channel creation because WriteSet is nil")
}

ordererGroup, ok := config.WriteSet.Groups[configtxorderer.GroupKey]
ordererGroup, ok := configMsg.WriteSet.Groups[config.OrdererGroupKey]
if !ok {
return fmt.Errorf("Rejecting channel creation because it is missing orderer group")
}
6 changes: 3 additions & 3 deletions orderer/multichain/util_test.go
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ import (

"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer"
config "github.com/hyperledger/fabric/common/configvalues/root"
"github.com/hyperledger/fabric/orderer/common/blockcutter"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"
@@ -89,8 +89,8 @@ func (mlw *mockLedgerWriter) Append(blockContents []*cb.Envelope, metadata [][]b

func makeConfigTx(chainID string, i int) *cb.Envelope {
group := cb.NewConfigGroup()
group.Groups[configtxorderer.GroupKey] = cb.NewConfigGroup()
group.Groups[configtxorderer.GroupKey].Values[fmt.Sprintf("%d", i)] = &cb.ConfigValue{
group.Groups[config.OrdererGroupKey] = cb.NewConfigGroup()
group.Groups[config.OrdererGroupKey].Values[fmt.Sprintf("%d", i)] = &cb.ConfigValue{
Value: []byte(fmt.Sprintf("%d", i)),
}
configTemplate := configtx.NewSimpleTemplate(group)

0 comments on commit c8ff4b1

Please sign in to comment.