Skip to content

Commit

Permalink
[FAB-1614] Provisional bootstrapper to templates
Browse files Browse the repository at this point in the history
https://jira.hyperledger.org/browse/FAB-1614

This changeset converts the orderer provisional bootstrapper to use the
new configtx.Template mechanism.

This is a precursor to removing the duplicate genesis code from
protos/utils.

Change-Id: I47ca9a9c8bcfab2b4eeff5b40b84da71a0230a08
Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
  • Loading branch information
Jason Yellick committed Jan 13, 2017
1 parent 47c182f commit c53d2e0
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 66 deletions.
64 changes: 64 additions & 0 deletions common/genesis/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
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 genesis

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

const (
msgVersion = int32(1)

// These values are fixed for the genesis block.
lastModified = 0
epoch = 0
)

type Factory interface {
Block(chainID string) (*cb.Block, error)
}

type factory struct {
template configtx.Template
}

func NewFactoryImpl(template configtx.Template) Factory {
return &factory{template: template}
}

func (f *factory) Block(chainID string) (*cb.Block, error) {
items, err := f.template.Items(chainID)
if err != nil {
return nil, err
}

payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, msgVersion, chainID, epoch)
payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic())
payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{Items: items})}
envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil}

block := cb.NewBlock(0, nil)
block.Data = &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}}
block.Header.DataHash = block.Data.Hash()
block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] = utils.MarshalOrPanic(&cb.Metadata{
Value: utils.MarshalOrPanic(&cb.LastConfiguration{Index: 0}),
})
return block, nil
}
32 changes: 32 additions & 0 deletions common/genesis/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
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 genesis

import (
"testing"

"github.com/hyperledger/fabric/common/configtx"
cb "github.com/hyperledger/fabric/protos/common"
)

func TestSanity(t *testing.T) {
impl := NewFactoryImpl(configtx.NewSimpleTemplate(&cb.ConfigurationItem{}))
_, err := impl.Block("TestChainID")
if err != nil {
t.Fatalf("Basic sanity fails")
}
}
45 changes: 18 additions & 27 deletions orderer/common/bootstrap/provisional/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,93 +25,84 @@ import (
"github.com/hyperledger/fabric/protos/utils"
)

func (cbs *commonBootstrapper) encodeConsensusType() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeConsensusType() *cb.ConfigurationItem {
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeBatchSize() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeBatchSize() *cb.ConfigurationItem {
configItemKey := sharedconfig.BatchSizeKey
configItemValue := utils.MarshalOrPanic(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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeBatchTimeout() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeBatchTimeout() *cb.ConfigurationItem {
configItemKey := sharedconfig.BatchTimeoutKey
configItemValue := utils.MarshalOrPanic(&ab.BatchTimeout{Timeout: cbs.batchTimeout})
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeChainCreators() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeChainCreators() *cb.ConfigurationItem {
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeAcceptAllPolicy() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeAcceptAllPolicy() *cb.ConfigurationItem {
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeIngressPolicy() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeIngressPolicy() *cb.ConfigurationItem {
configItemKey := sharedconfig.IngressPolicyKey
configItemValue := utils.MarshalOrPanic(&ab.IngressPolicy{Name: AcceptAllPolicyKey})
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) encodeEgressPolicy() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) encodeEgressPolicy() *cb.ConfigurationItem {
configItemKey := sharedconfig.EgressPolicyKey
configItemValue := utils.MarshalOrPanic(&ab.EgressPolicy{Name: AcceptAllPolicyKey})
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}

func (cbs *commonBootstrapper) lockDefaultModificationPolicy() *cb.SignedConfigurationItem {
func (cbs *commonBootstrapper) lockDefaultModificationPolicy() *cb.ConfigurationItem {
// 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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue)
}

func (kbs *kafkaBootstrapper) encodeKafkaBrokers() *cb.SignedConfigurationItem {
func (kbs *kafkaBootstrapper) encodeKafkaBrokers() *cb.ConfigurationItem {
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}
return utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
}
49 changes: 27 additions & 22 deletions orderer/common/bootstrap/provisional/provisional.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@ package provisional
import (
"fmt"

"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/genesis"
"github.com/hyperledger/fabric/orderer/common/bootstrap"
"github.com/hyperledger/fabric/orderer/localconfig"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
"github.com/hyperledger/fabric/protos/utils"
)

// Generator can either create an orderer genesis block or configuration template
type Generator interface {
bootstrap.Helper

// TemplateItems returns a set of configuration items which can be used to initialize a template
TemplateItems() []*cb.ConfigurationItem
}

const (
msgVersion = int32(1)

Expand Down Expand Up @@ -70,7 +79,7 @@ type kafkaBootstrapper struct {
}

// New returns a new provisional bootstrap helper.
func New(conf *config.TopLevel) bootstrap.Helper {
func New(conf *config.TopLevel) Generator {
cbs := &commonBootstrapper{
chainID: TestChainID,
consensusType: conf.Genesis.OrdererType,
Expand All @@ -95,30 +104,26 @@ func New(conf *config.TopLevel) bootstrap.Helper {
}
}

func (cbs *commonBootstrapper) genesisBlock(minimalTemplateItems func() []*cb.ConfigurationItem) *cb.Block {
block, err := genesis.NewFactoryImpl(
configtx.NewCompositeTemplate(
configtx.NewSimpleTemplate(minimalTemplateItems()...),
configtx.NewSimpleTemplate(cbs.makeOrdererSystemChainConfig()...),
),
).Block(TestChainID)

if err != nil {
panic(err)
}
return block
}

// GenesisBlock returns the genesis block to be used for bootstrapping.
func (cbs *commonBootstrapper) GenesisBlock() *cb.Block {
return cbs.makeGenesisBlock(cbs.makeGenesisConfigEnvelope())
return cbs.genesisBlock(cbs.TemplateItems)
}

// 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}

block := cb.NewBlock(0, nil)
block.Data = &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}}
block.Header.DataHash = block.Data.Hash()
block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] = utils.MarshalOrPanic(&cb.Metadata{
Value: utils.MarshalOrPanic(&cb.LastConfiguration{Index: 0}),
})

return block
return kbs.genesisBlock(kbs.TemplateItems)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,24 @@ 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(
func (cbs *commonBootstrapper) makeOrdererSystemChainConfig() []*cb.ConfigurationItem {
return []*cb.ConfigurationItem{cbs.encodeChainCreators()}
}

func (cbs *commonBootstrapper) TemplateItems() []*cb.ConfigurationItem {
return []*cb.ConfigurationItem{
cbs.encodeConsensusType(),
cbs.encodeBatchSize(),
cbs.encodeBatchTimeout(),
cbs.encodeChainCreators(),
cbs.encodeAcceptAllPolicy(),
cbs.encodeIngressPolicy(),
cbs.encodeEgressPolicy(),
cbs.lockDefaultModificationPolicy(),
)
}
}

func (kbs *kafkaBootstrapper) makeGenesisConfigEnvelope() *cb.ConfigurationEnvelope {
return utils.MakeConfigurationEnvelope(
kbs.encodeConsensusType(),
kbs.encodeBatchSize(),
kbs.encodeBatchTimeout(),
kbs.encodeKafkaBrokers(),
kbs.encodeChainCreators(),
kbs.encodeAcceptAllPolicy(),
kbs.encodeIngressPolicy(),
kbs.encodeEgressPolicy(),
kbs.lockDefaultModificationPolicy(),
)
func (kbs *kafkaBootstrapper) TemplateItems() []*cb.ConfigurationItem {
return append(kbs.commonBootstrapper.TemplateItems(), kbs.encodeKafkaBrokers())
}

0 comments on commit c53d2e0

Please sign in to comment.