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 }