feat: lightclient err handling (#1160)

This commit is contained in:
Prem Chaitanya Prathi 2024-07-15 19:47:27 +05:30 committed by GitHub
parent 9fbb955b16
commit dacff8a6ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 36 additions and 23 deletions

View File

@ -147,6 +147,17 @@ func (wf *WakuFilterLightNode) Stop() {
}) })
} }
func (wf *WakuFilterLightNode) unsubscribeWithoutSubscription(cf protocol.ContentFilter, peerID peer.ID) {
err := wf.request(
wf.Context(),
protocol.GenerateRequestID(),
pb.FilterSubscribeRequest_UNSUBSCRIBE_ALL,
cf, peerID)
if err != nil {
wf.log.Warn("could not unsubscribe from peer", logging.HostID("peerID", peerID), zap.Error(err))
}
}
func (wf *WakuFilterLightNode) onRequest(ctx context.Context) func(network.Stream) { func (wf *WakuFilterLightNode) onRequest(ctx context.Context) func(network.Stream) {
return func(stream network.Stream) { return func(stream network.Stream) {
peerID := stream.Conn().RemotePeer() peerID := stream.Conn().RemotePeer()
@ -156,6 +167,9 @@ func (wf *WakuFilterLightNode) onRequest(ctx context.Context) func(network.Strea
if !wf.subscriptions.IsSubscribedTo(peerID) { if !wf.subscriptions.IsSubscribedTo(peerID) {
logger.Warn("received message push from unknown peer", logging.HostID("peerID", peerID)) logger.Warn("received message push from unknown peer", logging.HostID("peerID", peerID))
wf.metrics.RecordError(unknownPeerMessagePush) wf.metrics.RecordError(unknownPeerMessagePush)
//Send a wildcard unsubscribe to this peer so that further requests are not forwarded to us
//This could be happening due to https://github.com/waku-org/go-waku/issues/1124
go wf.unsubscribeWithoutSubscription(protocol.ContentFilter{}, peerID)
if err := stream.Reset(); err != nil { if err := stream.Reset(); err != nil {
wf.log.Error("resetting connection", zap.Error(err)) wf.log.Error("resetting connection", zap.Error(err))
} }
@ -199,22 +213,24 @@ func (wf *WakuFilterLightNode) onRequest(ctx context.Context) func(network.Strea
} }
logger = messagePush.WakuMessage.Logger(logger, pubSubTopic) logger = messagePush.WakuMessage.Logger(logger, pubSubTopic)
cf := protocol.NewContentFilter(pubSubTopic, messagePush.WakuMessage.ContentTopic)
if !wf.subscriptions.Has(peerID, protocol.NewContentFilter(pubSubTopic, messagePush.WakuMessage.ContentTopic)) { if !wf.subscriptions.Has(peerID, cf) {
logger.Warn("received messagepush with invalid subscription parameters") logger.Warn("received messagepush with invalid subscription parameters")
//Unsubscribe from that peer for the contentTopic, possibly due to https://github.com/waku-org/go-waku/issues/1124
go wf.unsubscribeWithoutSubscription(cf, peerID)
wf.metrics.RecordError(invalidSubscriptionMessage) wf.metrics.RecordError(invalidSubscriptionMessage)
return return
} }
wf.metrics.RecordMessage() wf.metrics.RecordMessage()
wf.notify(peerID, pubSubTopic, messagePush.WakuMessage) wf.notify(ctx, peerID, pubSubTopic, messagePush.WakuMessage)
logger.Info("received message push") logger.Info("received message push")
} }
} }
func (wf *WakuFilterLightNode) notify(remotePeerID peer.ID, pubsubTopic string, msg *wpb.WakuMessage) { func (wf *WakuFilterLightNode) notify(ctx context.Context, remotePeerID peer.ID, pubsubTopic string, msg *wpb.WakuMessage) {
envelope := protocol.NewEnvelope(msg, wf.timesource.Now().UnixNano(), pubsubTopic) envelope := protocol.NewEnvelope(msg, wf.timesource.Now().UnixNano(), pubsubTopic)
if wf.broadcaster != nil { if wf.broadcaster != nil {
@ -222,7 +238,7 @@ func (wf *WakuFilterLightNode) notify(remotePeerID peer.ID, pubsubTopic string,
wf.broadcaster.Submit(envelope) wf.broadcaster.Submit(envelope)
} }
// Notify filter subscribers // Notify filter subscribers
wf.subscriptions.Notify(remotePeerID, envelope) wf.subscriptions.Notify(ctx, remotePeerID, envelope)
} }
func (wf *WakuFilterLightNode) request(ctx context.Context, requestID []byte, func (wf *WakuFilterLightNode) request(ctx context.Context, requestID []byte,

View File

@ -189,13 +189,6 @@ func (wakuLP *WakuLightPush) reply(stream network.Stream, responsePushRPC *pb.Pu
// request sends a message via lightPush protocol to either a specified peer or peer that is selected. // request sends a message via lightPush protocol to either a specified peer or peer that is selected.
func (wakuLP *WakuLightPush) request(ctx context.Context, req *pb.PushRequest, params *lightPushRequestParameters, peer peer.ID) (*pb.PushResponse, error) { func (wakuLP *WakuLightPush) request(ctx context.Context, req *pb.PushRequest, params *lightPushRequestParameters, peer peer.ID) (*pb.PushResponse, error) {
if params == nil {
return nil, errors.New("lightpush params are mandatory")
}
if len(params.requestID) == 0 {
return nil, ErrInvalidID
}
logger := wakuLP.log.With(logging.HostID("peer", peer)) logger := wakuLP.log.With(logging.HostID("peer", peer))
@ -336,8 +329,10 @@ func (wakuLP *WakuLightPush) Publish(ctx context.Context, message *wpb.WakuMessa
for _, peerID := range params.selectedPeers { for _, peerID := range params.selectedPeers {
wg.Add(1) wg.Add(1)
go func(id peer.ID) { go func(id peer.ID) {
paramsValue := *params
paramsValue.requestID = protocol.GenerateRequestID()
defer wg.Done() defer wg.Done()
response, err := wakuLP.request(ctx, req, params, id) response, err := wakuLP.request(ctx, req, &paramsValue, id)
if err != nil { if err != nil {
logger.Error("could not publish message", zap.Error(err), zap.Stringer("peer", id)) logger.Error("could not publish message", zap.Error(err), zap.Stringer("peer", id))
} }

View File

@ -133,7 +133,6 @@ func WithAutomaticRequestID() RequestOption {
// DefaultOptions are the default options to be used when using the lightpush protocol // DefaultOptions are the default options to be used when using the lightpush protocol
func DefaultOptions(host host.Host) []RequestOption { func DefaultOptions(host host.Host) []RequestOption {
return []RequestOption{ return []RequestOption{
WithAutomaticRequestID(),
WithAutomaticPeerSelection(), WithAutomaticPeerSelection(),
WithMaxPeers(1), //keeping default as 2 for status use-case WithMaxPeers(1), //keeping default as 2 for status use-case
} }

View File

@ -1,6 +1,7 @@
package subscription package subscription
import ( import (
"context"
"errors" "errors"
"sync" "sync"
@ -178,17 +179,17 @@ func (sub *SubscriptionsMap) Clear() {
sub.clear() sub.clear()
} }
func (sub *SubscriptionsMap) Notify(peerID peer.ID, envelope *protocol.Envelope) { func (sub *SubscriptionsMap) Notify(ctx context.Context, peerID peer.ID, envelope *protocol.Envelope) {
sub.RLock() sub.RLock()
defer sub.RUnlock() defer sub.RUnlock()
subscriptions, ok := sub.items[peerID].SubsPerPubsubTopic[envelope.PubsubTopic()] subscriptions, ok := sub.items[peerID].SubsPerPubsubTopic[envelope.PubsubTopic()]
if ok { if ok {
iterateSubscriptionSet(sub.logger, subscriptions, envelope) iterateSubscriptionSet(ctx, sub.logger, subscriptions, envelope)
} }
} }
func iterateSubscriptionSet(logger *zap.Logger, subscriptions SubscriptionSet, envelope *protocol.Envelope) { func iterateSubscriptionSet(ctx context.Context, logger *zap.Logger, subscriptions SubscriptionSet, envelope *protocol.Envelope) {
for _, subscription := range subscriptions { for _, subscription := range subscriptions {
func(subscription *SubscriptionDetails) { func(subscription *SubscriptionDetails) {
subscription.RLock() subscription.RLock()
@ -201,6 +202,8 @@ func iterateSubscriptionSet(logger *zap.Logger, subscriptions SubscriptionSet, e
if !subscription.Closed { if !subscription.Closed {
select { select {
case <-ctx.Done():
return
case subscription.C <- envelope: case subscription.C <- envelope:
default: default:
logger.Warn("can't deliver message to subscription. subscriber too slow") logger.Warn("can't deliver message to subscription. subscriber too slow")

View File

@ -153,8 +153,8 @@ func TestSubscriptionsNotify(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
fmap.Notify(p1, envTopic1Ct1) fmap.Notify(ctx, p1, envTopic1Ct1)
fmap.Notify(p2, envTopic1Ct1) fmap.Notify(ctx, p2, envTopic1Ct1)
}() }()
<-successChan <-successChan
@ -177,8 +177,8 @@ func TestSubscriptionsNotify(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
fmap.Notify(p1, envTopic1Ct2) fmap.Notify(ctx, p1, envTopic1Ct2)
fmap.Notify(p2, envTopic1Ct2) fmap.Notify(ctx, p2, envTopic1Ct2)
}() }()
<-successChan <-successChan
@ -207,8 +207,8 @@ func TestSubscriptionsNotify(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
fmap.Notify(p1, envTopic1Ct1_2) fmap.Notify(ctx, p1, envTopic1Ct1_2)
fmap.Notify(p2, envTopic1Ct1_2) fmap.Notify(ctx, p2, envTopic1Ct1_2)
}() }()
<-successChan // One of these successes is for closing the subscription <-successChan // One of these successes is for closing the subscription