2021-10-06 15:34:39 +00:00
|
|
|
package node
|
|
|
|
|
|
|
|
import (
|
2021-10-16 21:50:49 +00:00
|
|
|
"context"
|
2021-10-06 15:34:39 +00:00
|
|
|
|
2022-10-19 19:39:32 +00:00
|
|
|
"github.com/libp2p/go-libp2p/core/host"
|
|
|
|
"github.com/libp2p/go-libp2p/core/network"
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
2023-02-16 16:17:52 +00:00
|
|
|
"github.com/libp2p/go-libp2p/core/protocol"
|
2022-10-19 19:39:32 +00:00
|
|
|
"github.com/multiformats/go-multiaddr"
|
2022-11-09 19:53:01 +00:00
|
|
|
"github.com/waku-org/go-waku/logging"
|
2023-04-11 14:38:16 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/legacy_filter"
|
2022-11-09 19:53:01 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/lightpush"
|
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
|
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/store"
|
2022-01-18 18:17:06 +00:00
|
|
|
"go.uber.org/zap"
|
2023-08-03 16:21:15 +00:00
|
|
|
|
|
|
|
wps "github.com/waku-org/go-waku/waku/v2/peerstore"
|
2021-10-06 15:34:39 +00:00
|
|
|
)
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// PeerStatis is a map of peer IDs to supported protocols
|
2023-02-16 16:17:52 +00:00
|
|
|
type PeerStats map[peer.ID][]protocol.ID
|
2021-10-06 15:34:39 +00:00
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// ConnStatus is used to indicate if the node is online, has access to history
|
|
|
|
// and also see the list of peers the node is aware of
|
2021-10-06 15:34:39 +00:00
|
|
|
type ConnStatus struct {
|
|
|
|
IsOnline bool
|
|
|
|
HasHistory bool
|
|
|
|
Peers PeerStats
|
|
|
|
}
|
|
|
|
|
2023-05-10 14:13:10 +00:00
|
|
|
type PeerConnection struct {
|
|
|
|
PeerID peer.ID
|
|
|
|
Connected bool
|
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// ConnectionNotifier is a custom Notifier to be used to display when a peer
|
|
|
|
// connects or disconnects to the node
|
2021-10-06 15:34:39 +00:00
|
|
|
type ConnectionNotifier struct {
|
|
|
|
h host.Host
|
2021-10-16 21:50:49 +00:00
|
|
|
ctx context.Context
|
2022-05-27 13:25:06 +00:00
|
|
|
log *zap.Logger
|
2023-08-16 01:40:00 +00:00
|
|
|
metrics Metrics
|
2023-05-10 14:13:10 +00:00
|
|
|
connNotifCh chan<- PeerConnection
|
2021-10-06 15:34:39 +00:00
|
|
|
DisconnectChan chan peer.ID
|
|
|
|
}
|
|
|
|
|
2023-08-16 01:40:00 +00:00
|
|
|
// NewConnectionNotifier creates an instance of ConnectionNotifier to react to peer connection changes
|
|
|
|
func NewConnectionNotifier(ctx context.Context, h host.Host, connNotifCh chan<- PeerConnection, metrics Metrics, log *zap.Logger) ConnectionNotifier {
|
2021-10-06 15:34:39 +00:00
|
|
|
return ConnectionNotifier{
|
|
|
|
h: h,
|
2021-10-16 21:50:49 +00:00
|
|
|
ctx: ctx,
|
2021-10-06 15:34:39 +00:00
|
|
|
DisconnectChan: make(chan peer.ID, 100),
|
2023-05-10 14:13:10 +00:00
|
|
|
connNotifCh: connNotifCh,
|
2023-08-16 01:40:00 +00:00
|
|
|
metrics: metrics,
|
2023-05-10 14:13:10 +00:00
|
|
|
log: log.Named("connection-notifier"),
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// Listen is called when network starts listening on an addr
|
2022-10-19 19:39:32 +00:00
|
|
|
func (c ConnectionNotifier) Listen(n network.Network, m multiaddr.Multiaddr) {
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// ListenClose is called when network stops listening on an address
|
2022-10-19 19:39:32 +00:00
|
|
|
func (c ConnectionNotifier) ListenClose(n network.Network, m multiaddr.Multiaddr) {
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// Connected is called when a connection is opened
|
2021-10-06 15:34:39 +00:00
|
|
|
func (c ConnectionNotifier) Connected(n network.Network, cc network.Conn) {
|
2023-08-03 16:21:15 +00:00
|
|
|
c.log.Info("peer connected", logging.HostID("peer", cc.RemotePeer()), zap.String("direction", cc.Stat().Direction.String()))
|
2023-05-10 14:13:10 +00:00
|
|
|
if c.connNotifCh != nil {
|
|
|
|
select {
|
|
|
|
case c.connNotifCh <- PeerConnection{cc.RemotePeer(), true}:
|
|
|
|
default:
|
|
|
|
c.log.Warn("subscriber is too slow")
|
|
|
|
}
|
|
|
|
}
|
2023-08-03 16:21:15 +00:00
|
|
|
//TODO: Move this to be stored in Waku's own peerStore
|
|
|
|
err := c.h.Peerstore().(wps.WakuPeerstore).SetDirection(cc.RemotePeer(), cc.Stat().Direction)
|
|
|
|
if err != nil {
|
|
|
|
c.log.Error("Failed to set peer direction for an outgoing connection", zap.Error(err))
|
|
|
|
}
|
2023-08-16 01:40:00 +00:00
|
|
|
|
|
|
|
c.metrics.RecordPeerConnected()
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// Disconnected is called when a connection closed
|
2021-10-06 15:34:39 +00:00
|
|
|
func (c ConnectionNotifier) Disconnected(n network.Network, cc network.Conn) {
|
2022-05-27 13:25:06 +00:00
|
|
|
c.log.Info("peer disconnected", logging.HostID("peer", cc.RemotePeer()))
|
2023-08-16 01:40:00 +00:00
|
|
|
c.metrics.RecordPeerDisconnected()
|
2021-10-06 15:34:39 +00:00
|
|
|
c.DisconnectChan <- cc.RemotePeer()
|
2023-05-10 14:13:10 +00:00
|
|
|
if c.connNotifCh != nil {
|
|
|
|
select {
|
|
|
|
case c.connNotifCh <- PeerConnection{cc.RemotePeer(), false}:
|
|
|
|
default:
|
|
|
|
c.log.Warn("subscriber is too slow")
|
|
|
|
}
|
|
|
|
}
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// OpenedStream is called when a stream opened
|
2021-10-06 15:34:39 +00:00
|
|
|
func (c ConnectionNotifier) OpenedStream(n network.Network, s network.Stream) {
|
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// ClosedStream is called when a stream closed
|
2021-10-06 15:34:39 +00:00
|
|
|
func (c ConnectionNotifier) ClosedStream(n network.Network, s network.Stream) {
|
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// Close quits the ConnectionNotifier
|
2021-10-06 15:34:39 +00:00
|
|
|
func (c ConnectionNotifier) Close() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *WakuNode) sendConnStatus() {
|
|
|
|
isOnline, hasHistory := w.Status()
|
|
|
|
if w.connStatusChan != nil {
|
2021-11-10 13:36:51 +00:00
|
|
|
connStatus := ConnStatus{IsOnline: isOnline, HasHistory: hasHistory, Peers: w.PeerStats()}
|
2021-10-06 15:34:39 +00:00
|
|
|
w.connStatusChan <- connStatus
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-01-06 22:37:57 +00:00
|
|
|
func (w *WakuNode) connectednessListener(ctx context.Context) {
|
2021-11-23 15:03:12 +00:00
|
|
|
defer w.wg.Done()
|
|
|
|
|
2021-10-06 15:34:39 +00:00
|
|
|
for {
|
|
|
|
select {
|
2023-01-06 22:37:57 +00:00
|
|
|
case <-ctx.Done():
|
2021-10-06 15:34:39 +00:00
|
|
|
return
|
2022-02-24 13:40:18 +00:00
|
|
|
case <-w.protocolEventSub.Out():
|
|
|
|
case <-w.identificationEventSub.Out():
|
2021-10-06 19:25:41 +00:00
|
|
|
case <-w.connectionNotif.DisconnectChan:
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
w.sendConnStatus()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
// Status returns the current status of the node (online or not)
|
|
|
|
// and if the node has access to history nodes or not
|
2021-10-06 15:34:39 +00:00
|
|
|
func (w *WakuNode) Status() (isOnline bool, hasHistory bool) {
|
|
|
|
hasRelay := false
|
|
|
|
hasLightPush := false
|
|
|
|
hasStore := false
|
|
|
|
hasFilter := false
|
|
|
|
|
|
|
|
for _, peer := range w.host.Network().Peers() {
|
|
|
|
protocols, err := w.host.Peerstore().GetProtocols(peer)
|
|
|
|
if err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
w.log.Warn("reading peer protocols", logging.HostID("peer", peer), zap.Error(err))
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, protocol := range protocols {
|
2023-02-16 16:17:52 +00:00
|
|
|
if !hasRelay && protocol == relay.WakuRelayID_v200 {
|
2021-10-06 15:34:39 +00:00
|
|
|
hasRelay = true
|
|
|
|
}
|
2023-02-16 16:17:52 +00:00
|
|
|
if !hasLightPush && protocol == lightpush.LightPushID_v20beta1 {
|
2021-10-06 15:34:39 +00:00
|
|
|
hasLightPush = true
|
|
|
|
}
|
2023-02-16 16:17:52 +00:00
|
|
|
if !hasStore && protocol == store.StoreID_v20beta4 {
|
2021-10-06 15:34:39 +00:00
|
|
|
hasStore = true
|
|
|
|
}
|
2023-04-11 14:38:16 +00:00
|
|
|
if !hasFilter && protocol == legacy_filter.FilterID_v20beta1 {
|
2021-10-06 15:34:39 +00:00
|
|
|
hasFilter = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if hasStore {
|
|
|
|
hasHistory = true
|
|
|
|
}
|
|
|
|
|
2023-06-15 14:23:20 +00:00
|
|
|
if w.opts.enableFilterLightNode && !w.opts.enableRelay {
|
|
|
|
isOnline = hasLightPush && hasFilter
|
|
|
|
} else {
|
|
|
|
isOnline = hasRelay || hasLightPush && (hasStore || hasFilter)
|
2021-10-06 15:34:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|