Skip to content

Commit

Permalink
[FAB-2646] (PA) Create consortium configuration
Browse files Browse the repository at this point in the history
In order to support returning the list of channels via the ordering
system channel configuration, there needs to be additional configuration
structures representing the groups which may create channels.

We call these groups Consortiums by convention, where each consortium
represents a group of organizations which may form channels together.

Note, this also include FAB-2647 as combined with FAB-2700 it provides
testing coverage for the new code.

Change-Id: Iaa7dada39daa153c95613b47def8169b57f27be4
Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
Signed-off-by: Kostas Christidis <kostas@christidis.io>
  • Loading branch information
Jason Yellick authored and kchristidis committed Apr 26, 2017
1 parent 7f114bb commit 7998d07
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 83 deletions.
13 changes: 13 additions & 0 deletions common/config/api.go
Expand Up @@ -21,6 +21,7 @@ package config
import (
"time"

cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
pb "github.com/hyperledger/fabric/protos/peer"
)
Expand Down Expand Up @@ -62,6 +63,18 @@ type Channel interface {
OrdererAddresses() []string
}

// Consortiums represents the set of consortiums serviced by an ordering service
type Consortiums interface {
// Consortiums returns the set of consortiums
Consortiums() map[string]Consortium
}

// Consortium represents a group of orgs which may create channels together
type Consortium interface {
// ChannelCreationPolicy returns the policy to check when instantiating a channel for this consortium
ChannelCreationPolicy() *cb.Policy
}

// Orderer stores the common shared orderer config
type Orderer interface {
// ConsensusType returns the configured consensus type
Expand Down
17 changes: 15 additions & 2 deletions common/config/channel.go
Expand Up @@ -105,13 +105,20 @@ func (cg *ChannelGroup) ApplicationConfig() *ApplicationGroup {
return cg.ChannelConfig.appConfig
}

// ConsortiumsConfig returns the consortium config associated with this channel if it exists
func (cg *ChannelGroup) ConsortiumsConfig() *ConsortiumsGroup {
return cg.ChannelConfig.consortiumsConfig
}

// NewGroup instantiates either a new application or orderer config
func (cg *ChannelGroup) NewGroup(group string) (ValueProposer, error) {
switch group {
case ApplicationGroupKey:
return NewApplicationGroup(cg.mspConfigHandler), nil
case OrdererGroupKey:
return NewOrdererGroup(cg.mspConfigHandler), nil
case ConsortiumsGroupKey:
return NewConsortiumsGroup(), nil
default:
return nil, fmt.Errorf("Disallowed channel group: %s", group)
}
Expand All @@ -124,8 +131,9 @@ type ChannelConfig struct {

hashingAlgorithm func(input []byte) []byte

appConfig *ApplicationGroup
ordererConfig *OrdererGroup
appConfig *ApplicationGroup
ordererConfig *OrdererGroup
consortiumsConfig *ConsortiumsGroup
}

// NewChannelConfig creates a new ChannelConfig
Expand Down Expand Up @@ -183,6 +191,11 @@ func (cc *ChannelConfig) Validate(tx interface{}, groups map[string]ValuePropose
if !ok {
return fmt.Errorf("Orderer group was not Orderer config")
}
case ConsortiumsGroupKey:
cc.consortiumsConfig, ok = value.(*ConsortiumsGroup)
if !ok {
return fmt.Errorf("Consortiums group was no Consortium config")
}
default:
return fmt.Errorf("Disallowed channel group: %s", key)
}
Expand Down
137 changes: 137 additions & 0 deletions common/config/consortium.go
@@ -0,0 +1,137 @@
/*
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.
*/

package config

import (
"fmt"

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

// ConsortiumProtos holds the config protos for the consortium config
type ConsortiumProtos struct {
ChannelCreationPolicy *cb.Policy
}

// ConsortiumGroup stores the set of Consortium
type ConsortiumGroup struct {
*Proposer
*ConsortiumConfig

mspConfig *msp.MSPConfigHandler
consortiumsGroup *ConsortiumsGroup
}

// NewConsortiumGroup creates a new *ConsortiumGroup
func NewConsortiumGroup(consortiumsGroup *ConsortiumsGroup) *ConsortiumGroup {
cg := &ConsortiumGroup{
mspConfig: msp.NewMSPConfigHandler(),
consortiumsGroup: consortiumsGroup,
}
cg.Proposer = NewProposer(cg)
return cg
}

// NewGroup returns a Consortium instance
func (cg *ConsortiumGroup) NewGroup(name string) (ValueProposer, error) {
return NewOrganizationGroup(name, cg.mspConfig), nil
}

// Allocate returns the resources for a new config proposal
func (cg *ConsortiumGroup) Allocate() Values {
return NewConsortiumConfig(cg)
}

// BeginValueProposals calls through to Proposer after calling into the MSP config Handler
func (cg *ConsortiumGroup) BeginValueProposals(tx interface{}, groups []string) (ValueDeserializer, []ValueProposer, error) {
cg.mspConfig.BeginConfig(tx)
return cg.Proposer.BeginValueProposals(tx, groups)
}

// PreCommit intercepts the precommit request and commits the MSP config handler before calling the underlying proposer
func (cg *ConsortiumGroup) PreCommit(tx interface{}) error {
err := cg.mspConfig.PreCommit(tx)
if err != nil {
return err
}
return cg.Proposer.PreCommit(tx)
}

// RollbackProposals intercepts the rollback request and commits the MSP config handler before calling the underlying proposer
func (cg *ConsortiumGroup) RollbackProposals(tx interface{}) {
cg.mspConfig.RollbackProposals(tx)
cg.Proposer.RollbackProposals(tx)
}

// CommitProposals intercepts the commit request and commits the MSP config handler before calling the underlying proposer
func (cg *ConsortiumGroup) CommitProposals(tx interface{}) {
cg.mspConfig.CommitProposals(tx)
cg.Proposer.CommitProposals(tx)
}

// ConsortiumConfig holds the consoritums configuration information
type ConsortiumConfig struct {
*standardValues
protos *ConsortiumProtos
orgs map[string]*OrganizationGroup

consortiumGroup *ConsortiumGroup
}

// NewConsortiumConfig creates a new instance of the consoritums config
func NewConsortiumConfig(cg *ConsortiumGroup) *ConsortiumConfig {
cc := &ConsortiumConfig{
protos: &ConsortiumProtos{},
orgs: make(map[string]*OrganizationGroup),
consortiumGroup: cg,
}
var err error
cc.standardValues, err = NewStandardValues(cc.protos)
if err != nil {
logger.Panicf("Programming error: %s", err)
}
return cc
}

// Organizations returns the set of organizations in the consortium
func (cc *ConsortiumConfig) Organizations() map[string]*OrganizationGroup {
return cc.orgs
}

// CreationPolicy returns the policy structure used to validate
// the channel creation
func (cc *ConsortiumConfig) ChannelCreationPolicy() *cb.Policy {
return cc.protos.ChannelCreationPolicy
}

// Commit commits the ConsortiumConfig
func (cc *ConsortiumConfig) Commit() {
cc.consortiumGroup.ConsortiumConfig = cc
}

// Validate builds the Consortium map
func (cc *ConsortiumConfig) Validate(tx interface{}, groups map[string]ValueProposer) error {
var ok bool
for key, group := range groups {
cc.orgs[key], ok = group.(*OrganizationGroup)
if !ok {
return fmt.Errorf("Unexpected group type: %T", group)
}
}
return nil
}
93 changes: 93 additions & 0 deletions common/config/consortiums.go
@@ -0,0 +1,93 @@
/*
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.
*/

package config

import (
"fmt"
)

const (
// ConsortiumsGroupKey is the group name for the consortiums config
ConsortiumsGroupKey = "Consortiums"
)

// ConsortiumsGroup stores the set of Consortiums
type ConsortiumsGroup struct {
*Proposer
*ConsortiumsConfig
}

// NewConsortiumsGroup creates a new *ConsortiumsGroup
func NewConsortiumsGroup() *ConsortiumsGroup {
cg := &ConsortiumsGroup{}
cg.Proposer = NewProposer(cg)
return cg
}

// NewGroup returns a Consortium instance
func (cg *ConsortiumsGroup) NewGroup(name string) (ValueProposer, error) {
return NewConsortiumGroup(cg), nil
}

// Allocate returns the resources for a new config proposal
func (cg *ConsortiumsGroup) Allocate() Values {
return NewConsortiumsConfig(cg)
}

// ConsortiumsConfig holds the consoritums configuration information
type ConsortiumsConfig struct {
*standardValues
consortiums map[string]Consortium

consortiumsGroup *ConsortiumsGroup
}

// NewConsortiumsConfig creates a new instance of the consoritums config
func NewConsortiumsConfig(cg *ConsortiumsGroup) *ConsortiumsConfig {
cc := &ConsortiumsConfig{
consortiums: make(map[string]Consortium),
consortiumsGroup: cg,
}
var err error
cc.standardValues, err = NewStandardValues()
if err != nil {
logger.Panicf("Programming error: %s", err)
}
return cc
}

// Consortiums returns a map of the current consortiums
func (cc *ConsortiumsConfig) Consortiums() map[string]Consortium {
return cc.consortiums
}

// Commit commits the ConsortiumsConfig
func (cc *ConsortiumsConfig) Commit() {
cc.consortiumsGroup.ConsortiumsConfig = cc
}

// Validate builds the Consortiums map
func (cc *ConsortiumsConfig) Validate(tx interface{}, groups map[string]ValueProposer) error {
var ok bool
for key, group := range groups {
cc.consortiums[key], ok = group.(*ConsortiumGroup)
if !ok {
return fmt.Errorf("Unexpected group type: %T", group)
}
}
return nil
}
44 changes: 44 additions & 0 deletions common/config/consortiums_util.go
@@ -0,0 +1,44 @@
/*
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.
*/

package config

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

const (
// ChannelCreationPolicyKey is the key for the ChannelCreationPolicy value
ChannelCreationPolicyKey = "ChannelCreationPolicy"
)

// TemplateConsortiumsGroup creates an empty consortiums group
func TemplateConsortiumsGroup() *cb.ConfigGroup {
result := cb.NewConfigGroup()
result.Groups[ConsortiumsGroupKey] = cb.NewConfigGroup()
return result
}

// TemplateConsortiumChannelCreationPolicy sets the ChannelCreationPolicy for a given consortium
func TemplateConsortiumChannelCreationPolicy(name string, policy *cb.Policy) *cb.ConfigGroup {
result := TemplateConsortiumsGroup()
result.Groups[ConsortiumsGroupKey].Groups[name] = cb.NewConfigGroup()
result.Groups[ConsortiumsGroupKey].Groups[name].Values[ChannelCreationPolicyKey] = &cb.ConfigValue{
Value: utils.MarshalOrPanic(policy),
}
return result
}
4 changes: 4 additions & 0 deletions common/config/root.go
Expand Up @@ -87,3 +87,7 @@ func (r *Root) Orderer() *OrdererGroup {
func (r *Root) Application() *ApplicationGroup {
return r.channel.ApplicationConfig()
}

func (r *Root) Consortiums() *ConsortiumsGroup {
return r.channel.ConsortiumsConfig()
}
7 changes: 5 additions & 2 deletions common/configtx/api/api.go
Expand Up @@ -52,12 +52,15 @@ type Resources interface {
// PolicyManager returns the policies.Manager for the channel
PolicyManager() policies.Manager

// ChannelConfig returns the ChannelConfig for the chain
// ChannelConfig returns the config.Channel for the chain
ChannelConfig() config.Channel

// OrdererConfig returns the configtxorderer.SharedConfig for the channel
// OrdererConfig returns the config.Orderer for the channel
OrdererConfig() config.Orderer

// ConsortiumsConfig() returns the config.Consortiums for the channel
ConsortiumsConfig() config.Consortiums

// ApplicationConfig returns the configtxapplication.SharedConfig for the channel
ApplicationConfig() config.Application

Expand Down
5 changes: 5 additions & 0 deletions common/configtx/initializer.go
Expand Up @@ -56,6 +56,11 @@ func (r *resources) ApplicationConfig() config.Application {
return r.configRoot.Application()
}

// ConsortiumsConfig returns the api.ConsortiumsConfig for the chain
func (r *resources) ConsortiumsConfig() config.Consortiums {
return r.configRoot.Consortiums()
}

// MSPManager returns the msp.MSPManager for the chain
func (r *resources) MSPManager() msp.MSPManager {
return r.mspConfigHandler
Expand Down

0 comments on commit 7998d07

Please sign in to comment.