github.com/status-im/status-go@v1.1.0/wakuv2/message_publishing.go (about)

     1  package wakuv2
     2  
     3  import (
     4  	"errors"
     5  
     6  	"go.uber.org/zap"
     7  
     8  	"github.com/waku-org/go-waku/waku/v2/api/publish"
     9  	"github.com/waku-org/go-waku/waku/v2/protocol"
    10  	"github.com/waku-org/go-waku/waku/v2/protocol/pb"
    11  	"github.com/waku-org/go-waku/waku/v2/protocol/relay"
    12  
    13  	gethcommon "github.com/ethereum/go-ethereum/common"
    14  	"github.com/status-im/status-go/wakuv2/common"
    15  )
    16  
    17  // Send injects a message into the waku send queue, to be distributed in the
    18  // network in the coming cycles.
    19  func (w *Waku) Send(pubsubTopic string, msg *pb.WakuMessage, priority *int) ([]byte, error) {
    20  	pubsubTopic = w.GetPubsubTopic(pubsubTopic)
    21  	if w.protectedTopicStore != nil {
    22  		privKey, err := w.protectedTopicStore.FetchPrivateKey(pubsubTopic)
    23  		if err != nil {
    24  			return nil, err
    25  		}
    26  
    27  		if privKey != nil {
    28  			err = relay.SignMessage(privKey, msg, pubsubTopic)
    29  			if err != nil {
    30  				return nil, err
    31  			}
    32  		}
    33  	}
    34  
    35  	envelope := protocol.NewEnvelope(msg, msg.GetTimestamp(), pubsubTopic)
    36  
    37  	if priority != nil {
    38  		err := w.sendQueue.Push(w.ctx, envelope, *priority)
    39  		if err != nil {
    40  			return nil, err
    41  		}
    42  	} else {
    43  		err := w.sendQueue.Push(w.ctx, envelope)
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  	}
    48  
    49  	w.poolMu.Lock()
    50  	alreadyCached := w.envelopeCache.Has(gethcommon.BytesToHash(envelope.Hash().Bytes()))
    51  	w.poolMu.Unlock()
    52  	if !alreadyCached {
    53  		recvMessage := common.NewReceivedMessage(envelope, common.SendMessageType)
    54  		w.postEvent(recvMessage) // notify the local node about the new message
    55  		w.addEnvelope(recvMessage)
    56  	}
    57  
    58  	return envelope.Hash().Bytes(), nil
    59  }
    60  
    61  func (w *Waku) broadcast() {
    62  	defer w.wg.Done()
    63  	for {
    64  		var envelope *protocol.Envelope
    65  
    66  		select {
    67  		case envelope = <-w.sendQueue.Pop(w.ctx):
    68  
    69  		case <-w.ctx.Done():
    70  			return
    71  		}
    72  
    73  		w.wg.Add(1)
    74  		go w.publishEnvelope(envelope)
    75  	}
    76  }
    77  
    78  func (w *Waku) publishEnvelope(envelope *protocol.Envelope) {
    79  	defer w.wg.Done()
    80  
    81  	logger := w.logger.With(zap.Stringer("envelopeHash", envelope.Hash()), zap.String("pubsubTopic", envelope.PubsubTopic()), zap.String("contentTopic", envelope.Message().ContentTopic), zap.Int64("timestamp", envelope.Message().GetTimestamp()))
    82  
    83  	var err error
    84  	// only used in testing to simulate going offline
    85  	if w.cfg.SkipPublishToTopic {
    86  		logger.Info("skipping publish to topic")
    87  		err = errors.New("test send failure")
    88  	} else {
    89  		err = w.messageSender.Send(publish.NewRequest(w.ctx, envelope))
    90  	}
    91  
    92  	if w.statusTelemetryClient != nil {
    93  		if err == nil {
    94  			w.statusTelemetryClient.PushSentEnvelope(w.ctx, SentEnvelope{Envelope: envelope, PublishMethod: w.messageSender.PublishMethod()})
    95  		} else {
    96  			w.statusTelemetryClient.PushErrorSendingEnvelope(w.ctx, ErrorSendingEnvelope{Error: err, SentEnvelope: SentEnvelope{Envelope: envelope, PublishMethod: w.messageSender.PublishMethod()}})
    97  		}
    98  	}
    99  
   100  	if err != nil {
   101  		logger.Error("could not send message", zap.Error(err))
   102  		w.SendEnvelopeEvent(common.EnvelopeEvent{
   103  			Hash:  gethcommon.BytesToHash(envelope.Hash().Bytes()),
   104  			Event: common.EventEnvelopeExpired,
   105  		})
   106  		return
   107  	}
   108  
   109  	if !w.cfg.EnableStoreConfirmationForMessagesSent {
   110  		w.SendEnvelopeEvent(common.EnvelopeEvent{
   111  			Hash:  gethcommon.BytesToHash(envelope.Hash().Bytes()),
   112  			Event: common.EventEnvelopeSent,
   113  		})
   114  	}
   115  }