Skip to content

Commit

Permalink
Chain APIs for channel operations
Browse files Browse the repository at this point in the history
FAB-17744

Signed-off-by: Will Lahti <[email protected]>
  • Loading branch information
wlahti committed May 1, 2020
1 parent e638f2d commit b7c21fc
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 139 deletions.
43 changes: 0 additions & 43 deletions configtx/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,6 @@ import (
cb "github.com/hyperledger/fabric-protos-go/common"
)

// ChannelCapabilities returns a map of enabled channel capabilities
// from a config transaction.
func (c *ConfigTx) ChannelCapabilities() ([]string, error) {
capabilities, err := getCapabilities(c.original.ChannelGroup)
if err != nil {
return nil, fmt.Errorf("retrieving channel capabilities: %v", err)
}

return capabilities, nil
}

// AddChannelCapability adds capability to the provided channel config.
// If the provided capability already exist in current configuration, this action
// will be a no-op.
func (c *ConfigTx) AddChannelCapability(capability string) error {
capabilities, err := c.ChannelCapabilities()
if err != nil {
return err
}

err = addCapability(c.updated.ChannelGroup, capabilities, AdminsPolicyKey, capability)
if err != nil {
return err
}

return nil
}

// RemoveChannelCapability removes capability to the provided channel config.
func (c *ConfigTx) RemoveChannelCapability(capability string) error {
capabilities, err := c.ChannelCapabilities()
if err != nil {
return err
}

err = removeCapability(c.updated.ChannelGroup, capabilities, AdminsPolicyKey, capability)
if err != nil {
return err
}

return nil
}

// capabilitiesValue returns the config definition for a set of capabilities.
// It is a value for the /Channel/Orderer, Channel/Application/, and /Channel groups.
func capabilitiesValue(capabilities []string) *standardConfigValue {
Expand Down
12 changes: 6 additions & 6 deletions configtx/capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ func TestChannelCapabilities(t *testing.T) {
err := setValue(config.ChannelGroup, capabilitiesValue(expectedCapabilities), AdminsPolicyKey)
gt.Expect(err).NotTo(HaveOccurred())

channelCapabilities, err := c.ChannelCapabilities()
channelCapabilities, err := c.OriginalConfig().Channel().Capabilities()
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(channelCapabilities).To(Equal(expectedCapabilities))

// Delete the capabilities key and assert retrieval to return nil
delete(config.ChannelGroup.Values, CapabilitiesKey)
channelCapabilities, err = c.ChannelCapabilities()
channelCapabilities, err = c.OriginalConfig().Channel().Capabilities()
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(channelCapabilities).To(BeNil())
}
Expand Down Expand Up @@ -142,7 +142,7 @@ func TestSetChannelCapability(t *testing.T) {
}
`

err := c.AddChannelCapability("V3_0")
err := c.UpdatedConfig().Channel().AddCapability("V3_0")
gt.Expect(err).NotTo(HaveOccurred())

buf := bytes.Buffer{}
Expand Down Expand Up @@ -186,7 +186,7 @@ func TestSetChannelCapabilityFailures(t *testing.T) {

c := New(tt.config)

err := c.AddChannelCapability(tt.capability)
err := c.UpdatedConfig().Channel().AddCapability(tt.capability)
gt.Expect(err).To(MatchError(tt.expectedErr))
})
}
Expand Down Expand Up @@ -804,7 +804,7 @@ func TestRemoveChannelCapability(t *testing.T) {
}
`

err := c.RemoveChannelCapability("V3_0")
err := c.UpdatedConfig().Channel().RemoveCapability("V3_0")
gt.Expect(err).NotTo(HaveOccurred())

buf := bytes.Buffer{}
Expand Down Expand Up @@ -862,7 +862,7 @@ func TestRemoveChannelCapabilityFailures(t *testing.T) {

c := New(tt.config)

err := c.RemoveChannelCapability(tt.capability)
err := c.UpdatedConfig().Channel().RemoveCapability(tt.capability)
gt.Expect(err).To(MatchError(tt.expectedErr))
})
}
Expand Down
182 changes: 182 additions & 0 deletions configtx/channel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package configtx

import (
"fmt"

cb "github.com/hyperledger/fabric-protos-go/common"
)

// ChannelGroup encapsulates the parts of the config that control channels.
// This type implements retrieval of the various channel config values.
type ChannelGroup struct {
channelGroup *cb.ConfigGroup
}

// UpdatedChannelGroup is a ChannelGroup that can be modified in order to
// generate a config update.
type UpdatedChannelGroup struct {
*ChannelGroup
}

// Channel returns the channel group from the original config.
func (o *OriginalConfig) Channel() *ChannelGroup {
return &ChannelGroup{channelGroup: o.ChannelGroup}
}

// Channel returns the channel group from the updated config.
func (u *UpdatedConfig) Channel() *UpdatedChannelGroup {
return &UpdatedChannelGroup{ChannelGroup: &ChannelGroup{channelGroup: u.ChannelGroup}}
}

// Configuration returns a channel configuration value from a config transaction.
func (c *ChannelGroup) Configuration() (Channel, error) {
var (
err error
consortium string
application Application
orderer Orderer
consortiums []Consortium
capabilities []string
)

if _, ok := c.channelGroup.Values[ConsortiumKey]; ok {
consortiumProto := &cb.Consortium{}
err := unmarshalConfigValueAtKey(c.channelGroup, ConsortiumKey, consortiumProto)
if err != nil {
return Channel{}, err
}
consortium = consortiumProto.Name
}

if applicationGroup, ok := c.channelGroup.Groups[ApplicationGroupKey]; ok {
a := &ApplicationGroup{applicationGroup: applicationGroup}
application, err = a.Configuration()
if err != nil {
return Channel{}, err
}
}

if ordererGroup, ok := c.channelGroup.Groups[OrdererGroupKey]; ok {
o := &OrdererGroup{ordererGroup: ordererGroup, channelGroup: c.channelGroup}
orderer, err = o.Configuration()
if err != nil {
return Channel{}, err
}
}

if consortiumsGroup, ok := c.channelGroup.Groups[ConsortiumsGroupKey]; ok {
c := &ConsortiumsGroup{consortiumsGroup: consortiumsGroup}
consortiums, err = c.Configuration()
if err != nil {
return Channel{}, err
}
}

if _, ok := c.channelGroup.Values[CapabilitiesKey]; ok {
capabilities, err = c.Capabilities()
if err != nil {
return Channel{}, err
}
}

policies, err := c.Policies()
if err != nil {
return Channel{}, err
}

return Channel{
Consortium: consortium,
Application: application,
Orderer: orderer,
Consortiums: consortiums,
Capabilities: capabilities,
Policies: policies,
}, nil
}

// Configuration returns a channel configuration value from a config transaction.
func (u *UpdatedChannelGroup) Configuration() (Channel, error) {
return u.ChannelGroup.Configuration()
}

// Policies returns a map of policies for channel configuration.
func (c *ChannelGroup) Policies() (map[string]Policy, error) {
return getPolicies(c.channelGroup.Policies)
}

// Policies returns a map of policies for channel configuration.
func (u *UpdatedChannelGroup) Policies() (map[string]Policy, error) {
return u.ChannelGroup.Policies()
}

// SetPolicy sets the specified policy in the channel group's config policy map.
// If the policy already exist in current configuration, its value will be overwritten.
func (u *UpdatedChannelGroup) SetPolicy(modPolicy, policyName string, policy Policy) error {
return setPolicy(u.channelGroup, modPolicy, policyName, policy)
}

// RemovePolicy removes an existing channel level policy.
func (u *UpdatedChannelGroup) RemovePolicy(policyName string) error {
policies, err := u.Policies()
if err != nil {
return err
}

removePolicy(u.channelGroup, policyName, policies)
return nil
}

// Capabilities returns a map of enabled channel capabilities
// from a config transaction's original config.
func (c *ChannelGroup) Capabilities() ([]string, error) {
capabilities, err := getCapabilities(c.channelGroup)
if err != nil {
return nil, fmt.Errorf("retrieving channel capabilities: %v", err)
}

return capabilities, nil
}

// Capabilities returns a map of enabled channel capabilities
// from a config transaction's updated config..
func (u *UpdatedChannelGroup) Capabilities() ([]string, error) {
return u.ChannelGroup.Capabilities()
}

// AddCapability adds capability to the provided channel config.
// If the provided capability already exist in current configuration, this action
// will be a no-op.
func (u *UpdatedChannelGroup) AddCapability(capability string) error {
capabilities, err := u.Capabilities()
if err != nil {
return err
}

err = addCapability(u.channelGroup, capabilities, AdminsPolicyKey, capability)
if err != nil {
return err
}

return nil
}

// RemoveCapability removes capability to the provided channel config.
func (u *UpdatedChannelGroup) RemoveCapability(capability string) error {
capabilities, err := u.Capabilities()
if err != nil {
return err
}

err = removeCapability(u.channelGroup, capabilities, AdminsPolicyKey, capability)
if err != nil {
return err
}

return nil
}
64 changes: 0 additions & 64 deletions configtx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,70 +132,6 @@ func (c *ConfigTx) ComputeUpdate(channelID string) (*cb.ConfigUpdate, error) {
return updt, nil
}

// ChannelConfiguration returns a channel configuration value from a config transaction.
func (c *ConfigTx) ChannelConfiguration() (Channel, error) {
channelGroup := c.original.ChannelGroup
var (
err error
consortium string
application Application
orderer Orderer
consortiums []Consortium
capabilities []string
)

if _, ok := channelGroup.Values[ConsortiumKey]; ok {
consortiumProto := &cb.Consortium{}
err := unmarshalConfigValueAtKey(channelGroup, ConsortiumKey, consortiumProto)
if err != nil {
return Channel{}, err
}
consortium = consortiumProto.Name
}

if _, ok := channelGroup.Groups[ApplicationGroupKey]; ok {
application, err = c.OriginalConfig().Application().Configuration()
if err != nil {
return Channel{}, err
}
}

if _, ok := channelGroup.Groups[OrdererGroupKey]; ok {
orderer, err = c.OriginalConfig().Orderer().Configuration()
if err != nil {
return Channel{}, err
}
}

if _, ok := channelGroup.Groups[ConsortiumsGroupKey]; ok {
consortiums, err = c.OriginalConfig().Consortiums().Configuration()
if err != nil {
return Channel{}, err
}
}

if _, ok := channelGroup.Values[CapabilitiesKey]; ok {
capabilities, err = c.ChannelCapabilities()
if err != nil {
return Channel{}, err
}
}

policies, err := c.ChannelPolicies()
if err != nil {
return Channel{}, err
}

return Channel{
Consortium: consortium,
Application: application,
Orderer: orderer,
Consortiums: consortiums,
Capabilities: capabilities,
Policies: policies,
}, nil
}

// NewCreateChannelTx creates a create channel tx using the provided application channel
// configuration and returns an unsigned envelope for an application channel creation transaction.
func NewCreateChannelTx(channelConfig Channel, channelID string) (*cb.Envelope, error) {
Expand Down
2 changes: 1 addition & 1 deletion configtx/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@ func TestChannelConfiguration(t *testing.T) {
config := tt.configMod(gt)
c := New(config)

channel, err := c.ChannelConfiguration()
channel, err := c.OriginalConfig().Channel().Configuration()
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(channel.Consortium).To(Equal(tt.expectedChannel.Consortium))
gt.Expect(channel.Application.Organizations).To(ContainElements(tt.expectedChannel.Application.Organizations))
Expand Down
22 changes: 0 additions & 22 deletions configtx/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,6 @@ import (
mb "github.com/hyperledger/fabric-protos-go/msp"
)

// ChannelPolicies returns a map of policies for channel configuration.
func (c *ConfigTx) ChannelPolicies() (map[string]Policy, error) {
return getPolicies(c.original.ChannelGroup.Policies)
}

// SetChannelPolicy sets the specified policy in the channel group's config policy map.
// If the policy already exist in current configuration, its value will be overwritten.
func (c *ConfigTx) SetChannelPolicy(modPolicy, policyName string, policy Policy) error {
return setPolicy(c.updated.ChannelGroup, modPolicy, policyName, policy)
}

// RemoveChannelPolicy removes an existing channel level policy.
func (c *ConfigTx) RemoveChannelPolicy(policyName string) error {
policies, err := c.ChannelPolicies()
if err != nil {
return err
}

removePolicy(c.updated.ChannelGroup, policyName, policies)
return nil
}

// getPolicies returns a map of Policy from given map of ConfigPolicy in organization config group.
func getPolicies(policies map[string]*cb.ConfigPolicy) (map[string]Policy, error) {
p := map[string]Policy{}
Expand Down
Loading

0 comments on commit b7c21fc

Please sign in to comment.