From 71a3389fd15aea469b0940c0dcd252440825be75 Mon Sep 17 00:00:00 2001 From: Kostas Christidis Date: Sat, 10 Dec 2016 22:53:39 -0500 Subject: [PATCH] [FAB-1364] Switch to provisional bootstrapper https://jira.hyperledger.org/browse/FAB-1364 All consenters read several of their config settings (think sharedconfig) from the genesis block that is generated by a bootstrapper. The only bootstrapper available so far is the static one. However, when testing we need to be able to modify several of these config values on the fly. Therefore the bootstrapper should be able to read a config object (which is itself created by reading the orderer.yaml file and -if set- its associated ENV vars). An example of that would be the KafkaBrokers value. For unit tests the "right" value is "127.0.0.1:9092", whereas for the current Docker Compose-based BDD tests the right value is "kafka0:9092". Since this bootstrapper is no longer static, renaming the package seemed appropriate. For production we will need to introduce file-based bootstrapper that reads the genesis block created by the genesis block tool. This changeset allows the bootstrapper to generate the appropriate genesis blocks (with their own custom keys) for all know consenters types: solo, kafka, sbft (though sbft for now just short-circuits to the solo case). The new bootstrapper is built in a way that makes further extensions easier, and minimizes code duplication by creating the appropriate structs and doing the necessary embeddings. The test that inspected the block's Data field was removed. It was a tautological test, serving no good purpose, and was also hard to maintain. Finally, this changeset updates the bootstrap helper signature by removing the error return; while the error return can be useful if the expectation is that the caller will be able to resort to a different bootstrapper if the first one fails, etc. one could that this amount of flexibility is unnecessary, and complicates the code needlessly. The bootstrapper should simply panic if the wrong settings have been passed to it, and the user should read the fine manual. Change-Id: I6aef9b19dbf9a39652d2d6b3ccbefc794e3001df Signed-off-by: Kostas Christidis --- orderer/common/bootstrap/bootstrap.go | 7 +- .../common/bootstrap/provisional/envelope.go | 43 +++++ orderer/common/bootstrap/provisional/item.go | 87 +++++++++ .../bootstrap/provisional/provisional.go | 122 +++++++++++++ .../bootstrap/provisional/provisional_test.go | 57 ++++++ orderer/common/bootstrap/static/static.go | 148 --------------- .../common/bootstrap/static/static_test.go | 169 ------------------ orderer/common/deliver/deliver_test.go | 10 +- orderer/kafka/broadcast.go | 6 +- orderer/kafka/broadcast_mock_test.go | 4 +- orderer/kafka/chain_partition_test.go | 6 +- orderer/kafka/config_test.go | 2 +- orderer/kafka/partitioner_test.go | 4 +- orderer/localconfig/config.go | 2 +- orderer/main.go | 20 +-- orderer/multichain/manager.go | 4 +- orderer/multichain/manager_test.go | 48 ++--- orderer/multichain/systemchain_test.go | 22 +-- orderer/orderer.yaml | 2 +- .../rawledger/fileledger/fileledger_test.go | 10 +- orderer/rawledger/fileledger_test.go | 11 +- orderer/rawledger/ramledger/ramledger_test.go | 10 +- .../sample_clients/bd_counter/broadcast.go | 4 +- orderer/sample_clients/bd_counter/deliver.go | 4 +- .../broadcast_config/newchain.go | 12 +- .../broadcast_timestamp/client.go | 8 +- .../sample_clients/deliver_stdout/client.go | 4 +- .../single_tx_client/single_tx_client.go | 6 +- orderer/sbft/backend/backend_test.go | 10 +- orderer/sbft/main.go | 11 +- orderer/sbft/sbft_test.go | 4 +- 31 files changed, 412 insertions(+), 445 deletions(-) create mode 100644 orderer/common/bootstrap/provisional/envelope.go create mode 100644 orderer/common/bootstrap/provisional/item.go create mode 100644 orderer/common/bootstrap/provisional/provisional.go create mode 100644 orderer/common/bootstrap/provisional/provisional_test.go delete mode 100644 orderer/common/bootstrap/static/static.go delete mode 100644 orderer/common/bootstrap/static/static_test.go diff --git a/orderer/common/bootstrap/bootstrap.go b/orderer/common/bootstrap/bootstrap.go index 615c5d79d31..47535f51c01 100644 --- a/orderer/common/bootstrap/bootstrap.go +++ b/orderer/common/bootstrap/bootstrap.go @@ -20,8 +20,9 @@ import ( ab "github.com/hyperledger/fabric/protos/common" ) -// Helper defines the functions a bootstrapping implementation to provide +// Helper defines the functions a bootstrapping implementation should provide. type Helper interface { - // GenesisBlock should return the genesis block required to bootstrap the ledger (be it reading from the filesystem, generating it, etc.) - GenesisBlock() (*ab.Block, error) + // GenesisBlock should return the genesis block required to bootstrap + // the ledger (be it reading from the filesystem, generating it, etc.) + GenesisBlock() *ab.Block } diff --git a/orderer/common/bootstrap/provisional/envelope.go b/orderer/common/bootstrap/provisional/envelope.go new file mode 100644 index 00000000000..e0eeabe3918 --- /dev/null +++ b/orderer/common/bootstrap/provisional/envelope.go @@ -0,0 +1,43 @@ +/* +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 provisional + +import ( + cb "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/utils" +) + +func (cbs *commonBootstrapper) makeGenesisConfigEnvelope() *cb.ConfigurationEnvelope { + return utils.MakeConfigurationEnvelope( + cbs.encodeConsensusType(), + cbs.encodeBatchSize(), + cbs.encodeChainCreators(), + cbs.encodeAcceptAllPolicy(), + cbs.lockDefaultModificationPolicy(), + ) +} + +func (kbs *kafkaBootstrapper) makeGenesisConfigEnvelope() *cb.ConfigurationEnvelope { + return utils.MakeConfigurationEnvelope( + kbs.encodeConsensusType(), + kbs.encodeBatchSize(), + kbs.encodeKafkaBrokers(), + kbs.encodeChainCreators(), + kbs.encodeAcceptAllPolicy(), + kbs.lockDefaultModificationPolicy(), + ) +} diff --git a/orderer/common/bootstrap/provisional/item.go b/orderer/common/bootstrap/provisional/item.go new file mode 100644 index 00000000000..014311fff9e --- /dev/null +++ b/orderer/common/bootstrap/provisional/item.go @@ -0,0 +1,87 @@ +/* +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 provisional + +import ( + "github.com/hyperledger/fabric/common/cauthdsl" + "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) encodeConsensusType() *cb.SignedConfigurationItem { + configItemKey := sharedconfig.ConsensusTypeKey + configItemValue := utils.MarshalOrPanic(&ab.ConsensusType{Type: cbs.consensusType}) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} + +func (cbs *commonBootstrapper) encodeBatchSize() *cb.SignedConfigurationItem { + configItemKey := sharedconfig.BatchSizeKey + configItemValue := utils.MarshalOrPanic(&ab.BatchSize{Messages: cbs.batchSize}) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} + +func (cbs *commonBootstrapper) encodeChainCreators() *cb.SignedConfigurationItem { + configItemKey := sharedconfig.ChainCreatorsKey + configItemValue := utils.MarshalOrPanic(&ab.ChainCreators{Policies: DefaultChainCreators}) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} + +func (cbs *commonBootstrapper) encodeAcceptAllPolicy() *cb.SignedConfigurationItem { + configItemKey := AcceptAllPolicyKey + configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.AcceptAllPolicy)) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} + +func (cbs *commonBootstrapper) lockDefaultModificationPolicy() *cb.SignedConfigurationItem { + // Lock down the default modification policy to prevent any further policy modifications + configItemKey := configtx.DefaultModificationPolicyID + configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.RejectAllPolicy)) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} + +func (kbs *kafkaBootstrapper) encodeKafkaBrokers() *cb.SignedConfigurationItem { + configItemKey := sharedconfig.KafkaBrokersKey + configItemValue := utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: kbs.kafkaBrokers}) + modPolicy := configtx.DefaultModificationPolicyID + + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, kbs.chainID, epoch) + configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue) + return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} +} diff --git a/orderer/common/bootstrap/provisional/provisional.go b/orderer/common/bootstrap/provisional/provisional.go new file mode 100644 index 00000000000..224ee1bf5f2 --- /dev/null +++ b/orderer/common/bootstrap/provisional/provisional.go @@ -0,0 +1,122 @@ +/* +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 provisional + +import ( + "fmt" + + "github.com/hyperledger/fabric/orderer/common/bootstrap" + "github.com/hyperledger/fabric/orderer/localconfig" + cb "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/utils" +) + +const ( + msgVersion = int32(1) + + // ConsensusTypeSolo identifies the solo consensus implementation. + ConsensusTypeSolo = "solo" + // ConsensusTypeKafka identifies the Kafka-based consensus implementation. + ConsensusTypeKafka = "kafka" + // ConsensusTypeSbft identifies the SBFT consensus implementation. + ConsensusTypeSbft = "sbft" + + // TestChainID is the default value of ChainID. It is used by all testing + // networks. It it necessary to set and export this variable so that test + // clients can connect without being rejected for targetting a chain which + // does not exist. + TestChainID = "**TEST_CHAINID**" + + // AcceptAllPolicyKey is the key of the AcceptAllPolicy. + AcceptAllPolicyKey = "AcceptAllPolicy" + + // These values are fixed for the genesis block. + lastModified = 0 + epoch = 0 +) + +// DefaultChainCreators is the default value of ChainCreatorsKey. +var DefaultChainCreators = []string{AcceptAllPolicyKey} + +type commonBootstrapper struct { + chainID string + consensusType string + batchSize uint32 +} + +type soloBootstrapper struct { + commonBootstrapper +} + +type kafkaBootstrapper struct { + commonBootstrapper + kafkaBrokers []string +} + +// New returns a new provisional bootstrap helper. +func New(conf *config.TopLevel) bootstrap.Helper { + cbs := &commonBootstrapper{ + chainID: TestChainID, + consensusType: conf.General.OrdererType, + batchSize: conf.General.BatchSize, + } + + switch conf.General.OrdererType { + case ConsensusTypeSolo, ConsensusTypeSbft: + return &soloBootstrapper{ + commonBootstrapper: *cbs, + } + case ConsensusTypeKafka: + return &kafkaBootstrapper{ + commonBootstrapper: *cbs, + kafkaBrokers: conf.Kafka.Brokers, + } + default: + panic(fmt.Errorf("Wrong consenter type value given: %s", conf.General.OrdererType)) + } +} + +// GenesisBlock returns the genesis block to be used for bootstrapping. +func (cbs *commonBootstrapper) GenesisBlock() *cb.Block { + return cbs.makeGenesisBlock(cbs.makeGenesisConfigEnvelope()) +} + +// GenesisBlock returns the genesis block to be used for bootstrapping. +func (kbs *kafkaBootstrapper) GenesisBlock() *cb.Block { + return kbs.makeGenesisBlock(kbs.makeGenesisConfigEnvelope()) +} + +func (cbs *commonBootstrapper) makeGenesisBlock(configEnvelope *cb.ConfigurationEnvelope) *cb.Block { + configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch) + payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, configItemChainHeader.Version, cbs.chainID, epoch) + payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic()) + payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader) + payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(configEnvelope)} + envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil} + + blockData := &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}} + + return &cb.Block{ + Header: &cb.BlockHeader{ + Number: 0, + PreviousHash: nil, + DataHash: blockData.Hash(), + }, + Data: blockData, + Metadata: nil, + } +} diff --git a/orderer/common/bootstrap/provisional/provisional_test.go b/orderer/common/bootstrap/provisional/provisional_test.go new file mode 100644 index 00000000000..2e3d83bd35e --- /dev/null +++ b/orderer/common/bootstrap/provisional/provisional_test.go @@ -0,0 +1,57 @@ +/* +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 provisional + +import ( + "bytes" + "testing" + + "github.com/hyperledger/fabric/orderer/localconfig" +) + +var confSolo, confKafka *config.TopLevel +var testCases []*config.TopLevel + +func init() { + confSolo = config.Load() + confKafka = config.Load() + confKafka.General.OrdererType = ConsensusTypeKafka + testCases = []*config.TopLevel{confSolo, confKafka} +} + +func TestGenesisBlockHeader(t *testing.T) { + expectedHeaderNumber := uint64(0) + + for _, tc := range testCases { + genesisBlock := New(tc).GenesisBlock() + if genesisBlock.Header.Number != expectedHeaderNumber { + t.Fatalf("Case %s: Expected header number %d, got %d", tc.General.OrdererType, expectedHeaderNumber, genesisBlock.Header.Number) + } + if !bytes.Equal(genesisBlock.Header.PreviousHash, nil) { + t.Fatalf("Case %s: Expected header previousHash to be nil, got %x", tc.General.OrdererType, genesisBlock.Header.PreviousHash) + } + } +} + +func TestGenesisMetadata(t *testing.T) { + for _, tc := range testCases { + genesisBlock := New(tc).GenesisBlock() + if genesisBlock.Metadata != nil { + t.Fatalf("Expected metadata nil, got %x", genesisBlock.Metadata) + } + } +} diff --git a/orderer/common/bootstrap/static/static.go b/orderer/common/bootstrap/static/static.go deleted file mode 100644 index 22a7a1a3678..00000000000 --- a/orderer/common/bootstrap/static/static.go +++ /dev/null @@ -1,148 +0,0 @@ -/* -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 static - -import ( - "github.com/hyperledger/fabric/common/cauthdsl" - "github.com/hyperledger/fabric/common/configtx" - "github.com/hyperledger/fabric/orderer/common/bootstrap" - "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" -) - -// TestChainID is the default chain ID which is used by all statically bootstrapped networks -// This is necessary to allow test clients to connect without being rejected for targetting -// a chain which does not exist -const TestChainID = "**TEST_CHAINID**" - -const msgVersion = int32(1) - -type bootstrapper struct { - chainID string - lastModified uint64 - epoch uint64 - consensusType string - batchSize uint32 -} - -const ( - // DefaultBatchSize is the default value of BatchSizeKey - DefaultBatchSize = 10 - - // DefaultConsensusType is the default value of ConsensusTypeKey - DefaultConsensusType = "solo" - - // AcceptAllPolicyKey is the key of the AcceptAllPolicy - AcceptAllPolicyKey = "AcceptAllPolicy" -) - -var ( - // DefaultChainCreators is the default value of ChainCreatorsKey - DefaultChainCreators = []string{AcceptAllPolicyKey} -) - -// New returns a new static bootstrap helper. -func New() bootstrap.Helper { - return &bootstrapper{ - chainID: TestChainID, - consensusType: DefaultConsensusType, - batchSize: DefaultBatchSize, - } -} - -func (b *bootstrapper) encodeConsensusType() *cb.SignedConfigurationItem { - configItemKey := sharedconfig.ConsensusTypeKey - configItemValue := utils.MarshalOrPanic(&ab.ConsensusType{Type: b.consensusType}) - modPolicy := configtx.DefaultModificationPolicyID - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, b.lastModified, modPolicy, configItemKey, configItemValue) - return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} -} - -func (b *bootstrapper) encodeBatchSize() *cb.SignedConfigurationItem { - configItemKey := sharedconfig.BatchSizeKey - configItemValue := utils.MarshalOrPanic(&ab.BatchSize{Messages: b.batchSize}) - modPolicy := configtx.DefaultModificationPolicyID - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, b.lastModified, modPolicy, configItemKey, configItemValue) - return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} -} - -func (b *bootstrapper) encodeChainCreators() *cb.SignedConfigurationItem { - configItemKey := sharedconfig.ChainCreatorsKey - configItemValue := utils.MarshalOrPanic(&ab.ChainCreators{Policies: DefaultChainCreators}) - modPolicy := configtx.DefaultModificationPolicyID - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, b.lastModified, modPolicy, configItemKey, configItemValue) - return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} -} - -func (b *bootstrapper) encodeAcceptAllPolicy() *cb.SignedConfigurationItem { - configItemKey := AcceptAllPolicyKey - configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.AcceptAllPolicy)) - modPolicy := configtx.DefaultModificationPolicyID - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, b.lastModified, modPolicy, configItemKey, configItemValue) - return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} -} - -func (b *bootstrapper) lockDefaultModificationPolicy() *cb.SignedConfigurationItem { - // Lock down the default modification policy to prevent any further policy modifications - configItemKey := configtx.DefaultModificationPolicyID - configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.RejectAllPolicy)) - modPolicy := configtx.DefaultModificationPolicyID - - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, b.lastModified, modPolicy, configItemKey, configItemValue) - return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil} -} - -// GenesisBlock returns the genesis block to be used for bootstrapping -func (b *bootstrapper) GenesisBlock() (*cb.Block, error) { - configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, b.chainID, b.epoch) - - configEnvelope := utils.MakeConfigurationEnvelope( - b.encodeConsensusType(), - b.encodeBatchSize(), - b.encodeChainCreators(), - b.encodeAcceptAllPolicy(), - b.lockDefaultModificationPolicy(), - ) - payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, configItemChainHeader.Version, b.chainID, b.epoch) - payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic()) - payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader) - payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(configEnvelope)} - envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil} - - blockData := &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}} - - return &cb.Block{ - Header: &cb.BlockHeader{ - Number: 0, - PreviousHash: nil, - DataHash: blockData.Hash(), - }, - Data: blockData, - Metadata: nil, - }, nil -} diff --git a/orderer/common/bootstrap/static/static_test.go b/orderer/common/bootstrap/static/static_test.go deleted file mode 100644 index 25187dae4db..00000000000 --- a/orderer/common/bootstrap/static/static_test.go +++ /dev/null @@ -1,169 +0,0 @@ -/* -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 static - -import ( - "bytes" - "testing" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/common/cauthdsl" - "github.com/hyperledger/fabric/common/configtx" - cb "github.com/hyperledger/fabric/protos/common" - "github.com/hyperledger/fabric/protos/utils" -) - -func TestGenesisBlockCreation(t *testing.T) { - _, err := New().GenesisBlock() - if err != nil { - t.Fatalf("Cannot create genesis block: %s", err) - } -} - -func TestGenesisBlockHeader(t *testing.T) { - expectedHeaderNumber := uint64(0) - - genesisBlock, _ := New().GenesisBlock() // The error has been checked in a previous test - - if genesisBlock.Header.Number != expectedHeaderNumber { - t.Fatalf("Expected header number %d, got %d", expectedHeaderNumber, genesisBlock.Header.Number) - } - - if !bytes.Equal(genesisBlock.Header.PreviousHash, nil) { - t.Fatalf("Expected header previousHash to be nil, got %x", genesisBlock.Header.PreviousHash) - } -} - -func TestGenesisBlockData(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Fatalf("OrPanicked unexpectedly: %s", r) - } - }() - - expectedBlockDataLength := 1 - expectedPayloadChainHeaderType := int32(cb.HeaderType_CONFIGURATION_TRANSACTION) - expectedChainHeaderVersion := msgVersion - expectedChainHeaderEpoch := uint64(0) - expectedConfigEnvelopeItemsLength := 5 - expectedConfigurationItemChainHeaderType := int32(cb.HeaderType_CONFIGURATION_ITEM) - expectedConfigurationItemChainHeaderVersion := msgVersion - expectedConfigurationItemType := cb.ConfigurationItem_Policy - expectedConfigEnvelopeSequence := uint64(0) - expectedConfigurationItemModificationPolicy := configtx.DefaultModificationPolicyID - expectedConfigurationItemValueSignaturePolicyEnvelope := cauthdsl.RejectAllPolicy - - genesisBlock, _ := New().GenesisBlock() // The error has been checked in a previous test - - if len(genesisBlock.Data.Data) != expectedBlockDataLength { - t.Fatalf("Expected genesis block data length %d, got %d", expectedBlockDataLength, len(genesisBlock.Data.Data)) - } - - envelope := utils.ExtractEnvelopeOrPanic(genesisBlock, 0) - - envelopeSignature := envelope.Signature - if !bytes.Equal(envelopeSignature, nil) { - t.Fatalf("Expected envelope signature to be nil, got %x", envelopeSignature) - } - - payload := utils.ExtractPayloadOrPanic(envelope) - - signatureHeader := payload.Header.SignatureHeader - if !bytes.Equal(signatureHeader.Creator, nil) { - t.Fatalf("Expected payload signature header creator to be nil, got %x", signatureHeader.Creator) - } - if bytes.Equal(signatureHeader.Nonce, nil) { - t.Fatal("Expected non-nil nonce") - } - - payloadChainHeader := payload.Header.ChainHeader - if payloadChainHeader.Type != expectedPayloadChainHeaderType { - t.Fatalf("Expected payload chain header type %d, got %d", expectedPayloadChainHeaderType, payloadChainHeader.Type) - } - if payloadChainHeader.Version != expectedChainHeaderVersion { - t.Fatalf("Expected payload chain header version %d, got %d", expectedChainHeaderVersion, payloadChainHeader.Version) - } - if payloadChainHeader.Epoch != expectedChainHeaderEpoch { - t.Fatalf("Expected payload chain header header epoch to be %d, got %d", expectedChainHeaderEpoch, payloadChainHeader.Epoch) - } - - marshaledConfigurationEnvelope := payload.Data - configurationEnvelope := &cb.ConfigurationEnvelope{} - if err := proto.Unmarshal(marshaledConfigurationEnvelope, configurationEnvelope); err != nil { - t.Fatalf("Expected genesis block to carry a ConfigurationEnvelope") - } - if len(configurationEnvelope.Items) != expectedConfigEnvelopeItemsLength { - t.Fatalf("Expected configuration envelope to have %d configuration item(s), got %d", expectedConfigEnvelopeItemsLength, len(configurationEnvelope.Items)) - } - - signedConfigurationItem := configurationEnvelope.Items[4] - marshaledConfigurationItem := signedConfigurationItem.ConfigurationItem - configurationItem := &cb.ConfigurationItem{} - if err := proto.Unmarshal(marshaledConfigurationItem, configurationItem); err != nil { - t.Fatalf("Expected genesis block to carry a ConfigurationItem") - } - - configurationItemChainHeader := configurationItem.Header - if configurationItemChainHeader.Type != expectedConfigurationItemChainHeaderType { - t.Fatalf("Expected configuration item chain header type %d, got %d", expectedConfigurationItemChainHeaderType, configurationItemChainHeader.Type) - } - if configurationItemChainHeader.Version != expectedConfigurationItemChainHeaderVersion { - t.Fatalf("Expected configuration item chain header version %d, got %d", expectedConfigurationItemChainHeaderVersion, configurationItemChainHeader.Version) - } - if configurationItemChainHeader.ChainID != payloadChainHeader.ChainID { - t.Fatalf("Expected chain ID in chain headers of configuration item and payload to match, got %x and %x respectively", configurationItemChainHeader.ChainID, payloadChainHeader.ChainID) - } - if configurationItemChainHeader.Epoch != payloadChainHeader.Epoch { - t.Fatalf("Expected epoch in chain headers of configuration item and payload to match, got %d, and %d respectively", configurationItemChainHeader.Epoch, payloadChainHeader.Epoch) - } - - if configurationItem.Type != expectedConfigurationItemType { - t.Fatalf("Expected configuration item type %s, got %s", expectedConfigurationItemType.String(), configurationItem.Type.String()) - } - if configurationItem.LastModified != expectedConfigEnvelopeSequence { - t.Fatalf("Expected configuration item sequence to match configuration envelope sequence %d, got %d", expectedConfigEnvelopeSequence, configurationItem.LastModified) - } - if configurationItem.ModificationPolicy != expectedConfigurationItemModificationPolicy { - t.Fatalf("Expected configuration item modification policy %s, got %s", expectedConfigurationItemModificationPolicy, configurationItem.ModificationPolicy) - } - if configurationItem.Key != expectedConfigurationItemModificationPolicy { - t.Fatalf("Expected configuration item key to be equal to the modification policy %s, got %s", expectedConfigurationItemModificationPolicy, configurationItem.Key) - } - - marshaledPolicy := configurationItem.Value - policy := &cb.Policy{} - if err := proto.Unmarshal(marshaledPolicy, policy); err != nil { - t.Fatalf("Expected genesis block to carry a policy in its configuration item value") - } - switch policy.GetType().(type) { - case *cb.Policy_SignaturePolicy: - default: - t.Fatalf("Got unexpected configuration item value policy type") - } - signaturePolicyEnvelope := policy.GetSignaturePolicy() - if !proto.Equal(signaturePolicyEnvelope, expectedConfigurationItemValueSignaturePolicyEnvelope) { - t.Fatalf("Expected configuration item value signature policy envelope %s, got %s", expectedConfigurationItemValueSignaturePolicyEnvelope.String(), signaturePolicyEnvelope.String()) - } -} - -func TestGenesisMetadata(t *testing.T) { - genesisBlock, _ := New().GenesisBlock() // The error has been checked in a previous test - - if genesisBlock.Metadata != nil { - t.Fatalf("Expected metadata nil, got %x", genesisBlock.Metadata) - } -} diff --git a/orderer/common/deliver/deliver_test.go b/orderer/common/deliver/deliver_test.go index 2670f90478e..fb6a861af58 100644 --- a/orderer/common/deliver/deliver_test.go +++ b/orderer/common/deliver/deliver_test.go @@ -22,7 +22,8 @@ import ( "time" "github.com/hyperledger/fabric/common/policies" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" "github.com/hyperledger/fabric/orderer/rawledger" "github.com/hyperledger/fabric/orderer/rawledger/ramledger" cb "github.com/hyperledger/fabric/protos/common" @@ -38,12 +39,7 @@ var systemChainID = "systemChain" const ledgerSize = 10 func init() { - bootstrapper := static.New() - var err error - genesisBlock, err = bootstrapper.GenesisBlock() - if err != nil { - panic("Error intializing static bootstrap genesis block") - } + genesisBlock = provisional.New(config.Load()).GenesisBlock() } // MagicLargestWindow is used as the default max window size for initializing the deliver service diff --git a/orderer/kafka/broadcast.go b/orderer/kafka/broadcast.go index c24f5f64dc2..39354ffab65 100644 --- a/orderer/kafka/broadcast.go +++ b/orderer/kafka/broadcast.go @@ -21,7 +21,7 @@ import ( "sync" "time" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -47,13 +47,11 @@ type broadcasterImpl struct { } func newBroadcaster(conf *config.TopLevel) Broadcaster { - genesisBlock, _ := static.New().GenesisBlock() - b := &broadcasterImpl{ producer: newProducer(conf), config: conf, batchChan: make(chan *cb.Envelope, conf.General.BatchSize), - messages: genesisBlock.GetData().Data, + messages: provisional.New(conf).GenesisBlock().GetData().Data, nextNumber: 0, } diff --git a/orderer/kafka/broadcast_mock_test.go b/orderer/kafka/broadcast_mock_test.go index 5eda1a29975..891f9916425 100644 --- a/orderer/kafka/broadcast_mock_test.go +++ b/orderer/kafka/broadcast_mock_test.go @@ -20,7 +20,7 @@ import ( "fmt" "testing" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" @@ -28,7 +28,7 @@ import ( ) func mockNewBroadcaster(t *testing.T, conf *config.TopLevel, seek int64, disk chan []byte) Broadcaster { - genesisBlock, _ := static.New().GenesisBlock() + genesisBlock := provisional.New(conf).GenesisBlock() wait := make(chan struct{}) mb := &broadcasterImpl{ diff --git a/orderer/kafka/chain_partition_test.go b/orderer/kafka/chain_partition_test.go index 8830d4b9777..982f1662b4a 100644 --- a/orderer/kafka/chain_partition_test.go +++ b/orderer/kafka/chain_partition_test.go @@ -21,13 +21,13 @@ import ( "strings" "testing" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" ) func TestChainPartition(t *testing.T) { - cp := newChainPartition(static.TestChainID, rawPartition) + cp := newChainPartition(provisional.TestChainID, rawPartition) - expectedTopic := fmt.Sprintf("%x", static.TestChainID) + expectedTopic := fmt.Sprintf("%x", provisional.TestChainID) actualTopic := cp.Topic() if strings.Compare(expectedTopic, actualTopic) != 0 { t.Fatalf("Got the wrong topic, expected %s, got %s instead", expectedTopic, actualTopic) diff --git a/orderer/kafka/config_test.go b/orderer/kafka/config_test.go index 6da59bd841e..3bd460583b8 100644 --- a/orderer/kafka/config_test.go +++ b/orderer/kafka/config_test.go @@ -48,7 +48,7 @@ var testConf = &config.TopLevel{ MaxWindowSize: 100, ListenAddress: "127.0.0.1", ListenPort: 7050, - GenesisMethod: "static", + GenesisMethod: "provisional", }, Kafka: config.Kafka{ Brokers: []string{"127.0.0.1:9092"}, diff --git a/orderer/kafka/partitioner_test.go b/orderer/kafka/partitioner_test.go index f45e5a86404..258cfcfb10a 100644 --- a/orderer/kafka/partitioner_test.go +++ b/orderer/kafka/partitioner_test.go @@ -20,7 +20,7 @@ import ( "testing" "github.com/Shopify/sarama" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" ) func TestStaticPartitioner(t *testing.T) { @@ -28,7 +28,7 @@ func TestStaticPartitioner(t *testing.T) { var numberOfPartitions int32 = 6 partitionerConstructor := newStaticPartitioner(partition) - partitioner := partitionerConstructor(static.TestChainID) + partitioner := partitionerConstructor(provisional.TestChainID) for i := 0; i < 10; i++ { assignedPartition, err := partitioner.Partition(new(sarama.ProducerMessage), numberOfPartitions) diff --git a/orderer/localconfig/config.go b/orderer/localconfig/config.go index 470b0b3ea41..7be925fe91d 100644 --- a/orderer/localconfig/config.go +++ b/orderer/localconfig/config.go @@ -106,7 +106,7 @@ var defaults = TopLevel{ MaxWindowSize: 1000, ListenAddress: "127.0.0.1", ListenPort: 7050, - GenesisMethod: "static", + GenesisMethod: "provisional", Profile: Profile{ Enabled: false, Address: "0.0.0.0:6060", diff --git a/orderer/main.go b/orderer/main.go index 4470ced7f68..d06327f09b7 100644 --- a/orderer/main.go +++ b/orderer/main.go @@ -26,8 +26,7 @@ import ( "os" "os/signal" - "github.com/hyperledger/fabric/orderer/common/bootstrap" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/kafka" "github.com/hyperledger/fabric/orderer/localconfig" "github.com/hyperledger/fabric/orderer/multichain" @@ -35,6 +34,7 @@ import ( "github.com/hyperledger/fabric/orderer/rawledger/fileledger" "github.com/hyperledger/fabric/orderer/rawledger/ramledger" "github.com/hyperledger/fabric/orderer/solo" + cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" "github.com/Shopify/sarama" @@ -79,26 +79,18 @@ func launchGeneric(conf *config.TopLevel) { return } - var bootstrapper bootstrap.Helper + var genesisBlock *cb.Block // Select the bootstrapping mechanism switch conf.General.GenesisMethod { - case "static": - bootstrapper = static.New() + case "provisional": + genesisBlock = provisional.New(conf).GenesisBlock() default: panic(fmt.Errorf("Unknown genesis method %s", conf.General.GenesisMethod)) } - genesisBlock, err := bootstrapper.GenesisBlock() - - if err != nil { - panic(fmt.Errorf("Error retrieving the genesis block %s", err)) - } - - // Stand in until real config - ledgerType := os.Getenv("ORDERER_LEDGER_TYPE") var lf rawledger.Factory - switch ledgerType { + switch conf.General.LedgerType { case "file": location := conf.FileLedger.Location if location == "" { diff --git a/orderer/multichain/manager.go b/orderer/multichain/manager.go index 332c6d1bf8c..d7440664a7f 100644 --- a/orderer/multichain/manager.go +++ b/orderer/multichain/manager.go @@ -90,7 +90,9 @@ func getConfigTx(reader rawledger.Reader) *cb.Envelope { } payload := &cb.Payload{} - err = proto.Unmarshal(maybeConfigTx.Payload, payload) + if err = proto.Unmarshal(maybeConfigTx.Payload, payload); err != nil { + logger.Fatalf("Unable to unmarshal transaction payload: %s", err) + } if payload.Header.ChainHeader.Type != int32(cb.HeaderType_CONFIGURATION_TRANSACTION) { continue diff --git a/orderer/multichain/manager_test.go b/orderer/multichain/manager_test.go index 574fc1bf2f4..3aebe20c728 100644 --- a/orderer/multichain/manager_test.go +++ b/orderer/multichain/manager_test.go @@ -22,21 +22,20 @@ import ( "testing" "time" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" "github.com/hyperledger/fabric/orderer/rawledger/ramledger" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" "github.com/hyperledger/fabric/protos/utils" ) +var conf *config.TopLevel var genesisBlock *cb.Block func init() { - var err error - genesisBlock, err = static.New().GenesisBlock() - if err != nil { - panic(err) - } + conf = config.Load() + genesisBlock = provisional.New(conf).GenesisBlock() } // TODO move to util @@ -59,12 +58,12 @@ func makeNormalTx(chainID string, i int) *cb.Envelope { func TestGetConfigTx(t *testing.T) { _, rl := ramledger.New(10, genesisBlock) for i := 0; i < 5; i++ { - rl.Append([]*cb.Envelope{makeNormalTx(static.TestChainID, i)}, nil) + rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, i)}, nil) } - rl.Append([]*cb.Envelope{makeConfigTx(static.TestChainID, 5)}, nil) - ctx := makeConfigTx(static.TestChainID, 6) + rl.Append([]*cb.Envelope{makeConfigTx(provisional.TestChainID, 5)}, nil) + ctx := makeConfigTx(provisional.TestChainID, 6) rl.Append([]*cb.Envelope{ctx}, nil) - rl.Append([]*cb.Envelope{makeNormalTx(static.TestChainID, 7)}, nil) + rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, 7)}, nil) pctx := getConfigTx(rl) @@ -78,11 +77,11 @@ func TestGetConfigTxFailure(t *testing.T) { _, rl := ramledger.New(10, genesisBlock) for i := 0; i < 10; i++ { rl.Append([]*cb.Envelope{ - makeNormalTx(static.TestChainID, i), - makeConfigTx(static.TestChainID, i), + makeNormalTx(provisional.TestChainID, i), + makeConfigTx(provisional.TestChainID, i), }, nil) } - rl.Append([]*cb.Envelope{makeNormalTx(static.TestChainID, 11)}, nil) + rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, 11)}, nil) pctx := getConfigTx(rl) if pctx != nil { @@ -95,7 +94,7 @@ func TestManagerImpl(t *testing.T) { lf, rl := ramledger.New(10, genesisBlock) consenters := make(map[string]Consenter) - consenters[static.DefaultConsensusType] = &mockConsenter{} + consenters[conf.General.OrdererType] = &mockConsenter{} manager := NewManagerImpl(lf, consenters) @@ -104,15 +103,15 @@ func TestManagerImpl(t *testing.T) { t.Errorf("Should not have found a chain that was not created") } - chainSupport, ok := manager.GetChain(static.TestChainID) + chainSupport, ok := manager.GetChain(provisional.TestChainID) if !ok { t.Fatalf("Should have gotten chain which was initialized by ramledger") } - messages := make([]*cb.Envelope, static.DefaultBatchSize) - for i := 0; i < static.DefaultBatchSize; i++ { - messages[i] = makeNormalTx(static.TestChainID, i) + messages := make([]*cb.Envelope, conf.General.BatchSize) + for i := 0; i < int(conf.General.BatchSize); i++ { + messages[i] = makeNormalTx(provisional.TestChainID, i) } for _, message := range messages { @@ -126,7 +125,7 @@ func TestManagerImpl(t *testing.T) { if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve block") } - for i := 0; i < static.DefaultBatchSize; i++ { + for i := 0; i < int(conf.General.BatchSize); i++ { if !reflect.DeepEqual(utils.ExtractEnvelopeOrPanic(block, i), messages[i]) { t.Errorf("Block contents wrong at index %d", i) } @@ -138,10 +137,11 @@ func TestManagerImpl(t *testing.T) { // This test brings up the entire system, with the mock consenter, including the broadcasters etc. and creates a new chain func TestNewChain(t *testing.T) { + conf := config.Load() lf, rl := ramledger.New(10, genesisBlock) consenters := make(map[string]Consenter) - consenters[static.DefaultConsensusType] = &mockConsenter{} + consenters[conf.General.OrdererType] = &mockConsenter{} manager := NewManagerImpl(lf, consenters) @@ -150,7 +150,7 @@ func TestNewChain(t *testing.T) { oldConfigEnv := utils.UnmarshalConfigurationEnvelopeOrPanic(oldGenesisTxPayload.Data) newChainID := "TestNewChain" - newChainMessage := utils.ChainCreationConfigurationTransaction(static.AcceptAllPolicyKey, newChainID, oldConfigEnv) + newChainMessage := utils.ChainCreationConfigurationTransaction(provisional.AcceptAllPolicyKey, newChainID, oldConfigEnv) status := manager.ProposeChain(newChainMessage) @@ -182,8 +182,8 @@ func TestNewChain(t *testing.T) { t.Fatalf("Should have gotten new chain which was created") } - messages := make([]*cb.Envelope, static.DefaultBatchSize) - for i := 0; i < static.DefaultBatchSize; i++ { + messages := make([]*cb.Envelope, conf.General.BatchSize) + for i := 0; i < int(conf.General.BatchSize); i++ { messages[i] = makeNormalTx(newChainID, i) } @@ -215,7 +215,7 @@ func TestNewChain(t *testing.T) { if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve block on new chain") } - for i := 0; i < static.DefaultBatchSize; i++ { + for i := 0; i < int(conf.General.BatchSize); i++ { if !reflect.DeepEqual(utils.ExtractEnvelopeOrPanic(block, i), messages[i]) { t.Errorf("Block contents wrong at index %d in new chain", i) } diff --git a/orderer/multichain/systemchain_test.go b/orderer/multichain/systemchain_test.go index cd0afa0a84c..63884cdb2d6 100644 --- a/orderer/multichain/systemchain_test.go +++ b/orderer/multichain/systemchain_test.go @@ -22,7 +22,7 @@ import ( "github.com/hyperledger/fabric/common/policies" coreutil "github.com/hyperledger/fabric/core/util" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/common/filter" "github.com/hyperledger/fabric/orderer/common/sharedconfig" cb "github.com/hyperledger/fabric/protos/common" @@ -106,7 +106,7 @@ type mockChainCreator struct { func newMockChainCreator() *mockChainCreator { mcc := &mockChainCreator{ - ms: newMockSupport(static.TestChainID), + ms: newMockSupport(provisional.TestChainID), } mcc.sysChain = newSystemChain(mcc.ms) return mcc @@ -124,7 +124,7 @@ func TestGoodProposal(t *testing.T) { newChainID := "NewChainID" mcc := newMockChainCreator() - mcc.ms.msc.chainCreators = []string{static.AcceptAllPolicyKey} + mcc.ms.msc.chainCreators = []string{provisional.AcceptAllPolicyKey} mcc.ms.mpm.mp = &mockPolicy{} chainCreateTx := &cb.ConfigurationItem{ @@ -135,7 +135,7 @@ func TestGoodProposal(t *testing.T) { Key: utils.CreationPolicyKey, Type: cb.ConfigurationItem_Orderer, Value: utils.MarshalOrPanic(&ab.CreationPolicy{ - Policy: static.AcceptAllPolicyKey, + Policy: provisional.AcceptAllPolicyKey, Digest: coreutil.ComputeCryptoHash([]byte{}), }), } @@ -172,9 +172,8 @@ func TestGoodProposal(t *testing.T) { } committer.Commit() - expected = 1 if len(mcc.newChains) != 1 { - t.Fatalf("Proposal should only have created one new chain") + t.Fatalf("Proposal should only have created 1 new chain") } if !reflect.DeepEqual(mcc.newChains[0], ingressTx) { @@ -191,8 +190,9 @@ func TestProposalWithBadPolicy(t *testing.T) { chainCreateTx := &cb.ConfigurationItem{ Key: utils.CreationPolicyKey, Type: cb.ConfigurationItem_Orderer, + Value: utils.MarshalOrPanic(&ab.CreationPolicy{ - Policy: static.AcceptAllPolicyKey, + Policy: provisional.AcceptAllPolicyKey, Digest: coreutil.ComputeCryptoHash([]byte{}), }), } @@ -209,13 +209,13 @@ func TestProposalWithMissingPolicy(t *testing.T) { newChainID := "NewChainID" mcc := newMockChainCreator() - mcc.ms.msc.chainCreators = []string{static.AcceptAllPolicyKey} + mcc.ms.msc.chainCreators = []string{provisional.AcceptAllPolicyKey} chainCreateTx := &cb.ConfigurationItem{ Key: utils.CreationPolicyKey, Type: cb.ConfigurationItem_Orderer, Value: utils.MarshalOrPanic(&ab.CreationPolicy{ - Policy: static.AcceptAllPolicyKey, + Policy: provisional.AcceptAllPolicyKey, Digest: coreutil.ComputeCryptoHash([]byte{}), }), } @@ -233,13 +233,13 @@ func TestProposalWithBadDigest(t *testing.T) { mcc := newMockChainCreator() mcc.ms.mpm.mp = &mockPolicy{} - mcc.ms.msc.chainCreators = []string{static.AcceptAllPolicyKey} + mcc.ms.msc.chainCreators = []string{provisional.AcceptAllPolicyKey} chainCreateTx := &cb.ConfigurationItem{ Key: utils.CreationPolicyKey, Type: cb.ConfigurationItem_Orderer, Value: utils.MarshalOrPanic(&ab.CreationPolicy{ - Policy: static.AcceptAllPolicyKey, + Policy: provisional.AcceptAllPolicyKey, Digest: coreutil.ComputeCryptoHash([]byte("BAD_DIGEST")), }), } diff --git a/orderer/orderer.yaml b/orderer/orderer.yaml index 103756c325f..685b76e95ad 100644 --- a/orderer/orderer.yaml +++ b/orderer/orderer.yaml @@ -39,7 +39,7 @@ General: ListenPort: 7050 # Genesis method: The method by which to retrieve/generate the genesis block - GenesisMethod: static + GenesisMethod: provisional # Enable an HTTP service for Go "pprof" profiling as documented at # https://golang.org/pkg/net/http/pprof diff --git a/orderer/rawledger/fileledger/fileledger_test.go b/orderer/rawledger/fileledger/fileledger_test.go index 1ef36c8acf8..3cafe1e5a33 100644 --- a/orderer/rawledger/fileledger/fileledger_test.go +++ b/orderer/rawledger/fileledger/fileledger_test.go @@ -22,7 +22,8 @@ import ( "os" "testing" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" ) @@ -30,12 +31,7 @@ import ( var genesisBlock *cb.Block func init() { - bootstrapper := static.New() - var err error - genesisBlock, err = bootstrapper.GenesisBlock() - if err != nil { - panic("Error intializing static bootstrap genesis block") - } + genesisBlock = provisional.New(config.Load()).GenesisBlock() } type testEnv struct { diff --git a/orderer/rawledger/fileledger_test.go b/orderer/rawledger/fileledger_test.go index 4a31d9dcfeb..2e8460bd0c2 100644 --- a/orderer/rawledger/fileledger_test.go +++ b/orderer/rawledger/fileledger_test.go @@ -20,7 +20,8 @@ import ( "io/ioutil" "os" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" . "github.com/hyperledger/fabric/orderer/rawledger" "github.com/hyperledger/fabric/orderer/rawledger/fileledger" cb "github.com/hyperledger/fabric/protos/common" @@ -29,13 +30,7 @@ import ( var genesisBlock *cb.Block func init() { - bootstrapper := static.New() - var err error - genesisBlock, err = bootstrapper.GenesisBlock() - if err != nil { - panic("Error intializing static bootstrap genesis block") - } - + genesisBlock = provisional.New(config.Load()).GenesisBlock() testables = append(testables, &fileLedgerTestEnv{}) } diff --git a/orderer/rawledger/ramledger/ramledger_test.go b/orderer/rawledger/ramledger/ramledger_test.go index e6a952f7dbe..34ae460ca3d 100644 --- a/orderer/rawledger/ramledger/ramledger_test.go +++ b/orderer/rawledger/ramledger/ramledger_test.go @@ -19,19 +19,15 @@ package ramledger import ( "testing" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" ) var genesisBlock *cb.Block func init() { - bootstrapper := static.New() - var err error - genesisBlock, err = bootstrapper.GenesisBlock() - if err != nil { - panic("Error intializing static bootstrap genesis block") - } + genesisBlock = provisional.New(config.Load()).GenesisBlock() } // TestAppend ensures that appending blocks stores only the maxSize most recent blocks diff --git a/orderer/sample_clients/bd_counter/broadcast.go b/orderer/sample_clients/bd_counter/broadcast.go index 652dfa91942..b255d8b836c 100644 --- a/orderer/sample_clients/bd_counter/broadcast.go +++ b/orderer/sample_clients/bd_counter/broadcast.go @@ -21,7 +21,7 @@ import ( "io" "strconv" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -54,7 +54,7 @@ func (c *clientImpl) broadcast() { payload, err := proto.Marshal(&cb.Payload{ Header: &cb.Header{ ChainHeader: &cb.ChainHeader{ - ChainID: static.TestChainID, + ChainID: provisional.TestChainID, }, }, Data: []byte(strconv.Itoa(count)), diff --git a/orderer/sample_clients/bd_counter/deliver.go b/orderer/sample_clients/bd_counter/deliver.go index 1a3a2aadbd1..914e2b8cd9e 100644 --- a/orderer/sample_clients/bd_counter/deliver.go +++ b/orderer/sample_clients/bd_counter/deliver.go @@ -21,7 +21,7 @@ import ( "io" "log" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" ab "github.com/hyperledger/fabric/protos/orderer" context "golang.org/x/net/context" ) @@ -31,7 +31,7 @@ func (c *clientImpl) deliver() { Type: &ab.DeliverUpdate_Seek{ Seek: &ab.SeekInfo{ WindowSize: uint64(c.config.window), - ChainID: static.TestChainID, + ChainID: provisional.TestChainID, }, }, } diff --git a/orderer/sample_clients/broadcast_config/newchain.go b/orderer/sample_clients/broadcast_config/newchain.go index 31fc6e1b447..bd141b3ed38 100644 --- a/orderer/sample_clients/broadcast_config/newchain.go +++ b/orderer/sample_clients/broadcast_config/newchain.go @@ -17,7 +17,8 @@ limitations under the License. package main import ( - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" "github.com/hyperledger/fabric/protos/utils" ) @@ -25,12 +26,7 @@ import ( var genesisBlock *cb.Block func init() { - helper := static.New() - var err error - genesisBlock, err = helper.GenesisBlock() - if err != nil { - panic("Error retrieving static genesis block") - } + genesisBlock = provisional.New(config.Load()).GenesisBlock() } func newChainRequest(creationPolicy, newChainID string) *cb.Envelope { @@ -38,5 +34,5 @@ func newChainRequest(creationPolicy, newChainID string) *cb.Envelope { oldGenesisTxPayload := utils.ExtractPayloadOrPanic(oldGenesisTx) oldConfigEnv := utils.UnmarshalConfigurationEnvelopeOrPanic(oldGenesisTxPayload.Data) - return utils.ChainCreationConfigurationTransaction(static.AcceptAllPolicyKey, newChainID, oldConfigEnv) + return utils.ChainCreationConfigurationTransaction(provisional.AcceptAllPolicyKey, newChainID, oldConfigEnv) } diff --git a/orderer/sample_clients/broadcast_timestamp/client.go b/orderer/sample_clients/broadcast_timestamp/client.go index 98b5ce8bc80..563ee0c42f9 100644 --- a/orderer/sample_clients/broadcast_timestamp/client.go +++ b/orderer/sample_clients/broadcast_timestamp/client.go @@ -22,7 +22,7 @@ import ( "time" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -74,12 +74,14 @@ func main() { var messages uint64 flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.") - flag.StringVar(&chainID, "chainID", static.TestChainID, "The chain ID to broadcast to.") + flag.StringVar(&chainID, "chainID", provisional.TestChainID, "The chain ID to broadcast to.") flag.Uint64Var(&messages, "messages", 1, "The number of messages to braodcast.") flag.Parse() conn, err := grpc.Dial(serverAddr, grpc.WithInsecure()) - defer conn.Close() + defer func() { + _ = conn.Close() + }() if err != nil { fmt.Println("Error connecting:", err) return diff --git a/orderer/sample_clients/deliver_stdout/client.go b/orderer/sample_clients/deliver_stdout/client.go index b82c4c91076..022efa809f9 100644 --- a/orderer/sample_clients/deliver_stdout/client.go +++ b/orderer/sample_clients/deliver_stdout/client.go @@ -20,7 +20,7 @@ import ( "flag" "fmt" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" "github.com/hyperledger/fabric/orderer/localconfig" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -117,7 +117,7 @@ func main() { var windowSize uint64 flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.") - flag.StringVar(&chainID, "chainID", static.TestChainID, "The chain ID to deliver from.") + flag.StringVar(&chainID, "chainID", provisional.TestChainID, "The chain ID to deliver from.") flag.Uint64Var(&windowSize, "windowSize", 10, "The window size for the deliver.") flag.Parse() diff --git a/orderer/sample_clients/single_tx_client/single_tx_client.go b/orderer/sample_clients/single_tx_client/single_tx_client.go index 0a8ed19e02a..60134218349 100644 --- a/orderer/sample_clients/single_tx_client/single_tx_client.go +++ b/orderer/sample_clients/single_tx_client/single_tx_client.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -98,7 +98,7 @@ func updateReceiver(resultch chan byte, errorch chan error, client ab.AtomicBroa errorch <- fmt.Errorf("Failed to get Deliver stream: %s", err) return } - dstream.Send(&ab.DeliverUpdate{Type: &ab.DeliverUpdate_Seek{Seek: &ab.SeekInfo{Start: ab.SeekInfo_NEWEST, WindowSize: 10, ChainID: static.TestChainID}}}) + dstream.Send(&ab.DeliverUpdate{Type: &ab.DeliverUpdate_Seek{Seek: &ab.SeekInfo{Start: ab.SeekInfo_NEWEST, WindowSize: 10, ChainID: provisional.TestChainID}}}) logger.Info("{Update Receiver} Listening to ledger updates.") for i := 0; i < 2; i++ { m, inerr := dstream.Recv() @@ -134,7 +134,7 @@ func broadcastSender(resultch chan byte, errorch chan error, client ab.AtomicBro pl := &cb.Payload{ Header: &cb.Header{ ChainHeader: &cb.ChainHeader{ - ChainID: static.TestChainID, + ChainID: provisional.TestChainID, }, }, Data: bs, diff --git a/orderer/sbft/backend/backend_test.go b/orderer/sbft/backend/backend_test.go index 84bf7ac0d0e..b1fa2e9ad89 100644 --- a/orderer/sbft/backend/backend_test.go +++ b/orderer/sbft/backend/backend_test.go @@ -25,7 +25,8 @@ import ( "testing" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + localconfig "github.com/hyperledger/fabric/orderer/localconfig" "github.com/hyperledger/fabric/orderer/rawledger/ramledger" "github.com/hyperledger/fabric/orderer/sbft/simplebft" cb "github.com/hyperledger/fabric/protos/common" @@ -68,10 +69,9 @@ func TestSignAndVerifyEcdsa(t *testing.T) { } func TestLedgerReadWrite(t *testing.T) { - genesis, err := static.New().GenesisBlock() - if err != nil { - panic("Failed to generate genesis block.") - } + localConf := localconfig.Load() + localConf.General.OrdererType = provisional.ConsensusTypeSbft + genesis := provisional.New(localConf).GenesisBlock() _, rl := ramledger.New(10, genesis) b := Backend{ledger: rl} diff --git a/orderer/sbft/main.go b/orderer/sbft/main.go index 5a3e7a5a74b..0267f131684 100644 --- a/orderer/sbft/main.go +++ b/orderer/sbft/main.go @@ -23,7 +23,8 @@ import ( _ "net/http/pprof" "os" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" + localconfig "github.com/hyperledger/fabric/orderer/localconfig" "github.com/hyperledger/fabric/orderer/rawledger/fileledger" "github.com/hyperledger/fabric/orderer/sbft/backend" "github.com/hyperledger/fabric/orderer/sbft/connection" @@ -122,10 +123,10 @@ func serve(c flags) { s := &consensusStack{ persist: nil, } - genesisBlock, err := static.New().GenesisBlock() - if err != nil { - panic(err) - } + + localConf := localconfig.Load() + localConf.General.OrdererType = provisional.ConsensusTypeSbft + genesisBlock := provisional.New(localConf).GenesisBlock() _, ledger := fileledger.New(c.dataDir, genesisBlock) s.backend, err = backend.NewBackend(config.Peers, conn, ledger, persist) diff --git a/orderer/sbft/sbft_test.go b/orderer/sbft/sbft_test.go index 38971c6079b..e9de32f011e 100644 --- a/orderer/sbft/sbft_test.go +++ b/orderer/sbft/sbft_test.go @@ -24,7 +24,7 @@ import ( "time" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/orderer/common/bootstrap/static" + "github.com/hyperledger/fabric/orderer/common/bootstrap/provisional" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" "github.com/op/go-logging" @@ -130,7 +130,7 @@ func updateReceiver(t *testing.T, resultch chan byte, errorch chan error, client errorch <- fmt.Errorf("Failed to get Deliver stream: %s", err) return } - dstream.Send(&ab.DeliverUpdate{Type: &ab.DeliverUpdate_Seek{Seek: &ab.SeekInfo{Start: ab.SeekInfo_NEWEST, WindowSize: 10, ChainID: static.TestChainID}}}) + dstream.Send(&ab.DeliverUpdate{Type: &ab.DeliverUpdate_Seek{Seek: &ab.SeekInfo{Start: ab.SeekInfo_NEWEST, WindowSize: 10, ChainID: provisional.TestChainID}}}) logger.Info("{Update Receiver} Listening to ledger updates.") for i := 0; i < 2; i++ { m, inerr := dstream.Recv()