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