Skip to content

Commit

Permalink
[FAB-5816] Make channel config values immutable
Browse files Browse the repository at this point in the history
This is probably the most complex CR in the series, but the new code is
still obviously much simpler and more easily verified as correct than
the old version.

This CR modifies the config structures to be instantiated simply through
their constructors, rather than through the transactional
begin/propose/precommit/commit structure which existed before.

Although this CR produces a bit of churn, is it he last real obstacle to
removing a large swatch of otherwise unused code.

Change-Id: I108e3c8e215d9642b18654d19f58b056eea94081
Signed-off-by: Jason Yellick <[email protected]>
  • Loading branch information
Jason Yellick committed Aug 30, 2017
1 parent 5b0c2e4 commit 033d5e6
Show file tree
Hide file tree
Showing 22 changed files with 289 additions and 1,020 deletions.
31 changes: 12 additions & 19 deletions common/channelconfig/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/hyperledger/fabric/common/cauthdsl"
oldchannelconfig "github.com/hyperledger/fabric/common/config/channel"
oldmspconfig "github.com/hyperledger/fabric/common/config/channel/msp"
"github.com/hyperledger/fabric/common/configtx"
configtxapi "github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/flogging"
Expand All @@ -37,7 +36,7 @@ const RootGroupKey = "Channel"
type Bundle struct {
policyManager policies.Manager
mspManager msp.MSPManager
rootConfig *oldchannelconfig.Root
channelConfig *oldchannelconfig.ChannelConfig
configtxManager configtxapi.Manager
}

Expand All @@ -48,32 +47,32 @@ func (b *Bundle) PolicyManager() policies.Manager {

// MSPManager returns the MSP manager constructed for this config
func (b *Bundle) MSPManager() msp.MSPManager {
return b.mspManager
return b.channelConfig.MSPManager()
}

// ChannelConfig returns the config.Channel for the chain
func (b *Bundle) ChannelConfig() oldchannelconfig.Channel {
return b.rootConfig.Channel()
return b.channelConfig
}

// OrdererConfig returns the config.Orderer for the channel
// and whether the Orderer config exists
func (b *Bundle) OrdererConfig() (oldchannelconfig.Orderer, bool) {
result := b.rootConfig.Orderer()
result := b.channelConfig.OrdererConfig()
return result, result != nil
}

// ConsortiumsConfig() returns the config.Consortiums for the channel
// and whether the consortiums config exists
func (b *Bundle) ConsortiumsConfig() (oldchannelconfig.Consortiums, bool) {
result := b.rootConfig.Consortiums()
result := b.channelConfig.ConsortiumsConfig()
return result, result != nil
}

// ApplicationConfig returns the configtxapplication.SharedConfig for the channel
// and whether the Application config exists
func (b *Bundle) ApplicationConfig() (oldchannelconfig.Application, bool) {
result := b.rootConfig.Application()
result := b.channelConfig.ApplicationConfig()
return result, result != nil
}

Expand Down Expand Up @@ -131,8 +130,10 @@ func NewBundle(channelID string, config *cb.Config) (*Bundle, error) {
return nil, fmt.Errorf("config must contain a channel group")
}

mspConfigHandler := oldmspconfig.NewMSPConfigHandler()
rootConfig := oldchannelconfig.NewRoot(mspConfigHandler)
channelConfig, err := oldchannelconfig.NewChannelConfig(config.ChannelGroup)
if err != nil {
return nil, errors.Wrap(err, "initializing channelconfig failed")
}

policyProviderMap := make(map[int32]policies.Provider)
for pType := range cb.Policy_PolicyType_name {
Expand All @@ -141,19 +142,12 @@ func NewBundle(channelID string, config *cb.Config) (*Bundle, error) {
case cb.Policy_UNKNOWN:
// Do not register a handler
case cb.Policy_SIGNATURE:
policyProviderMap[pType] = cauthdsl.NewPolicyProvider(mspConfigHandler)
policyProviderMap[pType] = cauthdsl.NewPolicyProvider(channelConfig.MSPManager())
case cb.Policy_MSP:
// Add hook for MSP Handler here
}
}

err := InitializeConfigValues(rootConfig, &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{RootGroupKey: config.ChannelGroup},
})
if err != nil {
return nil, errors.Wrap(err, "initializing config values failed")
}

policyManager, err := policies.NewManagerImpl(RootGroupKey, policyProviderMap, config.ChannelGroup)
if err != nil {
return nil, errors.Wrap(err, "initializing policymanager failed")
Expand All @@ -172,9 +166,8 @@ func NewBundle(channelID string, config *cb.Config) (*Bundle, error) {
}

return &Bundle{
mspManager: mspConfigHandler,
policyManager: policyManager,
rootConfig: rootConfig,
channelConfig: channelConfig,
configtxManager: configtxManager,
}, nil
}
13 changes: 5 additions & 8 deletions common/channelconfig/bundlesource.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,28 @@ func (bs *BundleSource) MSPManager() msp.MSPManager {

// ChannelConfig returns the config.Channel for the chain
func (bs *BundleSource) ChannelConfig() oldchannelconfig.Channel {
return bs.StableBundle().rootConfig.Channel()
return bs.StableBundle().ChannelConfig()
}

// OrdererConfig returns the config.Orderer for the channel
// and whether the Orderer config exists
func (bs *BundleSource) OrdererConfig() (oldchannelconfig.Orderer, bool) {
result := bs.StableBundle().rootConfig.Orderer()
return result, result != nil
return bs.StableBundle().OrdererConfig()
}

// ConsortiumsConfig() returns the config.Consortiums for the channel
// and whether the consortiums config exists
func (bs *BundleSource) ConsortiumsConfig() (oldchannelconfig.Consortiums, bool) {
result := bs.StableBundle().rootConfig.Consortiums()
return result, result != nil
return bs.StableBundle().ConsortiumsConfig()
}

// ApplicationConfig returns the configtxapplication.SharedConfig for the channel
// and whether the Application config exists
func (bs *BundleSource) ApplicationConfig() (oldchannelconfig.Application, bool) {
result := bs.StableBundle().rootConfig.Application()
return result, result != nil
return bs.StableBundle().ApplicationConfig()
}

// ConfigtxManager returns the configtx.Manager for the channel
func (bs *BundleSource) ConfigtxManager() configtxapi.Manager {
return bs.StableBundle().configtxManager
return bs.StableBundle().ConfigtxManager()
}
3 changes: 3 additions & 0 deletions common/config/channel/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import (
"time"

configtxapi "github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
pb "github.com/hyperledger/fabric/protos/peer"
)

var logger = flogging.MustGetLogger("common/config/channel")

// Org stores the common organizational config
type Org interface {
// Name returns the name this org is referred to in config
Expand Down
80 changes: 13 additions & 67 deletions common/config/channel/application.go
Original file line number Diff line number Diff line change
@@ -1,94 +1,40 @@
/*
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.
SPDX-License-Identifier: Apache-2.0
*/

package config

import (
"fmt"

"github.com/hyperledger/fabric/common/config"
"github.com/hyperledger/fabric/common/config/channel/msp"
cb "github.com/hyperledger/fabric/protos/common"
)

const (
// ApplicationGroupKey is the group name for the Application config
ApplicationGroupKey = "Application"
)

// ApplicationGroup represents the application config group
type ApplicationGroup struct {
*config.Proposer
*ApplicationConfig
mspConfig *msp.MSPConfigHandler
}

type ApplicationConfig struct {
*config.StandardValues

applicationGroup *ApplicationGroup
applicationOrgs map[string]ApplicationOrg
applicationOrgs map[string]ApplicationOrg
}

// NewSharedConfigImpl creates a new SharedConfigImpl with the given CryptoHelper
func NewApplicationGroup(mspConfig *msp.MSPConfigHandler) *ApplicationGroup {
ag := &ApplicationGroup{
mspConfig: mspConfig,
// NewApplicationConfig creates config from an Application config group
func NewApplicationConfig(appGroup *cb.ConfigGroup, mspConfig *msp.MSPConfigHandler) (*ApplicationConfig, error) {
ac := &ApplicationConfig{
applicationOrgs: make(map[string]ApplicationOrg),
}
ag.Proposer = config.NewProposer(ag)

return ag
}

func (ag *ApplicationGroup) NewGroup(name string) (config.ValueProposer, error) {
return NewApplicationOrgGroup(name, ag.mspConfig), nil
}

// Allocate returns a new instance of the ApplicationConfig
func (ag *ApplicationGroup) Allocate() config.Values {
return NewApplicationConfig(ag)
}

func NewApplicationConfig(ag *ApplicationGroup) *ApplicationConfig {
sv, err := config.NewStandardValues(&(struct{}{}))
if err != nil {
logger.Panicf("Programming error: %s", err)
}

return &ApplicationConfig{
applicationGroup: ag,

// Currently there are no config values
StandardValues: sv,
}
}

func (ac *ApplicationConfig) Validate(tx interface{}, groups map[string]config.ValueProposer) error {
ac.applicationOrgs = make(map[string]ApplicationOrg)
var ok bool
for key, value := range groups {
ac.applicationOrgs[key], ok = value.(*ApplicationOrgGroup)
if !ok {
return fmt.Errorf("Application sub-group %s was not an ApplicationOrgGroup, actually %T", key, value)
var err error
for orgName, orgGroup := range appGroup.Groups {
ac.applicationOrgs[orgName], err = NewApplicationOrgConfig(orgName, orgGroup, mspConfig)
if err != nil {
return nil, err
}
}
return nil
}

func (ac *ApplicationConfig) Commit() {
ac.applicationGroup.ApplicationConfig = ac
return ac, nil
}

// Organizations returns a map of org ID to ApplicationOrg
Expand Down
14 changes: 2 additions & 12 deletions common/config/channel/application_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
/*
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.
SPDX-License-Identifier: Apache-2.0
*/

package config
Expand All @@ -27,5 +17,5 @@ func init() {
}

func TestApplicationInterface(t *testing.T) {
_ = Application((*ApplicationGroup)(nil))
_ = Application((*ApplicationConfig)(nil))
}
Loading

0 comments on commit 033d5e6

Please sign in to comment.