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 }