Skip to content

Commit

Permalink
[FAB-2144] Move configtx.Manager to ConfigNext
Browse files Browse the repository at this point in the history
https://jira.hyperledger.org/browse/FAB-2144

While integrating the ConfigNext proto, adapter code was written to
convert it back to the original Config type. This conversion code needs
to go away, and as a first step, the configtx.Manager needs to begin
using the updated format.

Change-Id: I4ea95795dcdf6f9395bec17f4b22e184e8c4780a
Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
  • Loading branch information
Jason Yellick committed Feb 12, 2017
1 parent ed4f136 commit 39378d3
Show file tree
Hide file tree
Showing 16 changed files with 417 additions and 251 deletions.
36 changes: 22 additions & 14 deletions common/configtx/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,6 @@ type OrdererConfig interface {

// Handler provides a hook which allows other pieces of code to participate in config proposals
type Handler interface {
// BeginConfig called when a config proposal is begun
BeginConfig()

// RollbackConfig called when a config proposal is abandoned
RollbackConfig()

// CommitConfig called when a config proposal is committed
CommitConfig()

// ProposeConfig called when config is added to a proposal
ProposeConfig(configItem *cb.ConfigItem) error
}
Expand Down Expand Up @@ -125,11 +116,28 @@ type Resources interface {
MSPManager() msp.MSPManager
}

// Initializer is a structure which is only useful before a configtx.Manager
// has been instantiated for a chain, afterwards, it is of no utility, which
// is why it embeds the Resources interface
// SubInitializer is used downstream from initializer
type SubInitializer interface {
// BeginConfig called when a config proposal is begun
BeginConfig()

// RollbackConfig called when a config proposal is abandoned
RollbackConfig()

// CommitConfig called when a config proposal is committed
CommitConfig()

// Handler returns the associated value handler for a given config path
Handler(path []string) (Handler, error)
}

// Initializer is used as indirection between Manager and Handler to allow
// for single Handlers to handle multiple paths
type Initializer interface {
SubInitializer

Resources
// Handlers returns the handlers to be used when initializing the configtx.Manager
Handlers() map[cb.ConfigItem_ConfigType]Handler

// PolicyProposer as a Handler is a temporary hack
PolicyProposer() Handler
}
3 changes: 2 additions & 1 deletion common/configtx/bytes_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

package configtx

// XXX Remove this

import (
cb "github.com/hyperledger/fabric/protos/common"
)
Expand Down Expand Up @@ -57,7 +59,6 @@ func (bh *BytesHandler) CommitConfig() {

// ProposeConfig called when config is added to a proposal
func (bh *BytesHandler) ProposeConfig(configItem *cb.ConfigItem) error {
bh.proposed[configItem.Key] = configItem.Value
return nil
}

Expand Down
29 changes: 29 additions & 0 deletions common/configtx/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type comparable struct {
*cb.ConfigGroup
*cb.ConfigValue
*cb.ConfigPolicy
path []string
}

func (cg comparable) equals(other comparable) bool {
Expand All @@ -51,6 +52,34 @@ func (cg comparable) equals(other comparable) bool {
return false
}

func (cg comparable) version() uint64 {
switch {
case cg.ConfigGroup != nil:
return cg.ConfigGroup.Version
case cg.ConfigValue != nil:
return cg.ConfigValue.Version
case cg.ConfigPolicy != nil:
return cg.ConfigPolicy.Version
}

// Unreachable
return 0
}

func (cg comparable) modPolicy() string {
switch {
case cg.ConfigGroup != nil:
return cg.ConfigGroup.ModPolicy
case cg.ConfigValue != nil:
return cg.ConfigValue.ModPolicy
case cg.ConfigPolicy != nil:
return cg.ConfigPolicy.ModPolicy
}

// Unreachable
return ""
}

func equalConfigValues(lhs, rhs *cb.ConfigValue) bool {
return lhs.Version == rhs.Version &&
lhs.ModPolicy == rhs.ModPolicy &&
Expand Down
26 changes: 20 additions & 6 deletions common/configtx/handlers/application/sharedconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package application
import (
"fmt"

"github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/configtx/handlers/msp"
cb "github.com/hyperledger/fabric/protos/common"
pb "github.com/hyperledger/fabric/protos/peer"

Expand Down Expand Up @@ -65,12 +67,15 @@ type sharedConfig struct {
type SharedConfigImpl struct {
pendingConfig *sharedConfig
config *sharedConfig

mspConfig *msp.MSPConfigHandler
}

// NewSharedConfigImpl creates a new SharedConfigImpl with the given CryptoHelper
func NewSharedConfigImpl() *SharedConfigImpl {
func NewSharedConfigImpl(mspConfig *msp.MSPConfigHandler) *SharedConfigImpl {
return &SharedConfigImpl{
config: &sharedConfig{},
config: &sharedConfig{},
mspConfig: mspConfig,
}
}

Expand Down Expand Up @@ -106,10 +111,6 @@ func (di *SharedConfigImpl) CommitConfig() {

// ProposeConfig is used to add new config to the config proposal
func (di *SharedConfigImpl) ProposeConfig(configItem *cb.ConfigItem) error {
if configItem.Type != cb.ConfigItem_PEER {
return fmt.Errorf("Expected type of ConfigItem_Peer, got %v", configItem.Type)
}

switch configItem.Key {
case AnchorPeersKey:
anchorPeers := &pb.AnchorPeers{}
Expand All @@ -125,3 +126,16 @@ func (di *SharedConfigImpl) ProposeConfig(configItem *cb.ConfigItem) error {
}
return nil
}

// Handler returns the associated api.Handler for the given path
func (pm *SharedConfigImpl) Handler(path []string) (api.Handler, error) {
if len(path) == 0 {
return pm, nil
}

if len(path) > 1 {
return nil, fmt.Errorf("Application group allows only one further level of nesting")
}

return pm.mspConfig.Handler(path[1:])
}
10 changes: 5 additions & 5 deletions common/configtx/handlers/application/sharedconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func makeInvalidConfigItem(key string) *cb.ConfigItem {
}

func TestInterface(t *testing.T) {
_ = configtxapi.ApplicationConfig(NewSharedConfigImpl())
_ = configtxapi.ApplicationConfig(NewSharedConfigImpl(nil))
}

func TestDoubleBegin(t *testing.T) {
Expand All @@ -50,7 +50,7 @@ func TestDoubleBegin(t *testing.T) {
}
}()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil)
m.BeginConfig()
m.BeginConfig()
}
Expand All @@ -62,12 +62,12 @@ func TestCommitWithoutBegin(t *testing.T) {
}
}()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil)
m.CommitConfig()
}

func TestRollback(t *testing.T) {
m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil)
m.pendingConfig = &sharedConfig{}
m.RollbackConfig()
if m.pendingConfig != nil {
Expand All @@ -82,7 +82,7 @@ func TestAnchorPeers(t *testing.T) {
}
invalidMessage := makeInvalidConfigItem(AnchorPeersKey)
validMessage := TemplateAnchorPeers(endVal)
m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil)
m.BeginConfig()

err := m.ProposeConfig(invalidMessage)
Expand Down
36 changes: 30 additions & 6 deletions common/configtx/handlers/channel/sharedconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"math"

"github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/configtx/handlers/application"
"github.com/hyperledger/fabric/common/configtx/handlers/orderer"
"github.com/hyperledger/fabric/common/util"
Expand Down Expand Up @@ -83,12 +84,17 @@ type chainConfig struct {
type SharedConfigImpl struct {
pendingConfig *chainConfig
config *chainConfig

ordererConfig *orderer.ManagerImpl
applicationConfig *application.SharedConfigImpl
}

// NewSharedConfigImpl creates a new SharedConfigImpl with the given CryptoHelper
func NewSharedConfigImpl() *SharedConfigImpl {
func NewSharedConfigImpl(ordererConfig *orderer.ManagerImpl, applicationConfig *application.SharedConfigImpl) *SharedConfigImpl {
return &SharedConfigImpl{
config: &chainConfig{},
config: &chainConfig{},
ordererConfig: ordererConfig,
applicationConfig: applicationConfig,
}
}

Expand Down Expand Up @@ -131,10 +137,6 @@ func (pm *SharedConfigImpl) CommitConfig() {

// ProposeConfig is used to add new config to the config proposal
func (pm *SharedConfigImpl) ProposeConfig(configItem *cb.ConfigItem) error {
if configItem.Type != cb.ConfigItem_CHAIN {
return fmt.Errorf("Expected type of ConfigItem_Chain, got %v", configItem.Type)
}

switch configItem.Key {
case HashingAlgorithmKey:
hashingAlgorithm := &cb.HashingAlgorithm{}
Expand Down Expand Up @@ -169,3 +171,25 @@ func (pm *SharedConfigImpl) ProposeConfig(configItem *cb.ConfigItem) error {
}
return nil
}

// Handler returns the associated api.Handler for the given path
func (pm *SharedConfigImpl) Handler(path []string) (api.Handler, error) {
if len(path) == 0 {
return pm, nil
}

var initializer api.SubInitializer

switch path[0] {
case ApplicationGroupKey:
initializer = pm.applicationConfig
case OrdererGroupKey:
initializer = pm.ordererConfig
default:
return nil, fmt.Errorf("Disallowed channel group: %s", path[0])
}

return initializer.Handler(path[1:])

return nil, fmt.Errorf("Unallowed group")
}
14 changes: 7 additions & 7 deletions common/configtx/handlers/channel/sharedconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func makeInvalidConfigItem(key string) *cb.ConfigItem {
}

func TestInterface(t *testing.T) {
_ = configtxapi.ChannelConfig(NewSharedConfigImpl())
_ = configtxapi.ChannelConfig(NewSharedConfigImpl(nil, nil))
}

func TestDoubleBegin(t *testing.T) {
Expand All @@ -49,7 +49,7 @@ func TestDoubleBegin(t *testing.T) {
}
}()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.BeginConfig()
m.BeginConfig()
}
Expand All @@ -61,12 +61,12 @@ func TestCommitWithoutBegin(t *testing.T) {
}
}()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.CommitConfig()
}

func TestRollback(t *testing.T) {
m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.pendingConfig = &chainConfig{}
m.RollbackConfig()
if m.pendingConfig != nil {
Expand All @@ -79,7 +79,7 @@ func TestHashingAlgorithm(t *testing.T) {
invalidAlgorithm := TemplateHashingAlgorithm("MD5")
validAlgorithm := DefaultHashingAlgorithm()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.BeginConfig()

err := m.ProposeConfig(invalidMessage)
Expand Down Expand Up @@ -109,7 +109,7 @@ func TestBlockDataHashingStructure(t *testing.T) {
invalidWidth := TemplateBlockDataHashingStructure(0)
validWidth := DefaultBlockDataHashingStructure()

m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.BeginConfig()

err := m.ProposeConfig(invalidMessage)
Expand Down Expand Up @@ -137,7 +137,7 @@ func TestBlockDataHashingStructure(t *testing.T) {
func TestOrdererAddresses(t *testing.T) {
invalidMessage := makeInvalidConfigItem(OrdererAddressesKey)
validMessage := DefaultOrdererAddresses()
m := NewSharedConfigImpl()
m := NewSharedConfigImpl(nil, nil)
m.BeginConfig()

err := m.ProposeConfig(invalidMessage)
Expand Down
19 changes: 19 additions & 0 deletions common/configtx/handlers/msp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package msp

import (
"fmt"
"reflect"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
mspprotos "github.com/hyperledger/fabric/protos/msp"
Expand Down Expand Up @@ -65,6 +67,14 @@ func (bh *MSPConfigHandler) ProposeConfig(configItem *common.ConfigItem) error {
return fmt.Errorf("Error unmarshalling msp config item, err %s", err)
}

// TODO handle deduplication more gracefully
for _, oMsp := range bh.config {
if reflect.DeepEqual(oMsp, mspconfig) {
// The MSP is already in the list
return nil
}
}

bh.config = append(bh.config, []*mspprotos.MSPConfig{mspconfig}...)
// the only way to make sure that I have a
// workable config is to toss the proposed
Expand All @@ -73,3 +83,12 @@ func (bh *MSPConfigHandler) ProposeConfig(configItem *common.ConfigItem) error {
bh.proposedMgr = msp.NewMSPManager()
return bh.proposedMgr.Setup(bh.config)
}

// Handler returns the associated api.Handler for the given path
func (bh *MSPConfigHandler) Handler(path []string) (api.Handler, error) {
if len(path) > 0 {
return nil, fmt.Errorf("MSP handler does not support nested groups")
}

return bh, nil
}
Loading

0 comments on commit 39378d3

Please sign in to comment.