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

     1  package connection
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/libp2p/go-libp2p/core/connmgr"
     8  	"github.com/libp2p/go-libp2p/core/network"
     9  	"github.com/libp2p/go-libp2p/core/peer"
    10  	libp2pconnmgr "github.com/libp2p/go-libp2p/p2p/net/connmgr"
    11  	"github.com/rs/zerolog"
    12  
    13  	"github.com/onflow/flow-go/module"
    14  	"github.com/onflow/flow-go/network/netconf"
    15  	"github.com/onflow/flow-go/network/p2p/connection/internal"
    16  )
    17  
    18  // ConnManager provides an implementation of Libp2p's ConnManager interface (https://pkg.go.dev/github.com/libp2p/go-libp2p/core/connmgr#ConnManager)
    19  // It is called back by libp2p when certain events occur such as opening/closing a stream, opening/closing connection etc.
    20  // Current implementation primarily acts as a wrapper around libp2p's BasicConnMgr (https://pkg.go.dev/github.com/libp2p/go-libp2p/p2p/net/connmgr#BasicConnMgr).
    21  // However, we override the notifiee callback to add additional functionality so that it provides metrics and logging instrumentation for Flow.
    22  type ConnManager struct {
    23  	basicConnMgr *libp2pconnmgr.BasicConnMgr
    24  	n            network.Notifiee // the notifiee callback provided by libp2p
    25  	log          zerolog.Logger   // logger to log connection, stream and other statistics about libp2p
    26  }
    27  
    28  var _ connmgr.ConnManager = (*ConnManager)(nil)
    29  
    30  // NewConnManager creates a new connection manager.
    31  // It errors if creating the basic connection manager of libp2p fails.
    32  // The error is not benign, and we should crash the node if it happens.
    33  // It is a malpractice to start the node without connection manager.
    34  func NewConnManager(logger zerolog.Logger, metric module.LibP2PConnectionMetrics, cfg *netconf.ConnectionManager) (*ConnManager, error) {
    35  	basic, err := libp2pconnmgr.NewConnManager(
    36  		cfg.LowWatermark,
    37  		cfg.HighWatermark,
    38  		libp2pconnmgr.WithGracePeriod(cfg.GracePeriod),
    39  		libp2pconnmgr.WithSilencePeriod(cfg.SilencePeriod))
    40  	if err != nil {
    41  		return nil, fmt.Errorf("failed to create basic connection manager of libp2p: %w", err)
    42  	}
    43  
    44  	cn := &ConnManager{
    45  		log:          logger.With().Str("component", "connection_manager").Logger(),
    46  		basicConnMgr: basic,
    47  	}
    48  
    49  	// aggregates the notifiee callbacks from libp2p and our own notifiee into one.
    50  	cn.n = internal.NewRelayNotifee(internal.NewLoggerNotifiee(cn.log, metric), cn.basicConnMgr.Notifee())
    51  
    52  	cn.log.Info().
    53  		Int("low_watermark", cfg.LowWatermark).
    54  		Int("high_watermark", cfg.HighWatermark).
    55  		Dur("grace_period", cfg.GracePeriod).
    56  		Dur("silence_period", cfg.SilencePeriod).
    57  		Msg("connection manager initialized")
    58  
    59  	return cn, nil
    60  }
    61  
    62  func (cm *ConnManager) Notifee() network.Notifiee {
    63  	return cm.n
    64  }
    65  
    66  func (cm *ConnManager) Protect(id peer.ID, tag string) {
    67  	cm.basicConnMgr.Protect(id, tag)
    68  }
    69  
    70  func (cm *ConnManager) Unprotect(id peer.ID, tag string) bool {
    71  	return cm.basicConnMgr.Unprotect(id, tag)
    72  }
    73  
    74  func (cm *ConnManager) IsProtected(id peer.ID, tag string) bool {
    75  	return cm.basicConnMgr.IsProtected(id, tag)
    76  }
    77  
    78  func (cm *ConnManager) TagPeer(id peer.ID, s string, i int) {
    79  	cm.basicConnMgr.TagPeer(id, s, i)
    80  }
    81  
    82  func (cm *ConnManager) UntagPeer(p peer.ID, tag string) {
    83  	cm.basicConnMgr.UntagPeer(p, tag)
    84  }
    85  
    86  func (cm *ConnManager) UpsertTag(p peer.ID, tag string, upsert func(int) int) {
    87  	cm.basicConnMgr.UpsertTag(p, tag, upsert)
    88  }
    89  
    90  func (cm *ConnManager) GetTagInfo(p peer.ID) *connmgr.TagInfo {
    91  	return cm.basicConnMgr.GetTagInfo(p)
    92  }
    93  
    94  func (cm *ConnManager) TrimOpenConns(ctx context.Context) {
    95  	cm.basicConnMgr.TrimOpenConns(ctx)
    96  }
    97  
    98  func (cm *ConnManager) Close() error {
    99  	return cm.basicConnMgr.Close()
   100  }
   101  
   102  func (cm *ConnManager) CheckLimit(l connmgr.GetConnLimiter) error {
   103  	return cm.basicConnMgr.CheckLimit(l)
   104  }