github.com/onflow/flow-go@v0.33.17/network/p2p/builder/inspector/suite.go (about)

     1  package inspector
     2  
     3  import (
     4  	pubsub "github.com/libp2p/go-libp2p-pubsub"
     5  	"github.com/libp2p/go-libp2p/core/peer"
     6  
     7  	"github.com/onflow/flow-go/model/flow"
     8  	"github.com/onflow/flow-go/module/component"
     9  	"github.com/onflow/flow-go/module/irrecoverable"
    10  	"github.com/onflow/flow-go/network/p2p"
    11  	"github.com/onflow/flow-go/network/p2p/inspector/validation"
    12  )
    13  
    14  // GossipSubInspectorSuite encapsulates what is exposed to the libp2p node regarding the gossipsub RPC inspectors as
    15  // well as their notification distributors.
    16  type GossipSubInspectorSuite struct {
    17  	component.Component
    18  	aggregatedInspector       *AggregateRPCInspector
    19  	validationInspector       *validation.ControlMsgValidationInspector
    20  	ctrlMsgInspectDistributor p2p.GossipSubInspectorNotifDistributor
    21  }
    22  
    23  // TODO: this can be simplified as there is no more need for the aggregated inspector.
    24  var _ p2p.GossipSubInspectorSuite = (*GossipSubInspectorSuite)(nil)
    25  
    26  // NewGossipSubInspectorSuite creates a new GossipSubInspectorSuite.
    27  // The suite is composed of the aggregated inspector, which is used to inspect the gossipsub rpc messages, and the
    28  // control message notification distributor, which is used to notify consumers when a misbehaving peer regarding gossipsub
    29  // control messages is detected.
    30  // The suite is also a component, which is used to start and stop the rpc inspectors.
    31  // Args:
    32  //   - metricsInspector: the control message metrics inspector.
    33  //   - validationInspector: the gossipsub validation control message validation inspector.
    34  //   - ctrlMsgInspectDistributor: the notification distributor that is used to notify consumers when a misbehaving peer
    35  //
    36  // regarding gossipsub control messages is detected.
    37  // Returns:
    38  //   - the new GossipSubInspectorSuite.
    39  func NewGossipSubInspectorSuite(
    40  	validationInspector *validation.ControlMsgValidationInspector,
    41  	ctrlMsgInspectDistributor p2p.GossipSubInspectorNotifDistributor) *GossipSubInspectorSuite {
    42  	inspectors := []p2p.GossipSubRPCInspector{validationInspector}
    43  	s := &GossipSubInspectorSuite{
    44  		ctrlMsgInspectDistributor: ctrlMsgInspectDistributor,
    45  		validationInspector:       validationInspector,
    46  		aggregatedInspector:       NewAggregateRPCInspector(inspectors...),
    47  	}
    48  
    49  	builder := component.NewComponentManagerBuilder()
    50  	for _, rpcInspector := range inspectors {
    51  		rpcInspector := rpcInspector // capture loop variable
    52  		builder.AddWorker(func(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
    53  			rpcInspector.Start(ctx)
    54  
    55  			select {
    56  			case <-ctx.Done():
    57  			case <-rpcInspector.Ready():
    58  				ready()
    59  			}
    60  
    61  			<-rpcInspector.Done()
    62  		})
    63  	}
    64  
    65  	s.Component = builder.Build()
    66  	return s
    67  }
    68  
    69  // InspectFunc returns the inspect function that is used to inspect the gossipsub rpc messages.
    70  // This function follows a dependency injection pattern, where the inspect function is injected into the gossipsu, and
    71  // is called whenever a gossipsub rpc message is received.
    72  func (s *GossipSubInspectorSuite) InspectFunc() func(peer.ID, *pubsub.RPC) error {
    73  	return s.aggregatedInspector.Inspect
    74  }
    75  
    76  // AddInvalidControlMessageConsumer adds a consumer to the invalid control message notification distributor.
    77  // This consumer is notified when a misbehaving peer regarding gossipsub control messages is detected. This follows a pub/sub
    78  // pattern where the consumer is notified when a new notification is published.
    79  // A consumer is only notified once for each notification, and only receives notifications that were published after it was added.
    80  func (s *GossipSubInspectorSuite) AddInvalidControlMessageConsumer(c p2p.GossipSubInvCtrlMsgNotifConsumer) {
    81  	s.ctrlMsgInspectDistributor.AddConsumer(c)
    82  }
    83  
    84  // ActiveClustersChanged is called when the list of active collection nodes cluster is changed.
    85  // GossipSubInspectorSuite consumes this event and forwards it to all the respective rpc inspectors, that are
    86  // concerned with this cluster-based topics (i.e., channels), so that they can update their internal state.
    87  func (s *GossipSubInspectorSuite) ActiveClustersChanged(list flow.ChainIDList) {
    88  	for _, rpcInspector := range s.aggregatedInspector.Inspectors() {
    89  		if r, ok := rpcInspector.(p2p.GossipSubMsgValidationRpcInspector); ok {
    90  			r.ActiveClustersChanged(list)
    91  		}
    92  	}
    93  }