From 3ed369118f1365dcac05719b4c9ff7936c651308 Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Tue, 28 Apr 2020 17:00:34 -0400 Subject: [PATCH] WIP Chain APIs for channel operations FAB-17744 Signed-off-by: Will Lahti --- configtx/capabilities.go | 43 --------- configtx/capabilities_test.go | 12 +-- configtx/channel.go | 176 ++++++++++++++++++++++++++++++++++ configtx/config.go | 64 ------------- configtx/config_test.go | 2 +- configtx/policies.go | 22 ----- configtx/policies_test.go | 6 +- 7 files changed, 186 insertions(+), 139 deletions(-) create mode 100644 configtx/channel.go diff --git a/configtx/capabilities.go b/configtx/capabilities.go index 923ab52..0be7434 100644 --- a/configtx/capabilities.go +++ b/configtx/capabilities.go @@ -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 { diff --git a/configtx/capabilities_test.go b/configtx/capabilities_test.go index 230f174..8be5399 100644 --- a/configtx/capabilities_test.go +++ b/configtx/capabilities_test.go @@ -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()) } @@ -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{} @@ -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)) }) } @@ -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{} @@ -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)) }) } diff --git a/configtx/channel.go b/configtx/channel.go new file mode 100644 index 0000000..248359e --- /dev/null +++ b/configtx/channel.go @@ -0,0 +1,176 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package configtx + +import ( + "fmt" + + cb "github.com/hyperledger/fabric-protos-go/common" +) + +type ChannelGroup struct { + channelGroup *cb.ConfigGroup +} + +type UpdatedChannelGroup struct { + *ChannelGroup +} + +func (c *Config) Channel() *ChannelGroup { + return &ChannelGroup{channelGroup: c.ChannelGroup} +} + +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 +} diff --git a/configtx/config.go b/configtx/config.go index c099ee3..4b6be74 100644 --- a/configtx/config.go +++ b/configtx/config.go @@ -125,70 +125,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) { diff --git a/configtx/config_test.go b/configtx/config_test.go index 27e4f6f..fb992a7 100644 --- a/configtx/config_test.go +++ b/configtx/config_test.go @@ -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)) diff --git a/configtx/policies.go b/configtx/policies.go index 0639035..8d39992 100644 --- a/configtx/policies.go +++ b/configtx/policies.go @@ -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{} diff --git a/configtx/policies_test.go b/configtx/policies_test.go index 33a1580..a3f5f68 100644 --- a/configtx/policies_test.go +++ b/configtx/policies_test.go @@ -858,7 +858,7 @@ func TestSetChannelPolicy(t *testing.T) { "TestPolicy": {Type: ImplicitMetaPolicyType, Rule: "ANY Readers"}, } - err = c.SetChannelPolicy(AdminsPolicyKey, "TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Readers"}) + err = c.UpdatedConfig().Channel().SetPolicy(AdminsPolicyKey, "TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Readers"}) gt.Expect(err).NotTo(HaveOccurred()) updatedChannelPolicy, err := getPolicies(c.updated.ChannelGroup.Policies) @@ -896,7 +896,7 @@ func TestRemoveChannelPolicy(t *testing.T) { }, } - err = c.RemoveChannelPolicy(ReadersPolicyKey) + err = c.UpdatedConfig().Channel().RemovePolicy(ReadersPolicyKey) gt.Expect(err).NotTo(HaveOccurred()) updatedChannelPolicy, err := getPolicies(c.UpdatedConfig().ChannelGroup.Policies) @@ -928,7 +928,7 @@ func TestRemoveChannelPolicyFailures(t *testing.T) { } c := New(config) - err = c.RemoveChannelPolicy(ReadersPolicyKey) + err = c.UpdatedConfig().Channel().RemovePolicy(ReadersPolicyKey) gt.Expect(err).To(MatchError("unknown policy type: 15")) }