From f0f748756db2b1eefcc9d89af56c378d7588bf4a Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Tue, 15 Aug 2017 15:14:46 -0400 Subject: [PATCH] [FAB-5806] Create channel config policy bundle The channel configuration is currently processed via the configtx package. This is actually a conflation of responsibilities, as the configtx package should be concerned about permission to modify a configuration, not the actual contents of the change. This CR creates a new channel config bundle, which will ultimately hold an immutable copy of the channel configuration. For the time being, it implements a poor man's parsing of the policy tree. This temporary parsing will be removed in the future in favor of more robust parsing once the mutability notion has been removed from the policy manager. Change-Id: Ia3f4dc4d247afcc9c4e7895fff93cc2d007fae5a Signed-off-by: Jason Yellick --- common/channelconfig/channelconfig.go | 77 +++++++++++++++++++++++++++ common/channelconfig/util.go | 46 ++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 common/channelconfig/channelconfig.go create mode 100644 common/channelconfig/util.go diff --git a/common/channelconfig/channelconfig.go b/common/channelconfig/channelconfig.go new file mode 100644 index 00000000000..077abb71f21 --- /dev/null +++ b/common/channelconfig/channelconfig.go @@ -0,0 +1,77 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package channelconfig + +import ( + "github.com/hyperledger/fabric/common/cauthdsl" + "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/common/policies" + "github.com/hyperledger/fabric/msp" + cb "github.com/hyperledger/fabric/protos/common" + + "github.com/pkg/errors" +) + +var logger = flogging.MustGetLogger("common/channelconfig") + +// RootGroupKey is the key for namespacing the channel config, especially for +// policy evaluation. +const RootGroupKey = "Channel" + +// Bundle is a collection of resources which will always have a consistent +// view of the channel configuration. In particular, for a given bundle reference, +// the config sequence, the policy manager etc. will always return exactly the +// same value. The Bundle structure is immutable and will always be replaced in its +// entirety, with new backing memory. +type Bundle struct { + policyManager policies.Manager + mspManager msp.MSPManager +} + +// PolicyManager returns the policy manager constructed for this config +func (b *Bundle) PolicyManager() policies.Manager { + return b.policyManager +} + +// MSPManager returns the MSP manager constructed for this config +func (b *Bundle) MSPManager() msp.MSPManager { + return b.mspManager +} + +// NewBundle creates a new immutable bundle of configuration +func NewBundle(config *cb.Config) (*Bundle, error) { + mspManager := msp.NewMSPManager() + // XXX Truly initialize the MSP manager + err := mspManager.Setup([]msp.MSP{}) + if err != nil { + logger.Panicf("Error creating MSP manager") + } + + policyProviderMap := make(map[int32]policies.Provider) + for pType := range cb.Policy_PolicyType_name { + rtype := cb.Policy_PolicyType(pType) + switch rtype { + case cb.Policy_UNKNOWN: + // Do not register a handler + case cb.Policy_SIGNATURE: + policyProviderMap[pType] = cauthdsl.NewPolicyProvider(mspManager) + case cb.Policy_MSP: + // Add hook for MSP Handler here + } + } + + policyManager := policies.NewManagerImpl(RootGroupKey, policyProviderMap) + err = InitializePolicyManager(policyManager, config.ChannelGroup) + if err != nil { + return nil, errors.Wrap(err, "initializing policymanager failed") + } + + return &Bundle{ + mspManager: mspManager, + policyManager: policyManager, + }, nil +} diff --git a/common/channelconfig/util.go b/common/channelconfig/util.go new file mode 100644 index 00000000000..9730f2ad20f --- /dev/null +++ b/common/channelconfig/util.go @@ -0,0 +1,46 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package channelconfig + +import ( + "github.com/hyperledger/fabric/common/policies" + cb "github.com/hyperledger/fabric/protos/common" + + "github.com/pkg/errors" +) + +// InitializePolicyManager takes a config group and uses it to initialize a PolicyManager +// XXX This goes away by the end of the CR series so no test logic +func InitializePolicyManager(pm policies.Proposer, group *cb.ConfigGroup) error { + subGroups := make([]string, len(group.Groups)) + i := 0 + for subGroup := range group.Groups { + subGroups[i] = subGroup + i++ + } + + subPolicyHandlers, err := pm.BeginPolicyProposals("", subGroups) + if err != nil { + return err + } + + for key, policy := range group.Policies { + _, err := pm.ProposePolicy("", key, policy) + if err != nil { + return err + } + } + + for i := range subGroups { + if err := InitializePolicyManager(subPolicyHandlers[i], group.Groups[subGroups[i]]); err != nil { + return errors.Wrapf(err, "failed initializing subgroup %s", subGroups[i]) + } + } + + pm.CommitProposals("") + return nil +}