diff --git a/orderer/common/bootstrap/provisional/item.go b/orderer/common/bootstrap/provisional/item.go index 30fca533901..73ff5912cac 100644 --- a/orderer/common/bootstrap/provisional/item.go +++ b/orderer/common/bootstrap/provisional/item.go @@ -21,44 +21,23 @@ import ( "github.com/hyperledger/fabric/common/configtx" "github.com/hyperledger/fabric/orderer/common/sharedconfig" cb "github.com/hyperledger/fabric/protos/common" - ab "github.com/hyperledger/fabric/protos/orderer" "github.com/hyperledger/fabric/protos/utils" ) func (cbs *commonBootstrapper) templateConsensusType() *cb.ConfigurationItem { - configItemKey := sharedconfig.ConsensusTypeKey - configItemValue := utils.MarshalOrPanic(&ab.ConsensusType{Type: cbs.consensusType}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateConsensusType(cbs.consensusType) } func (cbs *commonBootstrapper) templateBatchSize() *cb.ConfigurationItem { - configItemKey := sharedconfig.BatchSizeKey - configItemValue := utils.MarshalOrPanic(cbs.batchSize) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateBatchSize(cbs.batchSize) } func (cbs *commonBootstrapper) templateBatchTimeout() *cb.ConfigurationItem { - configItemKey := sharedconfig.BatchTimeoutKey - configItemValue := utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: cbs.batchTimeout}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateBatchTimeout(cbs.batchTimeout) } func (cbs *commonBootstrapper) templateChainCreationPolicyNames() *cb.ConfigurationItem { - configItemKey := sharedconfig.ChainCreationPolicyNamesKey - configItemValue := utils.MarshalOrPanic(&ab.ChainCreationPolicyNames{Names: DefaultChainCreationPolicyNames}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateChainCreationPolicyNames(DefaultChainCreationPolicyNames) } func (cbs *commonBootstrapper) templateAcceptAllPolicy() *cb.ConfigurationItem { @@ -71,21 +50,11 @@ func (cbs *commonBootstrapper) templateAcceptAllPolicy() *cb.ConfigurationItem { } func (cbs *commonBootstrapper) templateIngressPolicyNames() *cb.ConfigurationItem { - configItemKey := sharedconfig.IngressPolicyNamesKey - configItemValue := utils.MarshalOrPanic(&ab.IngressPolicyNames{Names: []string{AcceptAllPolicyKey}}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateIngressPolicyNames([]string{AcceptAllPolicyKey}) } func (cbs *commonBootstrapper) templateEgressPolicyNames() *cb.ConfigurationItem { - configItemKey := sharedconfig.EgressPolicyNamesKey - configItemValue := utils.MarshalOrPanic(&ab.EgressPolicyNames{Names: []string{AcceptAllPolicyKey}}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateEgressPolicyNames([]string{AcceptAllPolicyKey}) } func (cbs *commonBootstrapper) templateRejectAllPolicy() *cb.ConfigurationItem { @@ -99,10 +68,5 @@ func (cbs *commonBootstrapper) templateRejectAllPolicy() *cb.ConfigurationItem { } func (kbs *kafkaBootstrapper) templateKafkaBrokers() *cb.ConfigurationItem { - configItemKey := sharedconfig.KafkaBrokersKey - configItemValue := utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: kbs.kafkaBrokers}) - modPolicy := configtx.NewConfigurationItemPolicyKey - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, kbs.chainID, epoch) - return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return sharedconfig.TemplateKafkaBrokers(kbs.kafkaBrokers) } diff --git a/orderer/common/sharedconfig/sharedconfig_test.go b/orderer/common/sharedconfig/sharedconfig_test.go index ca698a0296f..66d91a6c677 100644 --- a/orderer/common/sharedconfig/sharedconfig_test.go +++ b/orderer/common/sharedconfig/sharedconfig_test.go @@ -27,7 +27,6 @@ import ( cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" - "github.com/hyperledger/fabric/protos/utils" logging "github.com/op/go-logging" ) @@ -36,6 +35,14 @@ func init() { logging.SetLevel(logging.DEBUG, "") } +func invalidMessage(key string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: key, + Value: []byte("Garbage Data"), + } +} + func doesFuncCrash(crasher func(), test string) bool { // Adapted from https://talks.golang.org/2014/testing.slide#23 to test os.Exit() functionality if os.Getenv("BE_CRASHER") == "1" { @@ -85,22 +92,10 @@ func TestRollback(t *testing.T) { func TestConsensusType(t *testing.T) { endType := "foo" - invalidMessage := - &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: ConsensusTypeKey, - Value: []byte("Garbage Data"), - } - validMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: ConsensusTypeKey, - Value: utils.MarshalOrPanic(&ab.ConsensusType{Type: endType}), - } - otherValidMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: ConsensusTypeKey, - Value: utils.MarshalOrPanic(&ab.ConsensusType{Type: "bar"}), - } + invalidMessage := invalidMessage(ConsensusTypeKey) + validMessage := TemplateConsensusType(endType) + otherValidMessage := TemplateConsensusType("bar") + m := NewManagerImpl() m.BeginConfig() @@ -143,11 +138,9 @@ func TestBatchSize(t *testing.T) { t.Run("ValidConfiguration", func(t *testing.T) { m := NewManagerImpl() m.BeginConfig() - err := m.ProposeConfig(&cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchSizeKey, - Value: utils.MarshalOrPanic(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}), - }) + err := m.ProposeConfig( + TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}), + ) assert.Nil(t, err, "Error applying valid config: %s", err) m.CommitConfig() if m.BatchSize().MaxMessageCount != validMaxMessageCount { @@ -164,11 +157,7 @@ func TestBatchSize(t *testing.T) { t.Run("UnserializableConfiguration", func(t *testing.T) { m := NewManagerImpl() m.BeginConfig() - err := m.ProposeConfig(&cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchSizeKey, - Value: []byte("Garbage Data"), - }) + err := m.ProposeConfig(invalidMessage(BatchSizeKey)) assert.NotNil(t, err, "Should have failed on invalid message") m.CommitConfig() }) @@ -176,11 +165,7 @@ func TestBatchSize(t *testing.T) { t.Run("ZeroMaxMessageCount", func(t *testing.T) { m := NewManagerImpl() m.BeginConfig() - err := m.ProposeConfig(&cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchSizeKey, - Value: utils.MarshalOrPanic(&ab.BatchSize{MaxMessageCount: 0, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}), - }) + err := m.ProposeConfig(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: 0, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes})) assert.NotNil(t, err, "Should have rejected batch size max message count of 0") m.CommitConfig() }) @@ -188,11 +173,7 @@ func TestBatchSize(t *testing.T) { t.Run("ZeroAbsoluteMaxBytes", func(t *testing.T) { m := NewManagerImpl() m.BeginConfig() - err := m.ProposeConfig(&cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchSizeKey, - Value: utils.MarshalOrPanic(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: 0, PreferredMaxBytes: validPreferredMaxBytes}), - }) + err := m.ProposeConfig(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: 0, PreferredMaxBytes: validPreferredMaxBytes})) assert.NotNil(t, err, "Should have rejected batch size absolute max message bytes of 0") m.CommitConfig() }) @@ -200,11 +181,7 @@ func TestBatchSize(t *testing.T) { t.Run("TooLargePreferredMaxBytes", func(t *testing.T) { m := NewManagerImpl() m.BeginConfig() - err := m.ProposeConfig(&cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchSizeKey, - Value: utils.MarshalOrPanic(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validAbsoluteMaxBytes + 1}), - }) + err := m.ProposeConfig(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validAbsoluteMaxBytes + 1})) assert.NotNil(t, err, "Should have rejected batch size preferred max message bytes greater than absolute max message bytes") m.CommitConfig() }) @@ -212,26 +189,11 @@ func TestBatchSize(t *testing.T) { func TestBatchTimeout(t *testing.T) { endBatchTimeout, _ := time.ParseDuration("1s") - invalidMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchTimeoutKey, - Value: []byte("Garbage Data"), - } - negativeBatchTimeout := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchTimeoutKey, - Value: utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: "-1s"}), - } - zeroBatchTimeout := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchTimeoutKey, - Value: utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: "0s"}), - } - validMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: BatchTimeoutKey, - Value: utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: endBatchTimeout.String()}), - } + invalidMessage := invalidMessage(BatchTimeoutKey) + negativeBatchTimeout := TemplateBatchTimeout("-1s") + zeroBatchTimeout := TemplateBatchTimeout("0s") + validMessage := TemplateBatchTimeout(endBatchTimeout.String()) + m := NewManagerImpl() m.BeginConfig() @@ -265,34 +227,15 @@ func TestBatchTimeout(t *testing.T) { func TestKafkaBrokers(t *testing.T) { endList := []string{"127.0.0.1:9092", "foo.bar:9092"} - invalidMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: KafkaBrokersKey, - Value: []byte("Garbage Data"), - } - - zeroBrokers := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: KafkaBrokersKey, - Value: utils.MarshalOrPanic(&ab.KafkaBrokers{}), - } - + invalidMessage := invalidMessage(KafkaBrokersKey) + zeroBrokers := TemplateKafkaBrokers([]string{}) badList := []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"} badMessages := []*cb.ConfigurationItem{} for _, badAddress := range badList { - msg := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: KafkaBrokersKey, - Value: utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: []string{badAddress}}), - } - badMessages = append(badMessages, msg) + badMessages = append(badMessages, TemplateKafkaBrokers([]string{badAddress})) } - validMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: KafkaBrokersKey, - Value: utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: endList}), - } + validMessage := TemplateKafkaBrokers(endList) m := NewManagerImpl() m.BeginConfig() @@ -330,20 +273,11 @@ func TestKafkaBrokers(t *testing.T) { } } -func TestIngressPolicyNames(t *testing.T) { - endPolicy := []string{"foo"} - invalidMessage := - &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: IngressPolicyNamesKey, - Value: []byte("Garbage Data"), - } - validMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: IngressPolicyNamesKey, - Value: utils.MarshalOrPanic(&ab.IngressPolicyNames{Names: endPolicy}), - } - m := NewManagerImpl() +func testPolicyNames(m *ManagerImpl, key string, initializer func(val []string) *cb.ConfigurationItem, retriever func() []string, t *testing.T) { + endPolicy := []string{"foo", "bar"} + invalidMessage := invalidMessage(key) + validMessage := initializer(endPolicy) + m.BeginConfig() err := m.ProposeConfig(validMessage) @@ -366,48 +300,22 @@ func TestIngressPolicyNames(t *testing.T) { m.CommitConfig() - if nowPolicy := m.IngressPolicyNames(); !reflect.DeepEqual(nowPolicy, endPolicy) { - t.Fatalf("IngressPolicyNames should have ended as %s but was %s", endPolicy, nowPolicy) + if nowPolicy := retriever(); !reflect.DeepEqual(nowPolicy, endPolicy) { + t.Fatalf("%s should have ended as %s but was %s", key, endPolicy, nowPolicy) } } -func TestEgressPolicyNames(t *testing.T) { - endPolicy := []string{"foo"} - invalidMessage := - &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: EgressPolicyNamesKey, - Value: []byte("Garbage Data"), - } - validMessage := &cb.ConfigurationItem{ - Type: cb.ConfigurationItem_Orderer, - Key: EgressPolicyNamesKey, - Value: utils.MarshalOrPanic(&ab.EgressPolicyNames{Names: endPolicy}), - } +func TestIngressPolicyNames(t *testing.T) { m := NewManagerImpl() - m.BeginConfig() - - err := m.ProposeConfig(validMessage) - if err != nil { - t.Fatalf("Error applying valid config: %s", err) - } - - m.CommitConfig() - m.BeginConfig() - - err = m.ProposeConfig(invalidMessage) - if err == nil { - t.Fatalf("Should have failed on invalid message") - } - - err = m.ProposeConfig(validMessage) - if err != nil { - t.Fatalf("Error re-applying valid config: %s", err) - } + testPolicyNames(m, IngressPolicyNamesKey, TemplateIngressPolicyNames, m.IngressPolicyNames, t) +} - m.CommitConfig() +func TestEgressPolicyNames(t *testing.T) { + m := NewManagerImpl() + testPolicyNames(m, EgressPolicyNamesKey, TemplateEgressPolicyNames, m.EgressPolicyNames, t) +} - if nowPolicy := m.EgressPolicyNames(); !reflect.DeepEqual(nowPolicy, endPolicy) { - t.Fatalf("EgressPolicyNames should have ended as %s but was %s", endPolicy, nowPolicy) - } +func TestChainCreationPolicyNames(t *testing.T) { + m := NewManagerImpl() + testPolicyNames(m, ChainCreationPolicyNamesKey, TemplateChainCreationPolicyNames, m.ChainCreationPolicyNames, t) } diff --git a/orderer/common/sharedconfig/sharedconfig_util.go b/orderer/common/sharedconfig/sharedconfig_util.go new file mode 100644 index 00000000000..90c3980298f --- /dev/null +++ b/orderer/common/sharedconfig/sharedconfig_util.go @@ -0,0 +1,86 @@ +/* +Copyright IBM Corp. 2017 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 sharedconfig + +import ( + cb "github.com/hyperledger/fabric/protos/common" + ab "github.com/hyperledger/fabric/protos/orderer" + "github.com/hyperledger/fabric/protos/utils" +) + +// TemplateConsensusType creates a headerless configuration item representing the consensus type +func TemplateConsensusType(typeValue string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: ConsensusTypeKey, + Value: utils.MarshalOrPanic(&ab.ConsensusType{Type: typeValue}), + } +} + +// TemplateBatchSize creates a headerless configuration item representing the batch size +func TemplateBatchSize(batchSize *ab.BatchSize) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: BatchSizeKey, + Value: utils.MarshalOrPanic(batchSize), + } +} + +// TemplateBatchTimeout creates a headerless configuration item representing the batch timeout +func TemplateBatchTimeout(batchTimeout string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: BatchTimeoutKey, + Value: utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: batchTimeout}), + } +} + +// TemplateChainCreationPolicyNames creates a headerless configuraiton item representing the chain creation policy names +func TemplateChainCreationPolicyNames(names []string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: ChainCreationPolicyNamesKey, + Value: utils.MarshalOrPanic(&ab.ChainCreationPolicyNames{Names: names}), + } +} + +// TemplateIngressPolicyNames creates a headerless configuration item representing the ingress policy names +func TemplateIngressPolicyNames(names []string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: IngressPolicyNamesKey, + Value: utils.MarshalOrPanic(&ab.IngressPolicyNames{Names: names}), + } +} + +// TemplateEgressPolicyNames creates a headerless configuration item representing the egress policy names +func TemplateEgressPolicyNames(names []string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: EgressPolicyNamesKey, + Value: utils.MarshalOrPanic(&ab.EgressPolicyNames{Names: names}), + } +} + +// TemplateKafkaBrokers creates a headerless configuration item representing the kafka brokers +func TemplateKafkaBrokers(brokers []string) *cb.ConfigurationItem { + return &cb.ConfigurationItem{ + Type: cb.ConfigurationItem_Orderer, + Key: KafkaBrokersKey, + Value: utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: brokers}), + } +}