From 44f6ef5dd78c3fc7955f58f29b25021db2e6ed6a Mon Sep 17 00:00:00 2001 From: manish Date: Wed, 21 Oct 2020 19:15:45 -0400 Subject: [PATCH] Pass channel config to service discovery In the current code, service discovery has a dependency that provides with the latest config block. However, a peer that bootstraps from a snapshot does not has the historical blocks. This commit makes changes for service discovery to work with channel configuration that is supplied from the state. Signed-off-by: manish --- common/configtx/test/helper.go | 9 + core/peer/configtx_test.go | 10 +- core/peer/peer.go | 6 +- discovery/support/config/support.go | 64 ++--- discovery/support/config/support_test.go | 265 ++++++------------ .../support/mocks/config_block_getter.go | 108 ------- discovery/support/mocks/config_getter.go | 108 +++++++ discovery/support/support.go | 6 +- discovery/test/integration_test.go | 16 +- internal/peer/node/start.go | 8 +- 10 files changed, 243 insertions(+), 357 deletions(-) delete mode 100644 discovery/support/mocks/config_block_getter.go create mode 100644 discovery/support/mocks/config_getter.go diff --git a/common/configtx/test/helper.go b/common/configtx/test/helper.go index c481114c5ba..97c437a2dc3 100644 --- a/common/configtx/test/helper.go +++ b/common/configtx/test/helper.go @@ -42,6 +42,15 @@ func MakeGenesisBlock(channelID string) (*cb.Block, error) { return gb, nil } +func MakeChannelConfig(channelID string) (*cb.Config, error) { + profile := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir()) + channelGroup, err := encoder.NewChannelGroup(profile) + if err != nil { + return nil, err + } + return &cb.Config{ChannelGroup: channelGroup}, nil +} + // MakeGenesisBlockWithMSPs creates a genesis block using the MSPs provided for the given channelID func MakeGenesisBlockFromMSPs(channelID string, appMSPConf, ordererMSPConf *mspproto.MSPConfig, appOrgID, ordererOrgID string) (*cb.Block, error) { profile := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir()) diff --git a/core/peer/configtx_test.go b/core/peer/configtx_test.go index 243cff40584..9f23545b7f3 100644 --- a/core/peer/configtx_test.go +++ b/core/peer/configtx_test.go @@ -48,7 +48,7 @@ func TestConfigTxCreateLedger(t *testing.T) { ledger, err := ledgerMgr.CreateLedger(channelID, genesisBlock) require.NoError(t, err) - retrievedchanConf, err := retrievePersistedChannelConfig(ledger) + retrievedchanConf, err := RetrievePersistedChannelConfig(ledger) require.NoError(t, err) require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf)) } @@ -91,7 +91,7 @@ func TestConfigTxUpdateChanConfig(t *testing.T) { lgr, err := ledgerMgr.CreateLedger(channelID, genesisBlock) require.NoError(t, err) - retrievedchanConf, err := retrievePersistedChannelConfig(lgr) + retrievedchanConf, err := RetrievePersistedChannelConfig(lgr) require.NoError(t, err) require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf)) @@ -102,7 +102,7 @@ func TestConfigTxUpdateChanConfig(t *testing.T) { inMemoryChanConf := bs.ConfigtxValidator().ConfigProto() require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(inMemoryChanConf)) - retrievedchanConf, err = retrievePersistedChannelConfig(lgr) + retrievedchanConf, err = RetrievePersistedChannelConfig(lgr) require.NoError(t, err) require.Equal(t, proto.CompactTextString(bs.ConfigtxValidator().ConfigProto()), proto.CompactTextString(retrievedchanConf)) @@ -130,7 +130,7 @@ func TestGenesisBlockCreateLedger(t *testing.T) { lgr, err := ledgerMgr.CreateLedger("testchain", b) require.NoError(t, err) - chanConf, err := retrievePersistedChannelConfig(lgr) + chanConf, err := RetrievePersistedChannelConfig(lgr) require.NoError(t, err) require.NotNil(t, chanConf) t.Logf("chanConf = %s", chanConf) @@ -219,7 +219,7 @@ func (h *testHelper) constructChannelBundle(channelID string, ledger ledger.Peer return nil, err } - chanConf, err := retrievePersistedChannelConfig(ledger) + chanConf, err := RetrievePersistedChannelConfig(ledger) if err != nil { return nil, err } diff --git a/core/peer/peer.go b/core/peer/peer.go index 528ccb3f714..64f1c4493d1 100644 --- a/core/peer/peer.go +++ b/core/peer/peer.go @@ -249,8 +249,8 @@ func (p *Peer) CreateChannelFromSnapshot( return nil } -// retrievePersistedChannelConfig retrieves the persisted channel config from statedb -func retrievePersistedChannelConfig(ledger ledger.PeerLedger) (*common.Config, error) { +// RetrievePersistedChannelConfig retrieves the persisted channel config from statedb +func RetrievePersistedChannelConfig(ledger ledger.PeerLedger) (*common.Config, error) { qe, err := ledger.NewQueryExecutor() if err != nil { return nil, err @@ -267,7 +267,7 @@ func (p *Peer) createChannel( legacyLifecycleValidation plugindispatcher.LifecycleResources, newLifecycleValidation plugindispatcher.CollectionAndLifecycleResources, ) error { - chanConf, err := retrievePersistedChannelConfig(l) + chanConf, err := RetrievePersistedChannelConfig(l) if err != nil { return err } diff --git a/discovery/support/config/support.go b/discovery/support/config/support.go index e72f668458c..8f827bfe54e 100644 --- a/discovery/support/config/support.go +++ b/discovery/support/config/support.go @@ -23,68 +23,53 @@ import ( var logger = flogging.MustGetLogger("discovery.config") -// CurrentConfigBlockGetter enables to fetch the last config block -type CurrentConfigBlockGetter interface { - // GetCurrConfigBlock returns the current config block for the given channel - GetCurrConfigBlock(channel string) *common.Block +// CurrentConfigGetter enables to fetch the last channel config +type CurrentConfigGetter interface { + // GetCurrConfig returns the current channel config for the given channel + GetCurrConfig(channel string) *common.Config } -// CurrentConfigBlockGetterFunc enables to fetch the last config block -type CurrentConfigBlockGetterFunc func(channel string) *common.Block +// CurrentConfigGetterFunc enables to fetch the last channel config +type CurrentConfigGetterFunc func(channel string) *common.Config -// CurrentConfigBlockGetterFunc enables to fetch the last config block -func (f CurrentConfigBlockGetterFunc) GetCurrConfigBlock(channel string) *common.Block { +// CurrentConfigGetterFunc enables to fetch the last channel config +func (f CurrentConfigGetterFunc) GetCurrConfig(channel string) *common.Config { return f(channel) } // DiscoverySupport implements support that is used for service discovery // that is related to configuration type DiscoverySupport struct { - CurrentConfigBlockGetter + CurrentConfigGetter } // NewDiscoverySupport creates a new DiscoverySupport -func NewDiscoverySupport(getLastConfigBlock CurrentConfigBlockGetter) *DiscoverySupport { +func NewDiscoverySupport(getLastConfig CurrentConfigGetter) *DiscoverySupport { return &DiscoverySupport{ - CurrentConfigBlockGetter: getLastConfigBlock, + CurrentConfigGetter: getLastConfig, } } // Config returns the channel's configuration func (s *DiscoverySupport) Config(channel string) (*discovery.ConfigResult, error) { - block := s.GetCurrConfigBlock(channel) - if block == nil { - return nil, errors.Errorf("could not get last config block for channel %s", channel) - } - if block.Data == nil || len(block.Data.Data) == 0 { - return nil, errors.Errorf("no transactions in block") - } - env := &common.Envelope{} - if err := proto.Unmarshal(block.Data.Data[0], env); err != nil { - return nil, errors.Wrap(err, "failed unmarshaling envelope") - } - pl := &common.Payload{} - if err := proto.Unmarshal(env.Payload, pl); err != nil { - return nil, errors.Wrap(err, "failed unmarshaling payload") - } - ce := &common.ConfigEnvelope{} - if err := proto.Unmarshal(pl.Data, ce); err != nil { - return nil, errors.Wrap(err, "failed unmarshaling config envelope") + config := s.GetCurrConfig(channel) + if config == nil { + return nil, errors.Errorf("could not get last config for channel %s", channel) } - if err := ValidateConfigEnvelope(ce); err != nil { - return nil, errors.Wrap(err, "config envelope is invalid") + if err := ValidateConfig(config); err != nil { + return nil, errors.WithMessage(err, "config is invalid") } res := &discovery.ConfigResult{ Msps: make(map[string]*msp.FabricMSPConfig), Orderers: make(map[string]*discovery.Endpoints), } - ordererGrp := ce.Config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups - appGrp := ce.Config.ChannelGroup.Groups[channelconfig.ApplicationGroupKey].Groups + ordererGrp := config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups + appGrp := config.ChannelGroup.Groups[channelconfig.ApplicationGroupKey].Groups var globalEndpoints []string - globalOrderers := ce.Config.ChannelGroup.Values[channelconfig.OrdererAddressesKey] + globalOrderers := config.ChannelGroup.Values[channelconfig.OrdererAddressesKey] if globalOrderers != nil { ordererAddressesConfig := &common.OrdererAddresses{} if err := proto.Unmarshal(globalOrderers.Value, ordererAddressesConfig); err != nil { @@ -241,14 +226,11 @@ func appendMSPConfigs(ordererGrp, appGrp map[string]*common.ConfigGroup, output return nil } -func ValidateConfigEnvelope(ce *common.ConfigEnvelope) error { - if ce.Config == nil { - return fmt.Errorf("field Config is nil") - } - if ce.Config.ChannelGroup == nil { +func ValidateConfig(c *common.Config) error { + if c.ChannelGroup == nil { return fmt.Errorf("field Config.ChannelGroup is nil") } - grps := ce.Config.ChannelGroup.Groups + grps := c.ChannelGroup.Groups if grps == nil { return fmt.Errorf("field Config.ChannelGroup.Groups is nil") } @@ -261,7 +243,7 @@ func ValidateConfigEnvelope(ce *common.ConfigEnvelope) error { return fmt.Errorf("key Config.ChannelGroup.Groups[%s].Groups is nil", field) } } - if ce.Config.ChannelGroup.Values == nil { + if c.ChannelGroup.Values == nil { return fmt.Errorf("field Config.ChannelGroup.Values is nil") } return nil diff --git a/discovery/support/config/support_test.go b/discovery/support/config/support_test.go index beb3ddd006c..cc789ded329 100644 --- a/discovery/support/config/support_test.go +++ b/discovery/support/config/support_test.go @@ -20,7 +20,6 @@ import ( "github.com/hyperledger/fabric-protos-go/discovery" "github.com/hyperledger/fabric-protos-go/msp" "github.com/hyperledger/fabric/common/channelconfig" - "github.com/hyperledger/fabric/common/configtx" "github.com/hyperledger/fabric/common/configtx/test" "github.com/hyperledger/fabric/discovery/support/config" "github.com/hyperledger/fabric/discovery/support/mocks" @@ -31,34 +30,6 @@ import ( "github.com/stretchr/testify/require" ) -func blockWithPayload() *common.Block { - env := &common.Envelope{ - Payload: []byte{1, 2, 3}, - } - b, _ := proto.Marshal(env) - return &common.Block{ - Data: &common.BlockData{ - Data: [][]byte{b}, - }, - } -} - -func blockWithConfigEnvelope() *common.Block { - pl := &common.Payload{ - Data: []byte{1, 2, 3}, - } - plBytes, _ := proto.Marshal(pl) - env := &common.Envelope{ - Payload: plBytes, - } - b, _ := proto.Marshal(env) - return &common.Block{ - Data: &common.BlockData{ - Data: [][]byte{b}, - }, - } -} - func TestMSPIDMapping(t *testing.T) { randString := func() string { buff := make([]byte, 10) @@ -108,13 +79,17 @@ func TestMSPIDMapping(t *testing.T) { org.MSPDir = filepath.Join(cryptoConfigDir, "peerOrganizations", "org1.example.com", "msp") } - gen := encoder.New(profileConfig) - block := gen.GenesisBlockForChannel("mychannel") - - fakeBlockGetter := &mocks.ConfigBlockGetter{} - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, block) + channelGroup, err := encoder.NewChannelGroup(profileConfig) + require.NoError(t, err) + fakeConfigGetter := &mocks.ConfigGetter{} + fakeConfigGetter.GetCurrConfigReturnsOnCall( + 0, + &common.Config{ + ChannelGroup: channelGroup, + }, + ) - cs := config.NewDiscoverySupport(fakeBlockGetter) + cs := config.NewDiscoverySupport(fakeConfigGetter) res, err := cs.Config("mychannel") require.NoError(t, err) @@ -138,90 +113,48 @@ func TestMSPIDMapping(t *testing.T) { } func TestSupportGreenPath(t *testing.T) { - fakeBlockGetter := &mocks.ConfigBlockGetter{} - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, nil) + fakeConfigGetter := &mocks.ConfigGetter{} + fakeConfigGetter.GetCurrConfigReturnsOnCall(0, nil) - cs := config.NewDiscoverySupport(fakeBlockGetter) + cs := config.NewDiscoverySupport(fakeConfigGetter) res, err := cs.Config("test") require.Nil(t, res) - require.Equal(t, "could not get last config block for channel test", err.Error()) + require.Equal(t, "could not get last config for channel test", err.Error()) - block, err := test.MakeGenesisBlock("test") + config, err := test.MakeChannelConfig("test") require.NoError(t, err) - require.NotNil(t, block) + require.NotNil(t, config) - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(1, block) + fakeConfigGetter.GetCurrConfigReturnsOnCall(1, config) res, err = cs.Config("test") require.NoError(t, err) require.NotNil(t, res) } -func TestSupportBadConfig(t *testing.T) { - fakeBlockGetter := &mocks.ConfigBlockGetter{} - cs := config.NewDiscoverySupport(fakeBlockGetter) - - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, &common.Block{ - Data: &common.BlockData{}, - }) - res, err := cs.Config("test") - require.Contains(t, err.Error(), "no transactions in block") - require.Nil(t, res) - - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(1, &common.Block{ - Data: &common.BlockData{ - Data: [][]byte{{1, 2, 3}}, - }, - }) - res, err = cs.Config("test") - require.Contains(t, err.Error(), "failed unmarshaling envelope") - require.Nil(t, res) - - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(2, blockWithPayload()) - res, err = cs.Config("test") - require.Contains(t, err.Error(), "failed unmarshaling payload") - require.Nil(t, res) - - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(3, blockWithConfigEnvelope()) - res, err = cs.Config("test") - require.Contains(t, err.Error(), "failed unmarshaling config envelope") - require.Nil(t, res) -} - -func TestValidateConfigEnvelope(t *testing.T) { +func TestValidateConfig(t *testing.T) { tests := []struct { name string - ce *common.ConfigEnvelope + config *common.Config containsError string }{ { name: "nil Config field", - ce: &common.ConfigEnvelope{}, - containsError: "field Config is nil", - }, - { - name: "nil ChannelGroup field", - ce: &common.ConfigEnvelope{ - Config: &common.Config{}, - }, + config: &common.Config{}, containsError: "field Config.ChannelGroup is nil", }, { name: "nil Groups field", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{}, - }, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{}, }, containsError: "field Config.ChannelGroup.Groups is nil", }, { name: "no orderer group key", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{ - Groups: map[string]*common.ConfigGroup{ - channelconfig.ApplicationGroupKey: {}, - }, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{ + Groups: map[string]*common.ConfigGroup{ + channelconfig.ApplicationGroupKey: {}, }, }, }, @@ -229,13 +162,11 @@ func TestValidateConfigEnvelope(t *testing.T) { }, { name: "no application group key", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{ - Groups: map[string]*common.ConfigGroup{ - channelconfig.OrdererGroupKey: { - Groups: map[string]*common.ConfigGroup{}, - }, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{ + Groups: map[string]*common.ConfigGroup{ + channelconfig.OrdererGroupKey: { + Groups: map[string]*common.ConfigGroup{}, }, }, }, @@ -244,15 +175,13 @@ func TestValidateConfigEnvelope(t *testing.T) { }, { name: "no groups key in orderer group", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{ - Groups: map[string]*common.ConfigGroup{ - channelconfig.ApplicationGroupKey: { - Groups: map[string]*common.ConfigGroup{}, - }, - channelconfig.OrdererGroupKey: {}, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{ + Groups: map[string]*common.ConfigGroup{ + channelconfig.ApplicationGroupKey: { + Groups: map[string]*common.ConfigGroup{}, }, + channelconfig.OrdererGroupKey: {}, }, }, }, @@ -260,14 +189,12 @@ func TestValidateConfigEnvelope(t *testing.T) { }, { name: "no groups key in application group", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{ - Groups: map[string]*common.ConfigGroup{ - channelconfig.ApplicationGroupKey: {}, - channelconfig.OrdererGroupKey: { - Groups: map[string]*common.ConfigGroup{}, - }, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{ + Groups: map[string]*common.ConfigGroup{ + channelconfig.ApplicationGroupKey: {}, + channelconfig.OrdererGroupKey: { + Groups: map[string]*common.ConfigGroup{}, }, }, }, @@ -276,16 +203,14 @@ func TestValidateConfigEnvelope(t *testing.T) { }, { name: "no Values in ChannelGroup", - ce: &common.ConfigEnvelope{ - Config: &common.Config{ - ChannelGroup: &common.ConfigGroup{ - Groups: map[string]*common.ConfigGroup{ - channelconfig.ApplicationGroupKey: { - Groups: map[string]*common.ConfigGroup{}, - }, - channelconfig.OrdererGroupKey: { - Groups: map[string]*common.ConfigGroup{}, - }, + config: &common.Config{ + ChannelGroup: &common.ConfigGroup{ + Groups: map[string]*common.ConfigGroup{ + channelconfig.ApplicationGroupKey: { + Groups: map[string]*common.ConfigGroup{}, + }, + channelconfig.OrdererGroupKey: { + Groups: map[string]*common.ConfigGroup{}, }, }, }, @@ -297,24 +222,23 @@ func TestValidateConfigEnvelope(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - err := config.ValidateConfigEnvelope(test.ce) + err := config.ValidateConfig(test.config) require.Contains(t, test.containsError, err.Error()) }) } - } func TestOrdererEndpoints(t *testing.T) { t.Run("Global endpoints", func(t *testing.T) { - block, err := test.MakeGenesisBlock("mychannel") + channelConfig, err := test.MakeChannelConfig("mychannel") require.NoError(t, err) - fakeBlockGetter := &mocks.ConfigBlockGetter{} - cs := config.NewDiscoverySupport(fakeBlockGetter) + fakeConfigGetter := &mocks.ConfigGetter{} + cs := config.NewDiscoverySupport(fakeConfigGetter) - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, block) + fakeConfigGetter.GetCurrConfigReturnsOnCall(0, channelConfig) - injectGlobalOrdererEndpoint(t, block, "globalEndpoint:7050") + injectGlobalOrdererEndpoint(t, channelConfig, "globalEndpoint:7050") res, err := cs.Config("test") require.NoError(t, err) @@ -324,16 +248,16 @@ func TestOrdererEndpoints(t *testing.T) { }) t.Run("Per org endpoints alongside global endpoints", func(t *testing.T) { - block, err := test.MakeGenesisBlock("mychannel") + channelConfig, err := test.MakeChannelConfig("mychannel") require.NoError(t, err) - fakeBlockGetter := &mocks.ConfigBlockGetter{} - cs := config.NewDiscoverySupport(fakeBlockGetter) + fakeConfigGetter := &mocks.ConfigGetter{} + cs := config.NewDiscoverySupport(fakeConfigGetter) - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, block) + fakeConfigGetter.GetCurrConfigReturnsOnCall(0, channelConfig) - injectAdditionalEndpointPair(t, block, "perOrgEndpoint:7050", "anotherOrg") - injectAdditionalEndpointPair(t, block, "endpointWithoutAPortName", "aBadOrg") + injectAdditionalEndpointPair(t, channelConfig, "perOrgEndpoint:7050", "anotherOrg") + injectAdditionalEndpointPair(t, channelConfig, "endpointWithoutAPortName", "aBadOrg") res, err := cs.Config("test") require.NoError(t, err) @@ -345,17 +269,17 @@ func TestOrdererEndpoints(t *testing.T) { }) t.Run("Per org endpoints without global endpoints", func(t *testing.T) { - block, err := test.MakeGenesisBlock("mychannel") + channelConfig, err := test.MakeChannelConfig("mychannel") require.NoError(t, err) - fakeBlockGetter := &mocks.ConfigBlockGetter{} - cs := config.NewDiscoverySupport(fakeBlockGetter) + fakeConfigGetter := &mocks.ConfigGetter{} + cs := config.NewDiscoverySupport(fakeConfigGetter) - fakeBlockGetter.GetCurrConfigBlockReturnsOnCall(0, block) + fakeConfigGetter.GetCurrConfigReturnsOnCall(0, channelConfig) - removeGlobalEndpoints(t, block) - injectAdditionalEndpointPair(t, block, "perOrgEndpoint:7050", "SampleOrg") - injectAdditionalEndpointPair(t, block, "endpointWithoutAPortName", "aBadOrg") + removeGlobalEndpoints(t, channelConfig) + injectAdditionalEndpointPair(t, channelConfig, "perOrgEndpoint:7050", "SampleOrg") + injectAdditionalEndpointPair(t, channelConfig, "endpointWithoutAPortName", "aBadOrg") res, err := cs.Config("test") require.NoError(t, err) @@ -366,58 +290,30 @@ func TestOrdererEndpoints(t *testing.T) { }) } -func removeGlobalEndpoints(t *testing.T, block *common.Block) { - // Unwrap the layers until we reach the orderer addresses - env, err := protoutil.ExtractEnvelope(block, 0) - require.NoError(t, err) - payload := protoutil.UnmarshalPayloadOrPanic(env.Payload) - confEnv, err := configtx.UnmarshalConfigEnvelope(payload.Data) - require.NoError(t, err) +func removeGlobalEndpoints(t *testing.T, config *common.Config) { // Remove the orderer addresses - delete(confEnv.Config.ChannelGroup.Values, channelconfig.OrdererAddressesKey) - // And put it back into the block - payload.Data = protoutil.MarshalOrPanic(confEnv) - env.Payload = protoutil.MarshalOrPanic(payload) - block.Data.Data[0] = protoutil.MarshalOrPanic(env) + delete(config.ChannelGroup.Values, channelconfig.OrdererAddressesKey) } -func injectGlobalOrdererEndpoint(t *testing.T, block *common.Block, endpoint string) { +func injectGlobalOrdererEndpoint(t *testing.T, config *common.Config, endpoint string) { ordererAddresses := channelconfig.OrdererAddressesValue([]string{endpoint}) - // Unwrap the layers until we reach the orderer addresses - env, err := protoutil.ExtractEnvelope(block, 0) - require.NoError(t, err) - payload, err := protoutil.UnmarshalPayload(env.Payload) - require.NoError(t, err) - confEnv, err := configtx.UnmarshalConfigEnvelope(payload.Data) - require.NoError(t, err) // Replace the orderer addresses - confEnv.Config.ChannelGroup.Values[ordererAddresses.Key()] = &common.ConfigValue{ + config.ChannelGroup.Values[ordererAddresses.Key()] = &common.ConfigValue{ Value: protoutil.MarshalOrPanic(ordererAddresses.Value()), ModPolicy: "/Channel/Orderer/Admins", } // Remove the per org addresses, if applicable - ordererGrps := confEnv.Config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups + ordererGrps := config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups for _, grp := range ordererGrps { if grp.Values[channelconfig.EndpointsKey] == nil { continue } grp.Values[channelconfig.EndpointsKey].Value = nil } - // And put it back into the block - payload.Data = protoutil.MarshalOrPanic(confEnv) - env.Payload = protoutil.MarshalOrPanic(payload) - block.Data.Data[0] = protoutil.MarshalOrPanic(env) } -func injectAdditionalEndpointPair(t *testing.T, block *common.Block, endpoint string, orgName string) { - // Unwrap the layers until we reach the orderer addresses - env, err := protoutil.ExtractEnvelope(block, 0) - require.NoError(t, err) - payload, err := protoutil.UnmarshalPayload(env.Payload) - require.NoError(t, err) - confEnv, err := configtx.UnmarshalConfigEnvelope(payload.Data) - require.NoError(t, err) - ordererGrp := confEnv.Config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups +func injectAdditionalEndpointPair(t *testing.T, config *common.Config, endpoint string, orgName string) { + ordererGrp := config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups // Get the first orderer org config var firstOrdererConfig *common.ConfigGroup for _, grp := range ordererGrp { @@ -429,7 +325,7 @@ func injectAdditionalEndpointPair(t *testing.T, block *common.Block, endpoint st ordererGrp[orgName] = secondOrdererConfig // Reach the FabricMSPConfig buried in it. mspConfig := &msp.MSPConfig{} - err = proto.Unmarshal(secondOrdererConfig.Values[channelconfig.MSPKey].Value, mspConfig) + err := proto.Unmarshal(secondOrdererConfig.Values[channelconfig.MSPKey].Value, mspConfig) require.NoError(t, err) fabricConfig := &msp.FabricMSPConfig{} @@ -450,9 +346,4 @@ func injectAdditionalEndpointPair(t *testing.T, block *common.Block, endpoint st Addresses: []string{endpoint}, } secondOrdererConfig.Values[channelconfig.EndpointsKey].Value = protoutil.MarshalOrPanic(ordererOrgProtos) - - // Fold everything back into the block - payload.Data = protoutil.MarshalOrPanic(confEnv) - env.Payload = protoutil.MarshalOrPanic(payload) - block.Data.Data[0] = protoutil.MarshalOrPanic(env) } diff --git a/discovery/support/mocks/config_block_getter.go b/discovery/support/mocks/config_block_getter.go deleted file mode 100644 index 948fb4b0ef8..00000000000 --- a/discovery/support/mocks/config_block_getter.go +++ /dev/null @@ -1,108 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package mocks - -import ( - "sync" - - "github.com/hyperledger/fabric-protos-go/common" -) - -type ConfigBlockGetter struct { - GetCurrConfigBlockStub func(string) *common.Block - getCurrConfigBlockMutex sync.RWMutex - getCurrConfigBlockArgsForCall []struct { - arg1 string - } - getCurrConfigBlockReturns struct { - result1 *common.Block - } - getCurrConfigBlockReturnsOnCall map[int]struct { - result1 *common.Block - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlock(arg1 string) *common.Block { - fake.getCurrConfigBlockMutex.Lock() - ret, specificReturn := fake.getCurrConfigBlockReturnsOnCall[len(fake.getCurrConfigBlockArgsForCall)] - fake.getCurrConfigBlockArgsForCall = append(fake.getCurrConfigBlockArgsForCall, struct { - arg1 string - }{arg1}) - fake.recordInvocation("GetCurrConfigBlock", []interface{}{arg1}) - fake.getCurrConfigBlockMutex.Unlock() - if fake.GetCurrConfigBlockStub != nil { - return fake.GetCurrConfigBlockStub(arg1) - } - if specificReturn { - return ret.result1 - } - fakeReturns := fake.getCurrConfigBlockReturns - return fakeReturns.result1 -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlockCallCount() int { - fake.getCurrConfigBlockMutex.RLock() - defer fake.getCurrConfigBlockMutex.RUnlock() - return len(fake.getCurrConfigBlockArgsForCall) -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlockCalls(stub func(string) *common.Block) { - fake.getCurrConfigBlockMutex.Lock() - defer fake.getCurrConfigBlockMutex.Unlock() - fake.GetCurrConfigBlockStub = stub -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlockArgsForCall(i int) string { - fake.getCurrConfigBlockMutex.RLock() - defer fake.getCurrConfigBlockMutex.RUnlock() - argsForCall := fake.getCurrConfigBlockArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlockReturns(result1 *common.Block) { - fake.getCurrConfigBlockMutex.Lock() - defer fake.getCurrConfigBlockMutex.Unlock() - fake.GetCurrConfigBlockStub = nil - fake.getCurrConfigBlockReturns = struct { - result1 *common.Block - }{result1} -} - -func (fake *ConfigBlockGetter) GetCurrConfigBlockReturnsOnCall(i int, result1 *common.Block) { - fake.getCurrConfigBlockMutex.Lock() - defer fake.getCurrConfigBlockMutex.Unlock() - fake.GetCurrConfigBlockStub = nil - if fake.getCurrConfigBlockReturnsOnCall == nil { - fake.getCurrConfigBlockReturnsOnCall = make(map[int]struct { - result1 *common.Block - }) - } - fake.getCurrConfigBlockReturnsOnCall[i] = struct { - result1 *common.Block - }{result1} -} - -func (fake *ConfigBlockGetter) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.getCurrConfigBlockMutex.RLock() - defer fake.getCurrConfigBlockMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *ConfigBlockGetter) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/discovery/support/mocks/config_getter.go b/discovery/support/mocks/config_getter.go new file mode 100644 index 00000000000..46771ab0672 --- /dev/null +++ b/discovery/support/mocks/config_getter.go @@ -0,0 +1,108 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mocks + +import ( + "sync" + + "github.com/hyperledger/fabric-protos-go/common" +) + +type ConfigGetter struct { + GetCurrConfigStub func(string) *common.Config + getCurrConfigMutex sync.RWMutex + getCurrConfigArgsForCall []struct { + arg1 string + } + getCurrConfigReturns struct { + result1 *common.Config + } + getCurrConfigReturnsOnCall map[int]struct { + result1 *common.Config + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *ConfigGetter) GetCurrConfig(arg1 string) *common.Config { + fake.getCurrConfigMutex.Lock() + ret, specificReturn := fake.getCurrConfigReturnsOnCall[len(fake.getCurrConfigArgsForCall)] + fake.getCurrConfigArgsForCall = append(fake.getCurrConfigArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("GetCurrConfig", []interface{}{arg1}) + fake.getCurrConfigMutex.Unlock() + if fake.GetCurrConfigStub != nil { + return fake.GetCurrConfigStub(arg1) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.getCurrConfigReturns + return fakeReturns.result1 +} + +func (fake *ConfigGetter) GetCurrConfigCallCount() int { + fake.getCurrConfigMutex.RLock() + defer fake.getCurrConfigMutex.RUnlock() + return len(fake.getCurrConfigArgsForCall) +} + +func (fake *ConfigGetter) GetCurrConfigCalls(stub func(string) *common.Config) { + fake.getCurrConfigMutex.Lock() + defer fake.getCurrConfigMutex.Unlock() + fake.GetCurrConfigStub = stub +} + +func (fake *ConfigGetter) GetCurrConfigArgsForCall(i int) string { + fake.getCurrConfigMutex.RLock() + defer fake.getCurrConfigMutex.RUnlock() + argsForCall := fake.getCurrConfigArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *ConfigGetter) GetCurrConfigReturns(result1 *common.Config) { + fake.getCurrConfigMutex.Lock() + defer fake.getCurrConfigMutex.Unlock() + fake.GetCurrConfigStub = nil + fake.getCurrConfigReturns = struct { + result1 *common.Config + }{result1} +} + +func (fake *ConfigGetter) GetCurrConfigReturnsOnCall(i int, result1 *common.Config) { + fake.getCurrConfigMutex.Lock() + defer fake.getCurrConfigMutex.Unlock() + fake.GetCurrConfigStub = nil + if fake.getCurrConfigReturnsOnCall == nil { + fake.getCurrConfigReturnsOnCall = make(map[int]struct { + result1 *common.Config + }) + } + fake.getCurrConfigReturnsOnCall[i] = struct { + result1 *common.Config + }{result1} +} + +func (fake *ConfigGetter) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getCurrConfigMutex.RLock() + defer fake.getCurrConfigMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *ConfigGetter) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/discovery/support/support.go b/discovery/support/support.go index 3c7afb30474..14d6108e533 100644 --- a/discovery/support/support.go +++ b/discovery/support/support.go @@ -41,9 +41,9 @@ type channelConfigGetter interface { acl.ChannelConfigGetter } -//go:generate counterfeiter -o mocks/config_block_getter.go --fake-name ConfigBlockGetter . configBlockGetter -type configBlockGetter interface { - config.CurrentConfigBlockGetter +//go:generate counterfeiter -o mocks/config_getter.go --fake-name ConfigGetter . configGetter +type configGetter interface { + config.CurrentConfigGetter } //go:generate counterfeiter -o mocks/configtx_validator.go --fake-name ConfigtxValidator . configtxValidator diff --git a/discovery/test/integration_test.go b/discovery/test/integration_test.go index 8c1b6f23a13..b851ef9fd50 100644 --- a/discovery/test/integration_test.go +++ b/discovery/test/integration_test.go @@ -447,9 +447,9 @@ func createSupport(t *testing.T, dir string, lsccMetadataManager *lsccMetadataMa ccSup := ccsupport.NewDiscoverySupport(lsccMetadataManager) ea := endorsement.NewEndorsementAnalyzer(gSup, ccSup, pe, lsccMetadataManager) - fakeBlockGetter := &mocks.ConfigBlockGetter{} - fakeBlockGetter.GetCurrConfigBlockReturns(createGenesisBlock(filepath.Join(dir, "crypto-config"))) - confSup := config.NewDiscoverySupport(fakeBlockGetter) + fakeConfigGetter := &mocks.ConfigGetter{} + fakeConfigGetter.GetCurrConfigReturns(createChannelConfig(t, filepath.Join(dir, "crypto-config"))) + confSup := config.NewDiscoverySupport(fakeConfigGetter) return &support{ Support: discsupport.NewDiscoverySupport(acl, gSup, ea, confSup, acl), mspWrapper: mspManagerWrapper, @@ -657,7 +657,7 @@ func generateChannelArtifacts() (string, error) { return dir, nil } -func createGenesisBlock(cryptoConfigDir string) *common.Block { +func createChannelConfig(t *testing.T, cryptoConfigDir string) *common.Config { appConfig := genesisconfig.Load("TwoOrgsChannel", "testdata") ordererConfig := genesisconfig.Load("TwoOrgsOrdererGenesis", "testdata") // Glue the two parts together, without loss of generality - to the application parts @@ -677,8 +677,12 @@ func createGenesisBlock(cryptoConfigDir string) *common.Block { org.MSPDir = filepath.Join(cryptoConfigDir, "peerOrganizations", fmt.Sprintf("org%d.example.com", i+1), "msp") } - channelGenerator := encoder.New(channelConfig) - return channelGenerator.GenesisBlockForChannel("mychannel") + channelGroup, err := encoder.NewChannelGroup(channelConfig) + require.NoError(t, err) + + return &common.Config{ + ChannelGroup: channelGroup, + } } type testPeer struct { diff --git a/internal/peer/node/start.go b/internal/peer/node/start.go index 3823e92571b..2b46d1871fb 100644 --- a/internal/peer/node/start.go +++ b/internal/peer/node/start.go @@ -954,17 +954,17 @@ func registerDiscoveryService( gSup := gossip.NewDiscoverySupport(gossipService) ccSup := ccsupport.NewDiscoverySupport(metadataProvider) ea := endorsement.NewEndorsementAnalyzer(gSup, ccSup, acl, metadataProvider) - confSup := config.NewDiscoverySupport(config.CurrentConfigBlockGetterFunc(func(channelID string) *common.Block { + confSup := config.NewDiscoverySupport(config.CurrentConfigGetterFunc(func(channelID string) *common.Config { channel := peerInstance.Channel(channelID) if channel == nil { return nil } - block, err := peer.ConfigBlockFromLedger(channel.Ledger()) + config, err := peer.RetrievePersistedChannelConfig(channel.Ledger()) if err != nil { - logger.Error("failed to get config block", err) + logger.Errorw("failed to get channel config", "error", err) return nil } - return block + return config })) support := discsupport.NewDiscoverySupport(acl, gSup, ea, confSup, acl) svc := discovery.NewService(discovery.Config{