Skip to content

Commit

Permalink
Fix channel config callback in gateway
Browse files Browse the repository at this point in the history
Currently, the config update callback triggers a discovery call to get the updated channel orderers.
However, this relies on the discovery service having processed the config message before the gateway.  If it hasn’t, the gateway just gets the stale orderer config.
This commit changes the logic so the gateway extracts the orderer endpoints directly from the config bundle.

Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>
(cherry picked from commit 8576508)
  • Loading branch information
andrew-coleman authored and denyeart committed Dec 8, 2021
1 parent abf5d30 commit 654a02b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 22 deletions.
6 changes: 3 additions & 3 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,14 @@ func (p *Peer) createChannel(
cryptoProvider: p.CryptoProvider,
}

callbacks := append(
p.configCallbacks,
callbacks := []channelconfig.BundleActor{
ordererSourceCallback,
gossipCallbackWrapper,
trustedRootsCallbackWrapper,
mspCallback,
channel.bundleUpdate,
)
}
callbacks = append(callbacks, p.configCallbacks...)

channel.bundleSource = channelconfig.NewBundleSource(
bundle,
Expand Down
29 changes: 18 additions & 11 deletions internal/pkg/gateway/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,27 +400,34 @@ func (reg *registry) config(channel string) ([]*endpointConfig, error) {
}
var channelOrderers []*endpointConfig
for mspid, eps := range config.GetOrderers() {
var tlsRootCerts [][]byte
if mspInfo, ok := config.GetMsps()[mspid]; ok {
tlsRootCerts = mspInfo.GetTlsRootCerts()
}
for _, ep := range eps.Endpoint {
address := fmt.Sprintf("%s:%d", ep.Host, ep.Port)
var tlsRootCerts [][]byte
if mspInfo, ok := config.GetMsps()[mspid]; ok {
tlsRootCerts = mspInfo.GetTlsRootCerts()
}
channelOrderers = append(channelOrderers, &endpointConfig{address: address, mspid: mspid, tlsRootCerts: tlsRootCerts})
}
}
return channelOrderers, nil
}

func (reg *registry) configUpdate(bundle *channelconfig.Bundle) {
if _, ok := bundle.OrdererConfig(); ok {
// orderer config has changed - invalidate the cache for this channel
if ordererConfig, ok := bundle.OrdererConfig(); ok {
// orderer config has changed - process the bundle
channel := bundle.ConfigtxValidator().ChannelID()
channelOrderers, err := reg.config(channel)
if err != nil {
reg.logger.Errorw("Failed update orderer config", "channel", channel, "err", err)
return
reg.logger.Infow("Updating orderer config", "channel", channel)
var channelOrderers []*endpointConfig
for _, org := range ordererConfig.Organizations() {
mspid := org.MSPID()
tlsRootCerts := org.MSP().GetTLSRootCerts()
for _, address := range org.Endpoints() {
channelOrderers = append(channelOrderers, &endpointConfig{address: address, mspid: mspid, tlsRootCerts: tlsRootCerts})
reg.logger.Debugw("Channel orderer", "address", address, "mspid", mspid)
}
}
if len(channelOrderers) > 0 {
reg.channelOrderers.Store(channel, channelOrderers)
}
reg.channelOrderers.Store(channel, channelOrderers)
}
}
10 changes: 2 additions & 8 deletions internal/pkg/gateway/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,7 @@ func TestOrdererCache(t *testing.T) {
require.NoError(t, err)
require.Len(t, orderers, 1)

// add 2 more orderer nodes
test.discovery.ConfigReturns(buildConfig(t, []string{"orderer1", "orderer2", "orderer3"}), nil)
// the config is cached in the registry - so will still return the single orderer
orderers, err = test.server.registry.orderers(channelName)
require.NoError(t, err)
require.Len(t, orderers, 1)

// the config update callback is triggered, which will invalidate the cache
// trigger the config update callback, updating the orderers
bundle, err := createChannelConfigBundle()
require.NoError(t, err)
test.server.registry.configUpdate(bundle)
Expand Down Expand Up @@ -74,6 +67,7 @@ func buildConfig(t *testing.T, orderers []string) *dp.ConfigResult {
func createChannelConfigBundle() (*channelconfig.Bundle, error) {
conf := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir())
conf.Capabilities = map[string]bool{"V2_0": true}
conf.Orderer.Organizations[0].OrdererEndpoints = []string{"orderer1", "orderer2", "orderer3"}

cg, err := encoder.NewChannelGroup(conf)
if err != nil {
Expand Down

0 comments on commit 654a02b

Please sign in to comment.