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  }