github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/p2p/libp2pNode.go (about)

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  
     6  	kbucket "github.com/libp2p/go-libp2p-kbucket"
     7  	"github.com/libp2p/go-libp2p/core/host"
     8  	libp2pnet "github.com/libp2p/go-libp2p/core/network"
     9  	"github.com/libp2p/go-libp2p/core/peer"
    10  	"github.com/libp2p/go-libp2p/core/protocol"
    11  	"github.com/libp2p/go-libp2p/core/routing"
    12  
    13  	"github.com/onflow/flow-go/engine/collection"
    14  	"github.com/onflow/flow-go/module"
    15  	"github.com/onflow/flow-go/module/component"
    16  	"github.com/onflow/flow-go/module/irrecoverable"
    17  	"github.com/onflow/flow-go/network"
    18  	flownet "github.com/onflow/flow-go/network"
    19  	"github.com/onflow/flow-go/network/channels"
    20  	"github.com/onflow/flow-go/network/p2p/unicast/protocols"
    21  )
    22  
    23  // CoreP2P service management capabilities
    24  type CoreP2P interface {
    25  	// Start the libp2p node.
    26  	Start(ctx irrecoverable.SignalerContext)
    27  	// Stop terminates the libp2p node.
    28  	Stop() error
    29  	// GetIPPort returns the IP and Port the libp2p node is listening on.
    30  	GetIPPort() (string, string, error)
    31  	// Host returns pointer to host object of node.
    32  	Host() host.Host
    33  	// SetComponentManager sets the component manager for the node.
    34  	// SetComponentManager may be called at most once.
    35  	SetComponentManager(cm *component.ComponentManager)
    36  }
    37  
    38  // PeerManagement set of node traits related to its lifecycle and metadata retrieval
    39  type PeerManagement interface {
    40  	// ConnectToPeer connects to the peer with the given peer address information.
    41  	// This method is used to connect to a peer that is not in the peer store.
    42  	ConnectToPeer(ctx context.Context, peerInfo peer.AddrInfo) error
    43  	// RemovePeer closes the connection with the peer.
    44  	RemovePeer(peerID peer.ID) error
    45  	// ListPeers returns list of peer IDs for peers subscribed to the topic.
    46  	ListPeers(topic string) []peer.ID
    47  	// GetPeersForProtocol returns slice peer IDs for the specified protocol ID.
    48  	GetPeersForProtocol(pid protocol.ID) peer.IDSlice
    49  	// GetIPPort returns the IP and Port the libp2p node is listening on.
    50  	GetIPPort() (string, string, error)
    51  	// RoutingTable returns the node routing table
    52  	RoutingTable() *kbucket.RoutingTable
    53  	// Subscribe subscribes the node to the given topic and returns the subscription
    54  	Subscribe(topic channels.Topic, topicValidator TopicValidatorFunc) (Subscription, error)
    55  	// Unsubscribe cancels the subscriber and closes the topic corresponding to the given channel.
    56  	Unsubscribe(topic channels.Topic) error
    57  	// Publish publishes the given payload on the topic.
    58  	Publish(ctx context.Context, messageScope network.OutgoingMessageScope) error
    59  	// Host returns pointer to host object of node.
    60  	Host() host.Host
    61  	// ID returns the peer.ID of the node, which is the unique identifier of the node at the libp2p level.
    62  	// For other libp2p nodes, the current node is identified by this ID.
    63  	ID() peer.ID
    64  	// WithDefaultUnicastProtocol overrides the default handler of the unicast manager and registers all preferred protocols.
    65  	WithDefaultUnicastProtocol(defaultHandler libp2pnet.StreamHandler, preferred []protocols.ProtocolName) error
    66  	// WithPeersProvider sets the PeersProvider for the peer manager.
    67  	// If a peer manager factory is set, this method will set the peer manager's PeersProvider.
    68  	WithPeersProvider(peersProvider PeersProvider)
    69  	// PeerManagerComponent returns the component interface of the peer manager.
    70  	PeerManagerComponent() component.Component
    71  	// RequestPeerUpdate requests an update to the peer connections of this node using the peer manager.
    72  	RequestPeerUpdate()
    73  }
    74  
    75  // Routable set of node routing capabilities
    76  type Routable interface {
    77  	// RoutingTable returns the node routing table
    78  	RoutingTable() *kbucket.RoutingTable
    79  	// SetRouting sets the node's routing implementation.
    80  	// SetRouting may be called at most once.
    81  	// Returns:
    82  	// - error: An error, if any occurred during the process; any returned error is irrecoverable.
    83  	SetRouting(r routing.Routing) error
    84  	// Routing returns node routing object.
    85  	Routing() routing.Routing
    86  }
    87  
    88  // UnicastManagement abstracts the unicast management capabilities of the node.
    89  type UnicastManagement interface {
    90  	// OpenAndWriteOnStream opens a new stream to a peer with a protection tag. The protection tag can be used to ensure
    91  	// that the connection to the peer is maintained for a particular purpose. The stream is opened to the given peerID
    92  	// and writingLogic is executed on the stream. The created stream does not need to be reused and can be inexpensively
    93  	// created for each send. Moreover, the stream creation does not incur a round-trip time as the stream negotiation happens
    94  	// on an existing connection.
    95  	//
    96  	// Args:
    97  	// - ctx: The context used to control the stream's lifecycle.
    98  	// - peerID: The ID of the peer to open the stream to.
    99  	// - protectionTag: A tag that protects the connection and ensures that the connection manager keeps it alive, and
   100  	//   won't prune the connection while the tag is active.
   101  	// - writingLogic: A callback function that contains the logic for writing to the stream. It allows an external caller to
   102  	//   write to the stream without having to worry about the stream creation and management.
   103  	//
   104  	// Returns:
   105  	// error: An error, if any occurred during the process. This includes failure in creating the stream, setting the write
   106  	// deadline, executing the writing logic, resetting the stream if the writing logic fails, or closing the stream.
   107  	// All returned errors during this process can be considered benign.
   108  	OpenAndWriteOnStream(ctx context.Context, peerID peer.ID, protectionTag string, writingLogic func(stream libp2pnet.Stream) error) error
   109  	// WithDefaultUnicastProtocol overrides the default handler of the unicast manager and registers all preferred protocols.
   110  	WithDefaultUnicastProtocol(defaultHandler libp2pnet.StreamHandler, preferred []protocols.ProtocolName) error
   111  }
   112  
   113  // PubSub publish subscribe features for node
   114  type PubSub interface {
   115  	// Subscribe subscribes the node to the given topic and returns the subscription
   116  	Subscribe(topic channels.Topic, topicValidator TopicValidatorFunc) (Subscription, error)
   117  	// Unsubscribe cancels the subscriber and closes the topic.
   118  	Unsubscribe(topic channels.Topic) error
   119  	// Publish publishes the given payload on the topic.
   120  	Publish(ctx context.Context, messageScope flownet.OutgoingMessageScope) error
   121  	// SetPubSub sets the node's pubsub implementation.
   122  	// SetPubSub may be called at most once.
   123  	SetPubSub(ps PubSubAdapter)
   124  
   125  	// GetLocalMeshPeers returns the list of peers in the local mesh for the given topic.
   126  	// Args:
   127  	// - topic: the topic.
   128  	// Returns:
   129  	// - []peer.ID: the list of peers in the local mesh for the given topic.
   130  	GetLocalMeshPeers(topic channels.Topic) []peer.ID
   131  }
   132  
   133  // LibP2PNode represents a Flow libp2p node. It provides the network layer with the necessary interface to
   134  // control the underlying libp2p node. It is essentially the Flow wrapper around the libp2p node, and allows
   135  // us to define different types of libp2p nodes that can operate in different ways by overriding these methods.
   136  type LibP2PNode interface {
   137  	module.ReadyDoneAware
   138  	Subscriptions
   139  	// PeerConnections connection status information per peer.
   140  	PeerConnections
   141  	// PeerScore exposes the peer score API.
   142  	PeerScore
   143  	// DisallowListNotificationConsumer exposes the disallow list notification consumer API for the node so that
   144  	// it will be notified when a new disallow list update is distributed.
   145  	DisallowListNotificationConsumer
   146  	// CollectionClusterChangesConsumer  is the interface for consuming the events of changes in the collection cluster.
   147  	// This is used to notify the node of changes in the collection cluster.
   148  	// LibP2PNode implements this interface and consumes the events to be notified of changes in the clustering channels.
   149  	// The clustering channels are used by the collection nodes of a cluster to communicate with each other.
   150  	// As the cluster (and hence their cluster channels) of collection nodes changes over time (per epoch) the node needs to be notified of these changes.
   151  	CollectionClusterChangesConsumer
   152  	// DisallowListOracle exposes the disallow list oracle API for external consumers to query about the disallow list.
   153  	DisallowListOracle
   154  
   155  	// CoreP2P service management capabilities
   156  	CoreP2P
   157  
   158  	// PeerManagement current peer management functions
   159  	PeerManagement
   160  
   161  	// Routable routing related features
   162  	Routable
   163  
   164  	// PubSub publish subscribe features for node
   165  	PubSub
   166  
   167  	// UnicastManagement node stream management
   168  	UnicastManagement
   169  }
   170  
   171  // Subscriptions set of funcs related to current subscription info of a node.
   172  type Subscriptions interface {
   173  	// HasSubscription returns true if the node currently has an active subscription to the topic.
   174  	HasSubscription(topic channels.Topic) bool
   175  	// SetUnicastManager sets the unicast manager for the node.
   176  	SetUnicastManager(uniMgr UnicastManager)
   177  }
   178  
   179  // CollectionClusterChangesConsumer  is the interface for consuming the events of changes in the collection cluster.
   180  // This is used to notify the node of changes in the collection cluster.
   181  // LibP2PNode implements this interface and consumes the events to be notified of changes in the clustering channels.
   182  // The clustering channels are used by the collection nodes of a cluster to communicate with each other.
   183  // As the cluster (and hence their cluster channels) of collection nodes changes over time (per epoch) the node needs to be notified of these changes.
   184  type CollectionClusterChangesConsumer interface {
   185  	collection.ClusterEvents
   186  }
   187  
   188  // PeerScore is the interface for the peer score module. It is used to expose the peer score to other
   189  // components of the node. It is also used to set the peer score exposer implementation.
   190  type PeerScore interface {
   191  	// PeerScoreExposer returns the node's peer score exposer implementation.
   192  	// If the node's peer score exposer has not been set, the second return value will be false.
   193  	PeerScoreExposer() PeerScoreExposer
   194  }
   195  
   196  // PeerConnections subset of funcs related to underlying libp2p host connections.
   197  type PeerConnections interface {
   198  	// IsConnected returns true if address is a direct peer of this node else false.
   199  	// Peers are considered not connected if the underlying libp2p host reports the
   200  	// peers as not connected and there are no connections in the connection list.
   201  	// The following error returns indicate a bug in the code:
   202  	//  * network.ErrIllegalConnectionState if the underlying libp2p host reports connectedness as NotConnected but the connections list
   203  	// 	  to the peer is not empty. This indicates a bug within libp2p.
   204  	IsConnected(peerID peer.ID) (bool, error)
   205  }
   206  
   207  // DisallowListNotificationConsumer is an interface for consuming disallow/allow list update notifications.
   208  type DisallowListNotificationConsumer interface {
   209  	// OnDisallowListNotification is called when a new disallow list update notification is distributed.
   210  	// Any error on consuming event must handle internally.
   211  	// The implementation must be concurrency safe.
   212  	// Args:
   213  	// 	id: peer ID of the peer being disallow-listed.
   214  	// 	cause: cause of the peer being disallow-listed (only this cause is added to the peer's disallow-listed causes).
   215  	// Returns:
   216  	// 	none
   217  	OnDisallowListNotification(id peer.ID, cause network.DisallowListedCause)
   218  
   219  	// OnAllowListNotification is called when a new allow list update notification is distributed.
   220  	// Any error on consuming event must handle internally.
   221  	// The implementation must be concurrency safe.
   222  	// Args:
   223  	// 	id: peer ID of the peer being allow-listed.
   224  	// 	cause: cause of the peer being allow-listed (only this cause is removed from the peer's disallow-listed causes).
   225  	// Returns:
   226  	// 	none
   227  	OnAllowListNotification(id peer.ID, cause network.DisallowListedCause)
   228  }
   229  
   230  // DisallowListOracle is an interface for querying disallow-listed peers.
   231  type DisallowListOracle interface {
   232  	// IsDisallowListed determines whether the given peer is disallow-listed for any reason.
   233  	// Args:
   234  	// - peerID: the peer to check.
   235  	// Returns:
   236  	// - []network.DisallowListedCause: the list of causes for which the given peer is disallow-listed. If the peer is not disallow-listed for any reason,
   237  	// a nil slice is returned.
   238  	// - bool: true if the peer is disallow-listed for any reason, false otherwise.
   239  	IsDisallowListed(peerId peer.ID) ([]network.DisallowListedCause, bool)
   240  }