github.com/ewagmig/fabric@v2.1.1+incompatible/gossip/service/eventer.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package service 8 9 import ( 10 "reflect" 11 12 "github.com/hyperledger/fabric-protos-go/peer" 13 "github.com/hyperledger/fabric/common/channelconfig" 14 "github.com/hyperledger/fabric/msp" 15 ) 16 17 // Config enumerates the configuration methods required by gossip 18 type Config interface { 19 // ChannelID returns the ChannelID for this channel 20 ChannelID() string 21 22 // Organizations returns a map of org ID to ApplicationOrgConfig 23 Organizations() map[string]channelconfig.ApplicationOrg 24 25 // Sequence should return the sequence number of the current configuration 26 Sequence() uint64 27 28 // OrdererAddresses returns the list of valid orderer addresses to connect to to invoke Broadcast/Deliver 29 OrdererAddresses() []string 30 } 31 32 // ConfigProcessor receives config updates 33 type ConfigProcessor interface { 34 // ProcessConfigUpdate should be invoked whenever a channel's configuration is initialized or updated 35 ProcessConfigUpdate(config Config) 36 } 37 38 type configStore struct { 39 anchorPeers []*peer.AnchorPeer 40 orgMap map[string]channelconfig.ApplicationOrg 41 } 42 43 type configEventReceiver interface { 44 updateAnchors(config Config) 45 } 46 47 type configEventer struct { 48 lastConfig *configStore 49 receiver configEventReceiver 50 } 51 52 func newConfigEventer(receiver configEventReceiver) *configEventer { 53 return &configEventer{ 54 receiver: receiver, 55 } 56 } 57 58 // ProcessConfigUpdate should be invoked whenever a channel's configuration is initialized or updated 59 // it invokes the associated method in configEventReceiver when configuration is updated 60 // but only if the configuration value actually changed 61 // Note, that a changing sequence number is ignored as changing configuration 62 func (ce *configEventer) ProcessConfigUpdate(config Config) { 63 logger.Debugf("Processing new config for channel %s", config.ChannelID()) 64 orgMap := cloneOrgConfig(config.Organizations()) 65 if ce.lastConfig != nil && reflect.DeepEqual(ce.lastConfig.orgMap, orgMap) { 66 logger.Debugf("Ignoring new config for channel %s because it contained no anchor peer updates", config.ChannelID()) 67 } else { 68 69 var newAnchorPeers []*peer.AnchorPeer 70 for _, group := range config.Organizations() { 71 newAnchorPeers = append(newAnchorPeers, group.AnchorPeers()...) 72 } 73 74 newConfig := &configStore{ 75 orgMap: orgMap, 76 anchorPeers: newAnchorPeers, 77 } 78 ce.lastConfig = newConfig 79 80 logger.Debugf("Calling out because config was updated for channel %s", config.ChannelID()) 81 ce.receiver.updateAnchors(config) 82 } 83 } 84 85 func cloneOrgConfig(src map[string]channelconfig.ApplicationOrg) map[string]channelconfig.ApplicationOrg { 86 clone := make(map[string]channelconfig.ApplicationOrg) 87 for k, v := range src { 88 clone[k] = &appGrp{ 89 name: v.Name(), 90 mspID: v.MSPID(), 91 anchorPeers: v.AnchorPeers(), 92 } 93 } 94 return clone 95 } 96 97 type appGrp struct { 98 name string 99 mspID string 100 anchorPeers []*peer.AnchorPeer 101 } 102 103 func (ag *appGrp) Name() string { 104 return ag.name 105 } 106 107 func (ag *appGrp) MSPID() string { 108 return ag.mspID 109 } 110 111 func (ag *appGrp) AnchorPeers() []*peer.AnchorPeer { 112 return ag.anchorPeers 113 } 114 115 func (ag *appGrp) MSP() msp.MSP { 116 return nil 117 }