Skip to content

Commit

Permalink
Merge "[FAB-6087] Add configtxgen capabilties support"
Browse files Browse the repository at this point in the history
  • Loading branch information
yacovm authored and Gerrit Code Review committed Oct 3, 2017
2 parents 14e9088 + a77389d commit 28b0da2
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 28 deletions.
18 changes: 16 additions & 2 deletions common/channelconfig/application_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/hyperledger/fabric/protos/utils"
)

func applicationConfigGroup(orgID string, key string, value []byte) *cb.ConfigGroup {
func applicationOrgConfigGroup(orgID string, key string, value []byte) *cb.ConfigGroup {
result := cb.NewConfigGroup()
result.Groups[ApplicationGroupKey] = cb.NewConfigGroup()
result.Groups[ApplicationGroupKey].Groups[orgID] = cb.NewConfigGroup()
Expand All @@ -22,7 +22,21 @@ func applicationConfigGroup(orgID string, key string, value []byte) *cb.ConfigGr
return result
}

func applicationConfigGroup(key string, value []byte) *cb.ConfigGroup {
result := cb.NewConfigGroup()
result.Groups[ApplicationGroupKey] = cb.NewConfigGroup()
result.Groups[ApplicationGroupKey].Values[key] = &cb.ConfigValue{
Value: value,
}
return result
}

// TemplateAnchorPeers creates a headerless config item representing the anchor peers
func TemplateAnchorPeers(orgID string, anchorPeers []*pb.AnchorPeer) *cb.ConfigGroup {
return applicationConfigGroup(orgID, AnchorPeersKey, utils.MarshalOrPanic(&pb.AnchorPeers{AnchorPeers: anchorPeers}))
return applicationOrgConfigGroup(orgID, AnchorPeersKey, utils.MarshalOrPanic(&pb.AnchorPeers{AnchorPeers: anchorPeers}))
}

// TemplateApplicationCapabilities creates a config value representing the application capabilities
func TemplateApplicationCapabilities(capabilities map[string]bool) *cb.ConfigGroup {
return applicationConfigGroup(CapabilitiesKey, utils.MarshalOrPanic(capabilitiesFromBoolMap(capabilities)))
}
4 changes: 4 additions & 0 deletions common/channelconfig/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ const (

// GroupKey is the name of the channel group
ChannelGroupKey = "Channel"

// CapabilitiesKey is the name of the key which refers to capabilities, it appears at the channel,
// application, and orderer levels and this constant is used for all three.
CapabilitiesKey = "Capabilities"
)

// ChannelValues gives read only access to the channel configuration
Expand Down
17 changes: 17 additions & 0 deletions common/channelconfig/channel_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,20 @@ func TemplateOrdererAddresses(addresses []string) *cb.ConfigGroup {
func DefaultOrdererAddresses() *cb.ConfigGroup {
return TemplateOrdererAddresses(defaultOrdererAddresses)
}

func capabilitiesFromBoolMap(capabilities map[string]bool) *cb.Capabilities {
value := &cb.Capabilities{
Capabilities: make(map[string]*cb.Capability),
}
for capability, required := range capabilities {
value.Capabilities[capability] = &cb.Capability{
Required: required,
}
}
return value
}

// TemplateChannelCapabilities creates a config value representing the channel capabilities
func TemplateChannelCapabilities(capabilities map[string]bool) *cb.ConfigGroup {
return configGroup(CapabilitiesKey, utils.MarshalOrPanic(capabilitiesFromBoolMap(capabilities)))
}
5 changes: 5 additions & 0 deletions common/channelconfig/orderer_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ func TemplateChannelRestrictions(maxChannels uint64) *cb.ConfigGroup {
func TemplateKafkaBrokers(brokers []string) *cb.ConfigGroup {
return ordererConfigGroup(KafkaBrokersKey, utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: brokers}))
}

// TemplateOrdererCapabilities creates a config value representing the orderer capabilities
func TemplateOrdererCapabilities(capabilities map[string]bool) *cb.ConfigGroup {
return ordererConfigGroup(CapabilitiesKey, utils.MarshalOrPanic(capabilitiesFromBoolMap(capabilities)))
}
44 changes: 18 additions & 26 deletions common/tools/configtxgen/localconfig/config.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Copyright IBM Corp. 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 localconfig
Expand Down Expand Up @@ -60,13 +50,17 @@ const (
SampleDevModeSoloProfile = "SampleDevModeSolo"
// SampleSingleMSPSoloProfile references the sample profile which includes only the sample MSP and uses solo for ordering.
SampleSingleMSPSoloProfile = "SampleSingleMSPSolo"
// SampleSingleMSPSoloV11Profile references the sample profile which includes only the sample MSP with v1.1 capabilities defined and uses solo for ordering.
SampleSingleMSPSoloV11Profile = "SampleSingleMSPSoloV1.1"

// SampleInsecureKafkaProfile references the sample profile which does not include any MSPs and uses Kafka for ordering.
SampleInsecureKafkaProfile = "SampleInsecureKafka"
// SampleDevModeKafkaProfile references the sample profile which requires only basic membership for admin privileges and uses Kafka for ordering.
SampleDevModeKafkaProfile = "SampleDevModeKafka"
// SampleSingleMSPKafkaProfile references the sample profile which includes only the sample MSP and uses Kafka for ordering.
SampleSingleMSPKafkaProfile = "SampleSingleMSPKafka"
// SampleSingleMSPKafkaV11Profile references the sample profile which includes only the sample MSPwith v1.1 capabilities defined and uses Kafka for ordering.
SampleSingleMSPKafkaV11Profile = "SampleSingleMSPKafkaV1.1"

// SampleSingleMSPChannelProfile references the sample profile which includes only the sample MSP and is used to create a channel
SampleSingleMSPChannelProfile = "SampleSingleMSPChannel"
Expand All @@ -84,18 +78,20 @@ const (

// TopLevel consists of the structs used by the configtxgen tool.
type TopLevel struct {
Profiles map[string]*Profile `yaml:"Profiles"`
Organizations []*Organization `yaml:"Organizations"`
Application *Application `yaml:"Application"`
Orderer *Orderer `yaml:"Orderer"`
Profiles map[string]*Profile `yaml:"Profiles"`
Organizations []*Organization `yaml:"Organizations"`
Application *Application `yaml:"Application"`
Orderer *Orderer `yaml:"Orderer"`
Capabilities map[string]map[string]bool `yaml:"Capabilities"`
}

// Profile encodes orderer/application configuration combinations for the configtxgen tool.
type Profile struct {
Consortium string `yaml:"Consortium"`
Application *Application `yaml:"Application"`
Orderer *Orderer `yaml:"Orderer"`
Consortiums map[string]*Consortium `yaml:"Consortiums"`
Consortium string `yaml:"Consortium"`
Application *Application `yaml:"Application"`
Orderer *Orderer `yaml:"Orderer"`
Consortiums map[string]*Consortium `yaml:"Consortiums"`
Capabilities map[string]bool `yaml:"Capabilities"`
}

// Consortium represents a group of organizations which may create channels with eachother
Expand All @@ -106,6 +102,7 @@ type Consortium struct {
// Application encodes the application-level configuration needed in config transactions.
type Application struct {
Organizations []*Organization `yaml:"Organizations"`
Capabilities map[string]bool `yaml:"Capabilities"`
}

// Organization encodes the organization-level configuration needed in config transactions.
Expand All @@ -127,12 +124,6 @@ type AnchorPeer struct {
Port int `yaml:"Port"`
}

// ApplicationOrganization ...
// TODO This should probably be removed
type ApplicationOrganization struct {
Organization `yaml:"Organization"`
}

// Orderer contains configuration which is used for the
// bootstrapping of an orderer by the provisional bootstrapper.
type Orderer struct {
Expand All @@ -143,6 +134,7 @@ type Orderer struct {
Kafka Kafka `yaml:"Kafka"`
Organizations []*Organization `yaml:"Organizations"`
MaxChannels uint64 `yaml:"MaxChannels"`
Capabilities map[string]bool `yaml:"Capabilities"`
}

// BatchSize contains configuration affecting the size of batches.
Expand Down
13 changes: 13 additions & 0 deletions common/tools/configtxgen/provisional/provisional.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ func New(conf *genesisconfig.Profile) Generator {
},
}

if len(conf.Capabilities) > 0 {
bs.channelGroups = append(bs.channelGroups, channelconfig.TemplateChannelCapabilities(conf.Capabilities))
}

if conf.Orderer != nil {
// Orderer addresses
oa := channelconfig.TemplateOrdererAddresses(conf.Orderer.Addresses)
Expand All @@ -115,6 +119,10 @@ func New(conf *genesisconfig.Profile) Generator {
policies.TemplateImplicitMetaMajorityPolicy([]string{channelconfig.OrdererGroupKey}, channelconfig.AdminsPolicyKey),
}

if len(conf.Orderer.Capabilities) > 0 {
bs.ordererGroups = append(bs.ordererGroups, channelconfig.TemplateOrdererCapabilities(conf.Orderer.Capabilities))
}

for _, org := range conf.Orderer.Organizations {
mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
if err != nil {
Expand Down Expand Up @@ -144,6 +152,11 @@ func New(conf *genesisconfig.Profile) Generator {
policies.TemplateImplicitMetaAnyPolicy([]string{channelconfig.ApplicationGroupKey}, channelconfig.WritersPolicyKey),
policies.TemplateImplicitMetaMajorityPolicy([]string{channelconfig.ApplicationGroupKey}, channelconfig.AdminsPolicyKey),
}

if len(conf.Application.Capabilities) > 0 {
bs.applicationGroups = append(bs.applicationGroups, channelconfig.TemplateApplicationCapabilities(conf.Application.Capabilities))
}

for _, org := range conf.Application.Organizations {
mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
if err != nil {
Expand Down
83 changes: 83 additions & 0 deletions sampleconfig/configtx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,41 @@ Profiles:
Organizations:
- *SampleOrg

# SampleSingleMSPSoloV1.1 mimics the SampleSingleMSPSolo definition but
# additionally defines the v1.1 only capabilities which do not allow a
# mixed v1.0.x v1.1.x network.
SampleSingleMSPSoloV1.1:
Capabilities:
<<: *GlobalCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *SampleOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *SampleOrg

# SampleSingleMSPKafkaV1.1 defines a configuration that differs from the
# SampleSingleMSPSoloV1.1 one only in that it uses the Kafka-based orderer.
SampleSingleMSPKafkaV1.1:
Capabilities:
<<: *GlobalCapabilities
Orderer:
<<: *OrdererDefaults
OrdererType: kafka
Organizations:
- *SampleOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *SampleOrg


# SampleNoConsortium is very similar to SampleInsecureSolo, except it does
# not define Consortiums.
SampleNoConsortium:
Expand All @@ -115,6 +150,17 @@ Profiles:
Organizations:
- *SampleOrg

# SampleSingleMSPChannelV1.1 defines a channel just as SampleSingleMSPChannel
# However, it also defines the capabilities map which makes this channel
# incompatible with v1.0.x peers.
SampleSingleMSPChannelV1.1:
Consortium: SampleConsortium
Application:
Organizations:
- *SampleOrg
Capabilities:
<<: *ApplicationCapabilities

################################################################################
#
# Section: Organizations
Expand Down Expand Up @@ -220,3 +266,40 @@ Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network.
Organizations:

################################################################################
#
# SECTION: Capabilities
#
# - This section defines the capabilities of fabric network. This is a new
# concept as of v1.1.0 and should not be utilized in mixed networks with
# v1.0.x peers and orderers. Capabilities define features which must be
# present in a fabric binary for that binary to safely participate in the
# fabric network. For instance, if a new MSP type is added, newer binaries
# might recognize and validate the signatures from this type, while older
# binaries without this support would be unable to validate those
# transactions. This could lead to different versions of the fabric binaries
# having different world states. Instead, defining a capability for a channel
# informs those binaries without this capability that they must cease
# processing transactions until they have been upgraded. For v1.0.x if any
# capabilities are defined (including a map with all capabilities turned off)
# then the v1.0.x peer will deliberately crash.
#
################################################################################
Capabilities:
# Global capabilities apply to both the orderers and the peers and must be
# supported by both. Set the value of the capability to true to require it.
Global: &GlobalCapabilities
"V1.1": true

# Orderer capabilities apply only to the orderers, and may be safely
# manipulated without concern for upgrading peers. Set the value of the
# capability to true to require it.
Orderer: &OrdererCapabilities
"V1.1": true

# Application capabilities apply only to the peer network, and may be safely
# manipulated without concern for upgrading orderers. Set the value of the
# capability to true to require it.
Application: &ApplicationCapabilities
"V1.1": true

0 comments on commit 28b0da2

Please sign in to comment.