github.com/onflow/flow-go@v0.33.17/network/p2p/consumers.go (about) 1 package p2p 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/module/component" 8 p2pmsg "github.com/onflow/flow-go/network/p2p/message" 9 ) 10 11 // GossipSubInspectorNotifDistributor is the interface for the distributor that distributes gossip sub inspector notifications. 12 // It is used to distribute notifications to the consumers in an asynchronous manner and non-blocking manner. 13 // The implementation should guarantee that all registered consumers are called upon distribution of a new event. 14 type GossipSubInspectorNotifDistributor interface { 15 component.Component 16 // Distribute distributes the event to all the consumers. 17 // Any error returned by the distributor is non-recoverable and will cause the node to crash. 18 // Implementation must be concurrency safe, and non-blocking. 19 Distribute(notification *InvCtrlMsgNotif) error 20 21 // AddConsumer adds a consumer to the distributor. The consumer will be called the distributor distributes a new event. 22 // AddConsumer must be concurrency safe. Once a consumer is added, it must be called for all future events. 23 // There is no guarantee that the consumer will be called for events that were already received by the distributor. 24 AddConsumer(GossipSubInvCtrlMsgNotifConsumer) 25 } 26 27 // CtrlMsgTopicType represents the type of the topic within a control message. 28 type CtrlMsgTopicType uint64 29 30 const ( 31 // CtrlMsgNonClusterTopicType represents a non-cluster-prefixed topic. 32 CtrlMsgNonClusterTopicType CtrlMsgTopicType = iota 33 // CtrlMsgTopicTypeClusterPrefixed represents a cluster-prefixed topic. 34 CtrlMsgTopicTypeClusterPrefixed 35 ) 36 37 func (t CtrlMsgTopicType) String() string { 38 switch t { 39 case CtrlMsgNonClusterTopicType: 40 return "non-cluster-prefixed" 41 case CtrlMsgTopicTypeClusterPrefixed: 42 return "cluster-prefixed" 43 default: 44 return "unknown" 45 } 46 } 47 48 // InvCtrlMsgNotif is the notification sent to the consumer when an invalid control message is received. 49 // It models the information that is available to the consumer about a misbehaving peer. 50 type InvCtrlMsgNotif struct { 51 // PeerID is the ID of the peer that sent the invalid control message. 52 PeerID peer.ID 53 // Error the error that occurred during validation. 54 Error error 55 // MsgType the control message type. 56 MsgType p2pmsg.ControlMessageType 57 // Count the number of errors. 58 Count uint64 59 // TopicType reports whether the error occurred on a cluster-prefixed topic within the control message. 60 // Notifications must be explicitly marked as cluster-prefixed or not because the penalty applied to the GossipSub score 61 // for an error on a cluster-prefixed topic is more lenient than the penalty applied to a non-cluster-prefixed topic. 62 // This distinction ensures that nodes engaged in cluster-prefixed topic communication are not penalized too harshly, 63 // as such communication is vital to the progress of the chain. 64 TopicType CtrlMsgTopicType 65 } 66 67 // NewInvalidControlMessageNotification returns a new *InvCtrlMsgNotif 68 // Args: 69 // - peerID: peer id of the offender. 70 // - ctlMsgType: the control message type of the rpc message that caused the error. 71 // - err: the error that occurred. 72 // - count: the number of occurrences of the error. 73 // 74 // Returns: 75 // - *InvCtlMsgNotif: invalid control message notification. 76 func NewInvalidControlMessageNotification(peerID peer.ID, ctlMsgType p2pmsg.ControlMessageType, err error, count uint64, topicType CtrlMsgTopicType) *InvCtrlMsgNotif { 77 return &InvCtrlMsgNotif{ 78 PeerID: peerID, 79 Error: err, 80 MsgType: ctlMsgType, 81 Count: count, 82 TopicType: topicType, 83 } 84 } 85 86 // GossipSubInvCtrlMsgNotifConsumer is the interface for the consumer that consumes gossipsub inspector notifications. 87 // It is used to consume notifications in an asynchronous manner. 88 // The implementation must be concurrency safe, but can be blocking. This is due to the fact that the consumer is called 89 // asynchronously by the distributor. 90 type GossipSubInvCtrlMsgNotifConsumer interface { 91 // OnInvalidControlMessageNotification is called when a new invalid control message notification is distributed. 92 // Any error on consuming event must handle internally. 93 // The implementation must be concurrency safe, but can be blocking. 94 OnInvalidControlMessageNotification(*InvCtrlMsgNotif) 95 } 96 97 // GossipSubInspectorSuite is the interface for the GossipSub inspector suite. 98 // It encapsulates the rpc inspectors and the notification distributors. 99 type GossipSubInspectorSuite interface { 100 component.Component 101 CollectionClusterChangesConsumer 102 // InspectFunc returns the inspect function that is used to inspect the gossipsub rpc messages. 103 // This function follows a dependency injection pattern, where the inspect function is injected into the gossipsu, and 104 // is called whenever a gossipsub rpc message is received. 105 InspectFunc() func(peer.ID, *pubsub.RPC) error 106 107 // AddInvalidControlMessageConsumer adds a consumer to the invalid control message notification distributor. 108 // This consumer is notified when a misbehaving peer regarding gossipsub control messages is detected. This follows a pub/sub 109 // pattern where the consumer is notified when a new notification is published. 110 // A consumer is only notified once for each notification, and only receives notifications that were published after it was added. 111 AddInvalidControlMessageConsumer(GossipSubInvCtrlMsgNotifConsumer) 112 }