github.com/status-im/status-go@v1.1.0/protocol/common/message_sender.go (about)

     1  package common
     2  
     3  import (
     4  	"context"
     5  	"crypto/ecdsa"
     6  	"database/sql"
     7  	"math/rand"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/golang/protobuf/proto"
    12  	"github.com/pkg/errors"
    13  	datasyncnode "github.com/status-im/mvds/node"
    14  	datasyncproto "github.com/status-im/mvds/protobuf"
    15  	"github.com/status-im/mvds/state"
    16  	"go.uber.org/zap"
    17  
    18  	"github.com/status-im/status-go/eth-node/crypto"
    19  	"github.com/status-im/status-go/eth-node/types"
    20  	"github.com/status-im/status-go/protocol/datasync"
    21  	datasyncpeer "github.com/status-im/status-go/protocol/datasync/peer"
    22  	"github.com/status-im/status-go/protocol/encryption"
    23  	"github.com/status-im/status-go/protocol/encryption/sharedsecret"
    24  	"github.com/status-im/status-go/protocol/protobuf"
    25  	"github.com/status-im/status-go/protocol/transport"
    26  	v1protocol "github.com/status-im/status-go/protocol/v1"
    27  )
    28  
    29  // Whisper message properties.
    30  const (
    31  	whisperTTL        = 15
    32  	whisperDefaultPoW = 0.002
    33  	// whisperLargeSizePoW is the PoWTarget for larger payload sizes
    34  	whisperLargeSizePoW = 0.000002
    35  	// largeSizeInBytes is when should we be using a lower POW.
    36  	// Roughly this is 50KB
    37  	largeSizeInBytes              = 50000
    38  	whisperPoWTime                = 5
    39  	maxMessageSenderEphemeralKeys = 3
    40  )
    41  
    42  // RekeyCompatibility indicates whether we should be sending
    43  // keys in 1-to-1 messages as well as in the newer format
    44  var RekeyCompatibility = true
    45  
    46  // SentMessage reprent a message that has been passed to the transport layer
    47  type SentMessage struct {
    48  	PublicKey  *ecdsa.PublicKey
    49  	Spec       *encryption.ProtocolMessageSpec
    50  	MessageIDs [][]byte
    51  }
    52  
    53  type MessageEventType uint32
    54  
    55  const (
    56  	MessageScheduled = iota + 1
    57  	MessageSent
    58  )
    59  
    60  type MessageEvent struct {
    61  	Recipient   *ecdsa.PublicKey
    62  	Type        MessageEventType
    63  	SentMessage *SentMessage
    64  	RawMessage  *RawMessage
    65  }
    66  
    67  type MessageSender struct {
    68  	identity    *ecdsa.PrivateKey
    69  	datasync    *datasync.DataSync
    70  	database    *sql.DB
    71  	protocol    *encryption.Protocol
    72  	transport   *transport.Transport
    73  	logger      *zap.Logger
    74  	persistence *RawMessagesPersistence
    75  
    76  	datasyncEnabled bool
    77  
    78  	// ephemeralKeys is a map that contains the ephemeral keys of the client, used
    79  	// to decrypt messages
    80  	ephemeralKeys      map[string]*ecdsa.PrivateKey
    81  	ephemeralKeysMutex sync.Mutex
    82  
    83  	// messageEventsSubscriptions contains all the subscriptions for message events
    84  	messageEventsSubscriptions      []chan<- *MessageEvent
    85  	messageEventsSubscriptionsMutex sync.Mutex
    86  
    87  	featureFlags FeatureFlags
    88  
    89  	// handleSharedSecrets is a callback that is called every time a new shared secret is negotiated
    90  	handleSharedSecrets func([]*sharedsecret.Secret) error
    91  }
    92  
    93  func NewMessageSender(
    94  	identity *ecdsa.PrivateKey,
    95  	database *sql.DB,
    96  	enc *encryption.Protocol,
    97  	transport *transport.Transport,
    98  	logger *zap.Logger,
    99  	features FeatureFlags,
   100  ) (*MessageSender, error) {
   101  	p := &MessageSender{
   102  		identity:        identity,
   103  		datasyncEnabled: features.Datasync,
   104  		protocol:        enc,
   105  		database:        database,
   106  		persistence:     NewRawMessagesPersistence(database),
   107  		transport:       transport,
   108  		logger:          logger,
   109  		ephemeralKeys:   make(map[string]*ecdsa.PrivateKey),
   110  		featureFlags:    features,
   111  	}
   112  
   113  	return p, nil
   114  }
   115  
   116  func (s *MessageSender) Stop() {
   117  	s.messageEventsSubscriptionsMutex.Lock()
   118  	defer s.messageEventsSubscriptionsMutex.Unlock()
   119  
   120  	for _, c := range s.messageEventsSubscriptions {
   121  		close(c)
   122  	}
   123  	s.messageEventsSubscriptions = nil
   124  	s.StopDatasync()
   125  }
   126  
   127  func (s *MessageSender) SetHandleSharedSecrets(handler func([]*sharedsecret.Secret) error) {
   128  	s.handleSharedSecrets = handler
   129  }
   130  
   131  func (s *MessageSender) StartDatasync(statusChangeEvent chan datasyncnode.PeerStatusChangeEvent, handler func(peer state.PeerID, payload *datasyncproto.Payload) error) error {
   132  	if !s.datasyncEnabled {
   133  		return nil
   134  	}
   135  
   136  	dataSyncTransport := datasync.NewNodeTransport()
   137  	dataSyncNode, err := datasyncnode.NewPersistentNode(
   138  		s.database,
   139  		dataSyncTransport,
   140  		datasyncpeer.PublicKeyToPeerID(s.identity.PublicKey),
   141  		datasyncnode.BATCH,
   142  		datasync.CalculateSendTime,
   143  		statusChangeEvent,
   144  		s.logger,
   145  	)
   146  	if err != nil {
   147  		return err
   148  	}
   149  
   150  	s.datasync = datasync.New(dataSyncNode, dataSyncTransport, true, s.logger)
   151  
   152  	s.datasync.Init(handler, s.logger)
   153  	s.datasync.Start(datasync.DatasyncTicker)
   154  
   155  	return nil
   156  }
   157  
   158  // SendPrivate takes encoded data, encrypts it and sends through the wire.
   159  func (s *MessageSender) SendPrivate(
   160  	ctx context.Context,
   161  	recipient *ecdsa.PublicKey,
   162  	rawMessage *RawMessage,
   163  ) ([]byte, error) {
   164  	s.logger.Debug(
   165  		"sending a private message",
   166  		zap.String("public-key", types.EncodeHex(crypto.FromECDSAPub(recipient))),
   167  		zap.String("site", "SendPrivate"),
   168  	)
   169  	// Currently we don't support sending through datasync and setting custom waku fields,
   170  	// as the datasync interface is not rich enough to propagate that information, so we
   171  	// would have to add some complexity to handle this.
   172  	if rawMessage.ResendType == ResendTypeDataSync && (rawMessage.Sender != nil || rawMessage.SkipEncryptionLayer || rawMessage.SendOnPersonalTopic) {
   173  		return nil, errors.New("setting identity, skip-encryption or personal topic and datasync not supported")
   174  	}
   175  
   176  	// Set sender identity if not specified
   177  	if rawMessage.Sender == nil {
   178  		rawMessage.Sender = s.identity
   179  	}
   180  
   181  	return s.sendPrivate(ctx, recipient, rawMessage)
   182  }
   183  
   184  // SendCommunityMessage takes encoded data, encrypts it and sends through the wire
   185  // using the community topic and their key
   186  func (s *MessageSender) SendCommunityMessage(
   187  	ctx context.Context,
   188  	rawMessage *RawMessage,
   189  ) ([]byte, error) {
   190  	s.logger.Debug(
   191  		"sending a community message",
   192  		zap.String("communityId", types.EncodeHex(rawMessage.CommunityID)),
   193  		zap.String("site", "SendCommunityMessage"),
   194  	)
   195  	rawMessage.Sender = s.identity
   196  
   197  	return s.sendCommunity(ctx, rawMessage)
   198  }
   199  
   200  // SendPubsubTopicKey sends the protected topic key for a community to a list of recipients
   201  func (s *MessageSender) SendPubsubTopicKey(
   202  	ctx context.Context,
   203  	rawMessage *RawMessage,
   204  ) ([]byte, error) {
   205  	s.logger.Debug(
   206  		"sending the protected topic key for a community",
   207  		zap.String("communityId", types.EncodeHex(rawMessage.CommunityID)),
   208  		zap.String("site", "SendPubsubTopicKey"),
   209  	)
   210  	rawMessage.Sender = s.identity
   211  	messageID, err := s.getMessageID(rawMessage)
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  
   216  	if err = s.setMessageID(messageID, rawMessage); err != nil {
   217  		return nil, err
   218  	}
   219  
   220  	// Notify before dispatching, otherwise the dispatch subscription might happen
   221  	// earlier than the scheduled
   222  	s.notifyOnScheduledMessage(nil, rawMessage)
   223  
   224  	// Send to each recipients
   225  	for _, recipient := range rawMessage.Recipients {
   226  		_, err = s.sendPrivate(ctx, recipient, rawMessage)
   227  		if err != nil {
   228  			return nil, errors.Wrap(err, "failed to send message")
   229  		}
   230  	}
   231  	return messageID, nil
   232  
   233  }
   234  
   235  // SendGroup takes encoded data, encrypts it and sends through the wire,
   236  // always return the messageID
   237  func (s *MessageSender) SendGroup(
   238  	ctx context.Context,
   239  	recipients []*ecdsa.PublicKey,
   240  	rawMessage RawMessage,
   241  ) ([]byte, error) {
   242  	s.logger.Debug(
   243  		"sending a private group message",
   244  		zap.String("site", "SendGroup"),
   245  	)
   246  	// Set sender if not specified
   247  	if rawMessage.Sender == nil {
   248  		rawMessage.Sender = s.identity
   249  	}
   250  
   251  	// Calculate messageID first and set on raw message
   252  	messageID, err := s.getMessageID(&rawMessage)
   253  	if err != nil {
   254  		return nil, err
   255  	}
   256  
   257  	if err = s.setMessageID(messageID, &rawMessage); err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	// We call it only once, and we nil the function after so it doesn't get called again
   262  	if rawMessage.BeforeDispatch != nil {
   263  		if err := rawMessage.BeforeDispatch(&rawMessage); err != nil {
   264  			return nil, err
   265  		}
   266  	}
   267  
   268  	// Send to each recipients
   269  	for _, recipient := range recipients {
   270  		_, err = s.sendPrivate(ctx, recipient, &rawMessage)
   271  		if err != nil {
   272  			return nil, errors.Wrap(err, "failed to send message")
   273  		}
   274  	}
   275  	return messageID, nil
   276  }
   277  
   278  func (s *MessageSender) getMessageID(rawMessage *RawMessage) (types.HexBytes, error) {
   279  	wrappedMessage, err := s.wrapMessageV1(rawMessage)
   280  	if err != nil {
   281  		return nil, errors.Wrap(err, "failed to wrap message")
   282  	}
   283  
   284  	messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage)
   285  	return messageID, nil
   286  }
   287  
   288  func (s *MessageSender) ValidateRawMessage(rawMessage *RawMessage) error {
   289  	id, err := s.getMessageID(rawMessage)
   290  	if err != nil {
   291  		return err
   292  	}
   293  	messageID := types.EncodeHex(id)
   294  
   295  	return s.validateMessageID(messageID, rawMessage)
   296  
   297  }
   298  
   299  func (s *MessageSender) validateMessageID(messageID string, rawMessage *RawMessage) error {
   300  	if len(rawMessage.ID) > 0 && rawMessage.ID != messageID {
   301  		s.logger.Error("failed to validate message ID, RawMessage content was modified",
   302  			zap.String("prevID", rawMessage.ID),
   303  			zap.String("newID", messageID),
   304  			zap.Any("contentType", rawMessage.MessageType))
   305  		return ErrModifiedRawMessage
   306  	}
   307  	return nil
   308  }
   309  
   310  func (s *MessageSender) setMessageID(messageID types.HexBytes, rawMessage *RawMessage) error {
   311  	msgID := types.EncodeHex(messageID)
   312  
   313  	if err := s.validateMessageID(msgID, rawMessage); err != nil {
   314  		return err
   315  	}
   316  
   317  	rawMessage.ID = msgID
   318  	return nil
   319  }
   320  
   321  func ShouldCommunityMessageBeEncrypted(msgType protobuf.ApplicationMetadataMessage_Type) bool {
   322  	return msgType == protobuf.ApplicationMetadataMessage_CHAT_MESSAGE ||
   323  		msgType == protobuf.ApplicationMetadataMessage_EDIT_MESSAGE ||
   324  		msgType == protobuf.ApplicationMetadataMessage_DELETE_MESSAGE ||
   325  		msgType == protobuf.ApplicationMetadataMessage_PIN_MESSAGE ||
   326  		msgType == protobuf.ApplicationMetadataMessage_EMOJI_REACTION
   327  }
   328  
   329  // sendCommunity sends a message that's to be sent in a community
   330  // If it's a chat message, it will go to the respective topic derived by the
   331  // chat id, if it's not a chat message, it will go to the community topic.
   332  func (s *MessageSender) sendCommunity(
   333  	ctx context.Context,
   334  	rawMessage *RawMessage,
   335  ) ([]byte, error) {
   336  	s.logger.Debug("sending community message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(&rawMessage.Sender.PublicKey))))
   337  
   338  	// Set sender
   339  	if rawMessage.Sender == nil {
   340  		rawMessage.Sender = s.identity
   341  	}
   342  
   343  	messageID, err := s.getMessageID(rawMessage)
   344  	if err != nil {
   345  		return nil, err
   346  	}
   347  
   348  	if err = s.setMessageID(messageID, rawMessage); err != nil {
   349  		return nil, err
   350  	}
   351  
   352  	if rawMessage.BeforeDispatch != nil {
   353  		if err := rawMessage.BeforeDispatch(rawMessage); err != nil {
   354  			return nil, err
   355  		}
   356  	}
   357  	// Notify before dispatching, otherwise the dispatch subscription might happen
   358  	// earlier than the scheduled
   359  	s.notifyOnScheduledMessage(nil, rawMessage)
   360  
   361  	var hashes [][]byte
   362  	var newMessages []*types.NewMessage
   363  
   364  	forceRekey := rawMessage.CommunityKeyExMsgType == KeyExMsgRekey
   365  
   366  	// Check if it's a key exchange message. In this case we send it
   367  	// to all the recipients
   368  	if rawMessage.CommunityKeyExMsgType != KeyExMsgNone {
   369  		// If rekeycompatibility is on, we always
   370  		// want to execute below, otherwise we execute
   371  		// only when we want to fill up old keys to a given user
   372  		if RekeyCompatibility || !forceRekey {
   373  			keyExMessageSpecs, err := s.protocol.GetKeyExMessageSpecs(rawMessage.HashRatchetGroupID, s.identity, rawMessage.Recipients, forceRekey)
   374  			if err != nil {
   375  				return nil, err
   376  			}
   377  
   378  			for i, spec := range keyExMessageSpecs {
   379  				recipient := rawMessage.Recipients[i]
   380  				_, _, err = s.sendMessageSpec(ctx, recipient, spec, [][]byte{messageID})
   381  				if err != nil {
   382  					return nil, err
   383  				}
   384  			}
   385  		}
   386  	}
   387  
   388  	wrappedMessage, err := s.wrapMessageV1(rawMessage)
   389  	if err != nil {
   390  		return nil, err
   391  	}
   392  
   393  	// If it's a chat message, we send it on the community chat topic
   394  	if ShouldCommunityMessageBeEncrypted(rawMessage.MessageType) {
   395  		messageSpec, err := s.protocol.BuildHashRatchetMessage(rawMessage.HashRatchetGroupID, wrappedMessage)
   396  		if err != nil {
   397  			return nil, err
   398  		}
   399  
   400  		payload, err := proto.Marshal(messageSpec.Message)
   401  		if err != nil {
   402  			return nil, errors.Wrap(err, "failed to marshal")
   403  		}
   404  		hashes, newMessages, err = s.dispatchCommunityChatMessage(ctx, rawMessage, payload, forceRekey)
   405  		if err != nil {
   406  			return nil, err
   407  		}
   408  
   409  		sentMessage := &SentMessage{
   410  			Spec:       messageSpec,
   411  			MessageIDs: [][]byte{messageID},
   412  		}
   413  
   414  		s.notifyOnSentMessage(sentMessage)
   415  
   416  	} else {
   417  
   418  		pubkey, err := crypto.DecompressPubkey(rawMessage.CommunityID)
   419  		if err != nil {
   420  			return nil, errors.Wrap(err, "failed to decompress pubkey")
   421  		}
   422  		hashes, newMessages, err = s.dispatchCommunityMessage(ctx, pubkey, wrappedMessage, rawMessage.PubsubTopic, forceRekey, rawMessage)
   423  		if err != nil {
   424  			s.logger.Error("failed to send a community message", zap.Error(err))
   425  			return nil, errors.Wrap(err, "failed to send a message spec")
   426  		}
   427  	}
   428  
   429  	s.logger.Debug("sent-message: community ",
   430  		zap.Strings("recipient", PubkeysToHex(rawMessage.Recipients)),
   431  		zap.String("messageID", messageID.String()),
   432  		zap.String("messageType", "community"),
   433  		zap.Any("contentType", rawMessage.MessageType),
   434  		zap.Strings("hashes", types.EncodeHexes(hashes)))
   435  	s.transport.Track(messageID, hashes, newMessages)
   436  
   437  	return messageID, nil
   438  }
   439  
   440  // sendPrivate sends data to the recipient identifying with a given public key.
   441  func (s *MessageSender) sendPrivate(
   442  	ctx context.Context,
   443  	recipient *ecdsa.PublicKey,
   444  	rawMessage *RawMessage,
   445  ) ([]byte, error) {
   446  	s.logger.Debug("sending private message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(recipient))))
   447  
   448  	var wrappedMessage []byte
   449  	var err error
   450  	if rawMessage.SkipApplicationWrap {
   451  		wrappedMessage = rawMessage.Payload
   452  	} else {
   453  		wrappedMessage, err = s.wrapMessageV1(rawMessage)
   454  		if err != nil {
   455  			return nil, errors.Wrap(err, "failed to wrap message")
   456  		}
   457  	}
   458  
   459  	messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage)
   460  
   461  	if err = s.setMessageID(messageID, rawMessage); err != nil {
   462  		return nil, err
   463  	}
   464  
   465  	if rawMessage.BeforeDispatch != nil {
   466  		if err := rawMessage.BeforeDispatch(rawMessage); err != nil {
   467  			return nil, err
   468  		}
   469  	}
   470  
   471  	// Notify before dispatching, otherwise the dispatch subscription might happen
   472  	// earlier than the scheduled
   473  	s.notifyOnScheduledMessage(recipient, rawMessage)
   474  
   475  	if s.datasync != nil && s.featureFlags.Datasync && rawMessage.ResendType == ResendTypeDataSync {
   476  		// No need to call transport tracking.
   477  		// It is done in a data sync dispatch step.
   478  		datasyncID, err := s.addToDataSync(recipient, wrappedMessage)
   479  		if err != nil {
   480  			return nil, errors.Wrap(err, "failed to send message with datasync")
   481  		}
   482  		// We don't need to receive confirmations from our own devices
   483  		if !IsPubKeyEqual(recipient, &s.identity.PublicKey) {
   484  			confirmation := &RawMessageConfirmation{
   485  				DataSyncID: datasyncID,
   486  				MessageID:  messageID,
   487  				PublicKey:  crypto.CompressPubkey(recipient),
   488  			}
   489  
   490  			err = s.persistence.InsertPendingConfirmation(confirmation)
   491  			if err != nil {
   492  				return nil, err
   493  			}
   494  		}
   495  	} else if rawMessage.SkipEncryptionLayer {
   496  
   497  		messageBytes := wrappedMessage
   498  		if rawMessage.CommunityKeyExMsgType == KeyExMsgReuse {
   499  			groupID := rawMessage.HashRatchetGroupID
   500  
   501  			ratchets, err := s.protocol.GetKeysForGroup(groupID)
   502  			if err != nil {
   503  				return nil, err
   504  			}
   505  
   506  			message, err := s.protocol.BuildHashRatchetKeyExchangeMessageWithPayload(s.identity, recipient, groupID, ratchets, wrappedMessage)
   507  			if err != nil {
   508  				return nil, err
   509  			}
   510  
   511  			messageBytes, err = proto.Marshal(message.Message)
   512  			if err != nil {
   513  				return nil, err
   514  			}
   515  		}
   516  
   517  		// When SkipProtocolLayer is set we don't pass the message to the encryption layer
   518  		hashes, newMessages, err := s.sendPrivateRawMessage(ctx, rawMessage, recipient, messageBytes)
   519  		if err != nil {
   520  			s.logger.Error("failed to send a private message", zap.Error(err))
   521  			return nil, errors.Wrap(err, "failed to send a message spec")
   522  		}
   523  
   524  		s.logger.Debug("sent-message: private skipProtocolLayer",
   525  			zap.String("recipient", PubkeyToHex(recipient)),
   526  			zap.String("messageID", messageID.String()),
   527  			zap.String("messageType", "private"),
   528  			zap.Any("contentType", rawMessage.MessageType),
   529  			zap.Strings("hashes", types.EncodeHexes(hashes)))
   530  		s.transport.Track(messageID, hashes, newMessages)
   531  
   532  	} else {
   533  		messageSpec, err := s.protocol.BuildEncryptedMessage(rawMessage.Sender, recipient, wrappedMessage)
   534  		if err != nil {
   535  			return nil, errors.Wrap(err, "failed to encrypt message")
   536  		}
   537  
   538  		hashes, newMessages, err := s.sendMessageSpec(ctx, recipient, messageSpec, [][]byte{messageID})
   539  		if err != nil {
   540  			s.logger.Error("failed to send a private message", zap.Error(err))
   541  			return nil, errors.Wrap(err, "failed to send a message spec")
   542  		}
   543  
   544  		s.logger.Debug("sent-message: private without datasync",
   545  			zap.String("recipient", PubkeyToHex(recipient)),
   546  			zap.String("messageID", messageID.String()),
   547  			zap.Any("contentType", rawMessage.MessageType),
   548  			zap.String("messageType", "private"),
   549  			zap.Strings("hashes", types.EncodeHexes(hashes)))
   550  		s.transport.Track(messageID, hashes, newMessages)
   551  	}
   552  
   553  	return messageID, nil
   554  }
   555  
   556  // sendPairInstallation sends data to the recipients, using DH
   557  func (s *MessageSender) SendPairInstallation(
   558  	ctx context.Context,
   559  	recipient *ecdsa.PublicKey,
   560  	rawMessage RawMessage,
   561  ) ([]byte, error) {
   562  	s.logger.Debug("sending private message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(recipient))))
   563  
   564  	wrappedMessage, err := s.wrapMessageV1(&rawMessage)
   565  	if err != nil {
   566  		return nil, errors.Wrap(err, "failed to wrap message")
   567  	}
   568  
   569  	messageSpec, err := s.protocol.BuildDHMessage(s.identity, recipient, wrappedMessage)
   570  	if err != nil {
   571  		return nil, errors.Wrap(err, "failed to encrypt message")
   572  	}
   573  
   574  	messageID := v1protocol.MessageID(&s.identity.PublicKey, wrappedMessage)
   575  
   576  	hashes, newMessages, err := s.sendMessageSpec(ctx, recipient, messageSpec, [][]byte{messageID})
   577  	if err != nil {
   578  		return nil, errors.Wrap(err, "failed to send a message spec")
   579  	}
   580  
   581  	s.transport.Track(messageID, hashes, newMessages)
   582  
   583  	return messageID, nil
   584  }
   585  
   586  func (s *MessageSender) encodeMembershipUpdate(
   587  	message v1protocol.MembershipUpdateMessage,
   588  	chatEntity ChatEntity,
   589  ) ([]byte, error) {
   590  
   591  	if chatEntity != nil {
   592  		chatEntityProtobuf := chatEntity.GetProtobuf()
   593  		switch chatEntityProtobuf := chatEntityProtobuf.(type) {
   594  		case *protobuf.ChatMessage:
   595  			message.Message = chatEntityProtobuf
   596  		case *protobuf.EmojiReaction:
   597  			message.EmojiReaction = chatEntityProtobuf
   598  
   599  		}
   600  	}
   601  
   602  	encodedMessage, err := v1protocol.EncodeMembershipUpdateMessage(message)
   603  	if err != nil {
   604  		return nil, errors.Wrap(err, "failed to encode membership update message")
   605  	}
   606  
   607  	return encodedMessage, nil
   608  }
   609  
   610  // EncodeMembershipUpdate takes a group and an optional chat message and returns the protobuf representation to be sent on the wire.
   611  // All the events in a group are encoded and added to the payload
   612  func (s *MessageSender) EncodeMembershipUpdate(
   613  	group *v1protocol.Group,
   614  	chatEntity ChatEntity,
   615  ) ([]byte, error) {
   616  	message := v1protocol.MembershipUpdateMessage{
   617  		ChatID: group.ChatID(),
   618  		Events: group.Events(),
   619  	}
   620  
   621  	return s.encodeMembershipUpdate(message, chatEntity)
   622  }
   623  
   624  // EncodeAbridgedMembershipUpdate takes a group and an optional chat message and returns the protobuf representation to be sent on the wire.
   625  // Only the events relevant to the current group are encoded
   626  func (s *MessageSender) EncodeAbridgedMembershipUpdate(
   627  	group *v1protocol.Group,
   628  	chatEntity ChatEntity,
   629  ) ([]byte, error) {
   630  	message := v1protocol.MembershipUpdateMessage{
   631  		ChatID: group.ChatID(),
   632  		Events: group.AbridgedEvents(),
   633  	}
   634  	return s.encodeMembershipUpdate(message, chatEntity)
   635  }
   636  
   637  func (s *MessageSender) dispatchCommunityChatMessage(ctx context.Context, rawMessage *RawMessage, wrappedMessage []byte, rekey bool) ([][]byte, []*types.NewMessage, error) {
   638  	payload := wrappedMessage
   639  	var err error
   640  	if rekey && len(rawMessage.HashRatchetGroupID) != 0 {
   641  
   642  		var ratchet *encryption.HashRatchetKeyCompatibility
   643  		// We have just rekeyed, pull the latest
   644  		if RekeyCompatibility {
   645  			ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID)
   646  			if err != nil {
   647  				return nil, nil, err
   648  			}
   649  
   650  		}
   651  		// We send the message over the community topic
   652  		spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet)
   653  		if err != nil {
   654  			return nil, nil, err
   655  		}
   656  		payload, err = proto.Marshal(spec.Message)
   657  		if err != nil {
   658  			return nil, nil, err
   659  		}
   660  	}
   661  
   662  	newMessage := &types.NewMessage{
   663  		TTL:         whisperTTL,
   664  		Payload:     payload,
   665  		PowTarget:   calculatePoW(payload),
   666  		PowTime:     whisperPoWTime,
   667  		PubsubTopic: rawMessage.PubsubTopic,
   668  	}
   669  
   670  	if rawMessage.BeforeDispatch != nil {
   671  		if err := rawMessage.BeforeDispatch(rawMessage); err != nil {
   672  			return nil, nil, err
   673  		}
   674  	}
   675  
   676  	// notify before dispatching
   677  	s.notifyOnScheduledMessage(nil, rawMessage)
   678  
   679  	newMessages, err := s.segmentMessage(newMessage)
   680  	if err != nil {
   681  		return nil, nil, err
   682  	}
   683  
   684  	hashes := make([][]byte, 0, len(newMessages))
   685  	for _, newMessage := range newMessages {
   686  		hash, err := s.transport.SendPublic(ctx, newMessage, rawMessage.LocalChatID)
   687  		if err != nil {
   688  			return nil, nil, err
   689  		}
   690  		hashes = append(hashes, hash)
   691  	}
   692  
   693  	return hashes, newMessages, nil
   694  }
   695  
   696  // SendPublic takes encoded data, encrypts it and sends through the wire.
   697  func (s *MessageSender) SendPublic(
   698  	ctx context.Context,
   699  	chatName string,
   700  	rawMessage RawMessage,
   701  ) ([]byte, error) {
   702  	// Set sender
   703  	if rawMessage.Sender == nil {
   704  		rawMessage.Sender = s.identity
   705  	}
   706  
   707  	var wrappedMessage []byte
   708  	var err error
   709  	if rawMessage.SkipApplicationWrap {
   710  		wrappedMessage = rawMessage.Payload
   711  	} else {
   712  		wrappedMessage, err = s.wrapMessageV1(&rawMessage)
   713  		if err != nil {
   714  			return nil, errors.Wrap(err, "failed to wrap message")
   715  		}
   716  	}
   717  
   718  	var newMessage *types.NewMessage
   719  
   720  	messageSpec, err := s.protocol.BuildPublicMessage(s.identity, wrappedMessage)
   721  	if err != nil {
   722  		s.logger.Error("failed to send a public message", zap.Error(err))
   723  		return nil, errors.Wrap(err, "failed to wrap a public message in the encryption layer")
   724  	}
   725  
   726  	if len(rawMessage.HashRatchetGroupID) != 0 {
   727  
   728  		var ratchet *encryption.HashRatchetKeyCompatibility
   729  		var err error
   730  		// We have just rekeyed, pull the latest
   731  		ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID)
   732  		if err != nil {
   733  			return nil, err
   734  		}
   735  
   736  		keyID, err := ratchet.GetKeyID()
   737  		if err != nil {
   738  			return nil, err
   739  		}
   740  		s.logger.Debug("adding key id to message", zap.String("keyid", types.Bytes2Hex(keyID)))
   741  		// We send the message over the community topic
   742  		spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet)
   743  		if err != nil {
   744  			return nil, err
   745  		}
   746  		newMessage, err = MessageSpecToWhisper(spec)
   747  		if err != nil {
   748  			return nil, err
   749  		}
   750  
   751  	} else if !rawMessage.SkipEncryptionLayer {
   752  		newMessage, err = MessageSpecToWhisper(messageSpec)
   753  		if err != nil {
   754  			return nil, err
   755  		}
   756  	} else {
   757  		newMessage = &types.NewMessage{
   758  			TTL:       whisperTTL,
   759  			Payload:   wrappedMessage,
   760  			PowTarget: calculatePoW(wrappedMessage),
   761  			PowTime:   whisperPoWTime,
   762  		}
   763  	}
   764  
   765  	newMessage.Ephemeral = rawMessage.Ephemeral
   766  	newMessage.PubsubTopic = rawMessage.PubsubTopic
   767  	newMessage.Priority = rawMessage.Priority
   768  
   769  	messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage)
   770  
   771  	if err = s.setMessageID(messageID, &rawMessage); err != nil {
   772  		return nil, err
   773  	}
   774  
   775  	if rawMessage.BeforeDispatch != nil {
   776  		if err := rawMessage.BeforeDispatch(&rawMessage); err != nil {
   777  			return nil, err
   778  		}
   779  	}
   780  
   781  	// notify before dispatching
   782  	s.notifyOnScheduledMessage(nil, &rawMessage)
   783  
   784  	newMessages, err := s.segmentMessage(newMessage)
   785  	if err != nil {
   786  		return nil, err
   787  	}
   788  
   789  	hashes := make([][]byte, 0, len(newMessages))
   790  	for _, newMessage := range newMessages {
   791  		hash, err := s.transport.SendPublic(ctx, newMessage, chatName)
   792  		if err != nil {
   793  			return nil, err
   794  		}
   795  		hashes = append(hashes, hash)
   796  	}
   797  
   798  	sentMessage := &SentMessage{
   799  		Spec:       messageSpec,
   800  		MessageIDs: [][]byte{messageID},
   801  	}
   802  
   803  	s.notifyOnSentMessage(sentMessage)
   804  
   805  	s.logger.Debug("sent-message: public message",
   806  		zap.Strings("recipient", PubkeysToHex(rawMessage.Recipients)),
   807  		zap.String("messageID", messageID.String()),
   808  		zap.Any("contentType", rawMessage.MessageType),
   809  		zap.String("messageType", "public"),
   810  		zap.Strings("hashes", types.EncodeHexes(hashes)))
   811  	s.transport.Track(messageID, hashes, newMessages)
   812  
   813  	return messageID, nil
   814  }
   815  
   816  // unwrapDatasyncMessage tries to unwrap message as datasync one and in case of success
   817  // returns cloned messages with replaced payloads
   818  func (s *MessageSender) unwrapDatasyncMessage(m *v1protocol.StatusMessage, response *handleMessageResponse) error {
   819  
   820  	datasyncMessage, err := s.datasync.Unwrap(
   821  		m.SigPubKey(),
   822  		m.EncryptionLayer.Payload,
   823  	)
   824  	if err != nil {
   825  		return err
   826  	}
   827  
   828  	response.DatasyncSender = m.SigPubKey()
   829  	response.DatasyncAcks = append(response.DatasyncAcks, datasyncMessage.Acks...)
   830  	response.DatasyncRequests = append(response.DatasyncRequests, datasyncMessage.Requests...)
   831  	for _, o := range datasyncMessage.GroupOffers {
   832  		for _, mID := range o.MessageIds {
   833  			response.DatasyncOffers = append(response.DatasyncOffers, DatasyncOffer{GroupID: o.GroupId, MessageID: mID})
   834  		}
   835  	}
   836  
   837  	for _, ds := range datasyncMessage.Messages {
   838  		message, err := m.Clone()
   839  		if err != nil {
   840  			return err
   841  		}
   842  		message.EncryptionLayer.Payload = ds.Body
   843  		response.DatasyncMessages = append(response.DatasyncMessages, message)
   844  
   845  	}
   846  	return nil
   847  }
   848  
   849  // HandleMessages expects a whisper message as input, and it will go through
   850  // a series of transformations until the message is parsed into an application
   851  // layer message, or in case of Raw methods, the processing stops at the layer
   852  // before.
   853  // It returns an error only if the processing of required steps failed.
   854  func (s *MessageSender) HandleMessages(wakuMessage *types.Message) (*HandleMessageResponse, error) {
   855  	logger := s.logger.With(zap.String("site", "HandleMessages"))
   856  	hlogger := logger.With(zap.String("hash", types.HexBytes(wakuMessage.Hash).String()))
   857  
   858  	response, err := s.handleMessage(wakuMessage)
   859  	if err != nil {
   860  		// Hash ratchet with a group id not found yet, save the message for future processing
   861  		if err == encryption.ErrHashRatchetGroupIDNotFound && len(response.Message.EncryptionLayer.HashRatchetInfo) == 1 {
   862  			info := response.Message.EncryptionLayer.HashRatchetInfo[0]
   863  			return nil, s.persistence.SaveHashRatchetMessage(info.GroupID, info.KeyID, wakuMessage)
   864  		}
   865  
   866  		// The current message segment has been successfully retrieved.
   867  		// However, the collection of segments is not yet complete.
   868  		if err == ErrMessageSegmentsIncomplete {
   869  			return nil, nil
   870  		}
   871  
   872  		return nil, err
   873  	}
   874  
   875  	// Process queued hash ratchet messages
   876  	for _, hashRatchetInfo := range response.Message.EncryptionLayer.HashRatchetInfo {
   877  		messages, err := s.persistence.GetHashRatchetMessages(hashRatchetInfo.KeyID)
   878  		if err != nil {
   879  			return nil, err
   880  		}
   881  
   882  		var processedIds [][]byte
   883  		for _, message := range messages {
   884  			hlogger.Info("handling out of order encrypted messages", zap.String("hash", types.Bytes2Hex(message.Hash)))
   885  			r, err := s.handleMessage(message)
   886  			if err != nil {
   887  				hlogger.Debug("failed to handle hash ratchet message", zap.Error(err))
   888  				continue
   889  			}
   890  			response.DatasyncMessages = append(response.toPublicResponse().StatusMessages, r.Messages()...)
   891  			response.DatasyncAcks = append(response.DatasyncAcks, r.DatasyncAcks...)
   892  
   893  			processedIds = append(processedIds, message.Hash)
   894  		}
   895  
   896  		err = s.persistence.DeleteHashRatchetMessages(processedIds)
   897  		if err != nil {
   898  			s.logger.Warn("failed to delete hash ratchet messages", zap.Error(err))
   899  			return nil, err
   900  		}
   901  	}
   902  
   903  	return response.toPublicResponse(), nil
   904  }
   905  
   906  type DatasyncOffer struct {
   907  	GroupID   []byte
   908  	MessageID []byte
   909  }
   910  
   911  type HandleMessageResponse struct {
   912  	Hash             []byte
   913  	StatusMessages   []*v1protocol.StatusMessage
   914  	DatasyncSender   *ecdsa.PublicKey
   915  	DatasyncAcks     [][]byte
   916  	DatasyncOffers   []DatasyncOffer
   917  	DatasyncRequests [][]byte
   918  }
   919  
   920  func (h *handleMessageResponse) toPublicResponse() *HandleMessageResponse {
   921  	return &HandleMessageResponse{
   922  		Hash:             h.Hash,
   923  		StatusMessages:   h.Messages(),
   924  		DatasyncSender:   h.DatasyncSender,
   925  		DatasyncAcks:     h.DatasyncAcks,
   926  		DatasyncOffers:   h.DatasyncOffers,
   927  		DatasyncRequests: h.DatasyncRequests,
   928  	}
   929  }
   930  
   931  type handleMessageResponse struct {
   932  	Hash             []byte
   933  	Message          *v1protocol.StatusMessage
   934  	DatasyncMessages []*v1protocol.StatusMessage
   935  	DatasyncSender   *ecdsa.PublicKey
   936  	DatasyncAcks     [][]byte
   937  	DatasyncOffers   []DatasyncOffer
   938  	DatasyncRequests [][]byte
   939  }
   940  
   941  func (h *handleMessageResponse) Messages() []*v1protocol.StatusMessage {
   942  	if len(h.DatasyncMessages) > 0 {
   943  		return h.DatasyncMessages
   944  	}
   945  	return []*v1protocol.StatusMessage{h.Message}
   946  }
   947  
   948  func (s *MessageSender) handleMessage(wakuMessage *types.Message) (*handleMessageResponse, error) {
   949  	logger := s.logger.With(zap.String("site", "handleMessage"))
   950  	hlogger := logger.With(zap.String("hash", types.EncodeHex(wakuMessage.Hash)))
   951  
   952  	message := &v1protocol.StatusMessage{}
   953  
   954  	response := &handleMessageResponse{
   955  		Hash:             wakuMessage.Hash,
   956  		Message:          message,
   957  		DatasyncMessages: []*v1protocol.StatusMessage{},
   958  		DatasyncAcks:     [][]byte{},
   959  	}
   960  
   961  	err := message.HandleTransportLayer(wakuMessage)
   962  	if err != nil {
   963  		hlogger.Error("failed to handle transport layer message", zap.Error(err))
   964  		return nil, err
   965  	}
   966  
   967  	err = s.handleSegmentationLayerV2(message)
   968  	if err != nil {
   969  		hlogger.Debug("failed to handle segmentation layer message", zap.Error(err))
   970  
   971  		// Segments not completed yet, stop processing
   972  		if err == ErrMessageSegmentsIncomplete {
   973  			return nil, err
   974  		}
   975  		// Segments already completed, stop processing
   976  		if err == ErrMessageSegmentsAlreadyCompleted {
   977  			return nil, err
   978  		}
   979  	}
   980  
   981  	err = s.handleEncryptionLayer(context.Background(), message)
   982  	if err != nil {
   983  		hlogger.Debug("failed to handle an encryption message", zap.Error(err))
   984  
   985  		// Hash ratchet with a group id not found yet, stop processing
   986  		if err == encryption.ErrHashRatchetGroupIDNotFound {
   987  			return response, err
   988  		}
   989  	}
   990  
   991  	if s.datasync != nil && s.datasyncEnabled {
   992  		err := s.unwrapDatasyncMessage(message, response)
   993  		if err != nil {
   994  			hlogger.Debug("failed to handle datasync message", zap.Error(err))
   995  		}
   996  	}
   997  
   998  	for _, msg := range response.Messages() {
   999  		err := msg.HandleApplicationLayer()
  1000  		if err != nil {
  1001  			hlogger.Error("failed to handle application metadata layer message", zap.Error(err))
  1002  		}
  1003  	}
  1004  
  1005  	return response, nil
  1006  }
  1007  
  1008  // fetchDecryptionKey returns the private key associated with this public key, and returns true if it's an ephemeral key
  1009  func (s *MessageSender) fetchDecryptionKey(destination *ecdsa.PublicKey) (*ecdsa.PrivateKey, bool) {
  1010  	destinationID := types.EncodeHex(crypto.FromECDSAPub(destination))
  1011  
  1012  	s.ephemeralKeysMutex.Lock()
  1013  	decryptionKey, ok := s.ephemeralKeys[destinationID]
  1014  	s.ephemeralKeysMutex.Unlock()
  1015  
  1016  	// the key is not there, fallback on identity
  1017  	if !ok {
  1018  		return s.identity, false
  1019  	}
  1020  	return decryptionKey, true
  1021  }
  1022  
  1023  func (s *MessageSender) handleEncryptionLayer(ctx context.Context, message *v1protocol.StatusMessage) error {
  1024  	logger := s.logger.With(zap.String("site", "handleEncryptionLayer"))
  1025  	publicKey := message.SigPubKey()
  1026  
  1027  	// if it's an ephemeral key, we don't negotiate a topic
  1028  	decryptionKey, skipNegotiation := s.fetchDecryptionKey(message.TransportLayer.Dst)
  1029  
  1030  	err := message.HandleEncryptionLayer(decryptionKey, publicKey, s.protocol, skipNegotiation)
  1031  
  1032  	// if it's an ephemeral key, we don't have to handle a device not found error
  1033  	if err == encryption.ErrDeviceNotFound && !skipNegotiation {
  1034  		if err := s.handleErrDeviceNotFound(ctx, publicKey); err != nil {
  1035  			logger.Error("failed to handle ErrDeviceNotFound", zap.Error(err))
  1036  		}
  1037  	}
  1038  	if err != nil {
  1039  		logger.Error("failed to handle an encrypted message", zap.Error(err))
  1040  		return err
  1041  	}
  1042  
  1043  	return nil
  1044  }
  1045  
  1046  func (s *MessageSender) handleErrDeviceNotFound(ctx context.Context, publicKey *ecdsa.PublicKey) error {
  1047  	now := time.Now().Unix()
  1048  	advertise, err := s.protocol.ShouldAdvertiseBundle(publicKey, now)
  1049  	if err != nil {
  1050  		return err
  1051  	}
  1052  	if !advertise {
  1053  		return nil
  1054  	}
  1055  
  1056  	messageSpec, err := s.protocol.BuildBundleAdvertiseMessage(s.identity, publicKey)
  1057  	if err != nil {
  1058  		return err
  1059  	}
  1060  
  1061  	ctx, cancel := context.WithTimeout(ctx, time.Second)
  1062  	defer cancel()
  1063  	// We don't pass an array of messageIDs as no action needs to be taken
  1064  	// when sending a bundle
  1065  	_, _, err = s.sendMessageSpec(ctx, publicKey, messageSpec, nil)
  1066  	if err != nil {
  1067  		return err
  1068  	}
  1069  
  1070  	s.protocol.ConfirmBundleAdvertisement(publicKey, now)
  1071  
  1072  	return nil
  1073  }
  1074  
  1075  func (s *MessageSender) wrapMessageV1(rawMessage *RawMessage) ([]byte, error) {
  1076  	wrappedMessage, err := v1protocol.WrapMessageV1(rawMessage.Payload, rawMessage.MessageType, rawMessage.Sender)
  1077  	if err != nil {
  1078  		return nil, errors.Wrap(err, "failed to wrap message")
  1079  	}
  1080  	return wrappedMessage, nil
  1081  }
  1082  
  1083  func (s *MessageSender) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) ([]byte, error) {
  1084  	groupID := datasync.ToOneToOneGroupID(&s.identity.PublicKey, publicKey)
  1085  	peerID := datasyncpeer.PublicKeyToPeerID(*publicKey)
  1086  	exist, err := s.datasync.IsPeerInGroup(groupID, peerID)
  1087  	if err != nil {
  1088  		return nil, errors.Wrap(err, "failed to check if peer is in group")
  1089  	}
  1090  	if !exist {
  1091  		if err := s.datasync.AddPeer(groupID, peerID); err != nil {
  1092  			return nil, errors.Wrap(err, "failed to add peer")
  1093  		}
  1094  	}
  1095  	id, err := s.datasync.AppendMessage(groupID, message)
  1096  	if err != nil {
  1097  		return nil, errors.Wrap(err, "failed to append message to datasync")
  1098  	}
  1099  
  1100  	return id[:], nil
  1101  }
  1102  
  1103  // sendPrivateRawMessage sends a message not wrapped in an encryption layer
  1104  func (s *MessageSender) sendPrivateRawMessage(ctx context.Context, rawMessage *RawMessage, publicKey *ecdsa.PublicKey, payload []byte) ([][]byte, []*types.NewMessage, error) {
  1105  	newMessage := &types.NewMessage{
  1106  		TTL:         whisperTTL,
  1107  		Payload:     payload,
  1108  		PowTarget:   calculatePoW(payload),
  1109  		PowTime:     whisperPoWTime,
  1110  		PubsubTopic: rawMessage.PubsubTopic,
  1111  	}
  1112  
  1113  	newMessages, err := s.segmentMessage(newMessage)
  1114  	if err != nil {
  1115  		return nil, nil, err
  1116  	}
  1117  
  1118  	hashes := make([][]byte, 0, len(newMessages))
  1119  	var hash []byte
  1120  	for _, newMessage := range newMessages {
  1121  		if rawMessage.SendOnPersonalTopic {
  1122  			hash, err = s.transport.SendPrivateOnPersonalTopic(ctx, newMessage, publicKey)
  1123  		} else {
  1124  			hash, err = s.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
  1125  		}
  1126  		if err != nil {
  1127  			return nil, nil, err
  1128  		}
  1129  		hashes = append(hashes, hash)
  1130  	}
  1131  
  1132  	return hashes, newMessages, nil
  1133  }
  1134  
  1135  // sendCommunityMessage sends a message not wrapped in an encryption layer
  1136  // to a community
  1137  func (s *MessageSender) dispatchCommunityMessage(ctx context.Context, publicKey *ecdsa.PublicKey, wrappedMessage []byte, pubsubTopic string, rekey bool, rawMessage *RawMessage) ([][]byte, []*types.NewMessage, error) {
  1138  	payload := wrappedMessage
  1139  	if rekey && len(rawMessage.HashRatchetGroupID) != 0 {
  1140  
  1141  		var ratchet *encryption.HashRatchetKeyCompatibility
  1142  		var err error
  1143  		// We have just rekeyed, pull the latest
  1144  		if RekeyCompatibility {
  1145  			ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID)
  1146  			if err != nil {
  1147  				return nil, nil, err
  1148  			}
  1149  
  1150  		}
  1151  		keyID, err := ratchet.GetKeyID()
  1152  		if err != nil {
  1153  			return nil, nil, err
  1154  		}
  1155  		s.logger.Debug("adding key id to message", zap.String("keyid", types.Bytes2Hex(keyID)))
  1156  		// We send the message over the community topic
  1157  		spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet)
  1158  		if err != nil {
  1159  			return nil, nil, err
  1160  		}
  1161  		payload, err = proto.Marshal(spec.Message)
  1162  		if err != nil {
  1163  			return nil, nil, err
  1164  		}
  1165  	}
  1166  
  1167  	newMessage := &types.NewMessage{
  1168  		TTL:         whisperTTL,
  1169  		Payload:     payload,
  1170  		PowTarget:   calculatePoW(payload),
  1171  		PowTime:     whisperPoWTime,
  1172  		PubsubTopic: pubsubTopic,
  1173  	}
  1174  
  1175  	newMessages, err := s.segmentMessage(newMessage)
  1176  	if err != nil {
  1177  		return nil, nil, err
  1178  	}
  1179  
  1180  	hashes := make([][]byte, 0, len(newMessages))
  1181  	for _, newMessage := range newMessages {
  1182  		hash, err := s.transport.SendCommunityMessage(ctx, newMessage, publicKey)
  1183  		if err != nil {
  1184  			return nil, nil, err
  1185  		}
  1186  		hashes = append(hashes, hash)
  1187  	}
  1188  
  1189  	return hashes, newMessages, nil
  1190  }
  1191  
  1192  func (s *MessageSender) SendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec, messageIDs [][]byte) ([][]byte, []*types.NewMessage, error) {
  1193  	return s.sendMessageSpec(ctx, publicKey, messageSpec, messageIDs)
  1194  }
  1195  
  1196  // sendMessageSpec analyses the spec properties and selects a proper transport method.
  1197  func (s *MessageSender) sendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec, messageIDs [][]byte) ([][]byte, []*types.NewMessage, error) {
  1198  	logger := s.logger.With(zap.String("site", "sendMessageSpec"))
  1199  
  1200  	newMessage, err := MessageSpecToWhisper(messageSpec)
  1201  	if err != nil {
  1202  		return nil, nil, err
  1203  	}
  1204  
  1205  	newMessages, err := s.segmentMessage(newMessage)
  1206  	if err != nil {
  1207  		return nil, nil, err
  1208  	}
  1209  
  1210  	hashes := make([][]byte, 0, len(newMessages))
  1211  	var hash []byte
  1212  	for _, newMessage := range newMessages {
  1213  		// The shared secret needs to be handle before we send a message
  1214  		// otherwise the topic might not be set up before we receive a message
  1215  		if messageSpec.SharedSecret != nil && s.handleSharedSecrets != nil {
  1216  			err := s.handleSharedSecrets([]*sharedsecret.Secret{messageSpec.SharedSecret})
  1217  			if err != nil {
  1218  				return nil, nil, err
  1219  			}
  1220  
  1221  		}
  1222  		// process shared secret
  1223  		if messageSpec.AgreedSecret {
  1224  			logger.Debug("sending using shared secret")
  1225  			hash, err = s.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret.Key)
  1226  		} else {
  1227  			logger.Debug("sending partitioned topic")
  1228  			hash, err = s.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
  1229  		}
  1230  		if err != nil {
  1231  			return nil, nil, err
  1232  		}
  1233  		hashes = append(hashes, hash)
  1234  	}
  1235  
  1236  	sentMessage := &SentMessage{
  1237  		PublicKey:  publicKey,
  1238  		Spec:       messageSpec,
  1239  		MessageIDs: messageIDs,
  1240  	}
  1241  
  1242  	s.notifyOnSentMessage(sentMessage)
  1243  
  1244  	return hashes, newMessages, nil
  1245  }
  1246  
  1247  func (s *MessageSender) SubscribeToMessageEvents() <-chan *MessageEvent {
  1248  	c := make(chan *MessageEvent, 100)
  1249  	s.messageEventsSubscriptions = append(s.messageEventsSubscriptions, c)
  1250  	return c
  1251  }
  1252  
  1253  func (s *MessageSender) notifyOnSentMessage(sentMessage *SentMessage) {
  1254  	event := &MessageEvent{
  1255  		Type:        MessageSent,
  1256  		SentMessage: sentMessage,
  1257  	}
  1258  
  1259  	s.messageEventsSubscriptionsMutex.Lock()
  1260  	defer s.messageEventsSubscriptionsMutex.Unlock()
  1261  
  1262  	// Publish on channels, drop if buffer is full
  1263  	for _, c := range s.messageEventsSubscriptions {
  1264  		select {
  1265  		case c <- event:
  1266  		default:
  1267  			s.logger.Warn("message events subscription channel full when publishing sent event, dropping message")
  1268  		}
  1269  	}
  1270  
  1271  }
  1272  
  1273  func (s *MessageSender) notifyOnScheduledMessage(recipient *ecdsa.PublicKey, message *RawMessage) {
  1274  	event := &MessageEvent{
  1275  		Recipient:  recipient,
  1276  		Type:       MessageScheduled,
  1277  		RawMessage: message,
  1278  	}
  1279  
  1280  	s.messageEventsSubscriptionsMutex.Lock()
  1281  	defer s.messageEventsSubscriptionsMutex.Unlock()
  1282  
  1283  	// Publish on channels, drop if buffer is full
  1284  	for _, c := range s.messageEventsSubscriptions {
  1285  		select {
  1286  		case c <- event:
  1287  		default:
  1288  			s.logger.Warn("message events subscription channel full when publishing scheduled event, dropping message")
  1289  		}
  1290  	}
  1291  }
  1292  
  1293  func (s *MessageSender) JoinPublic(id string) (*transport.Filter, error) {
  1294  	return s.transport.JoinPublic(id)
  1295  }
  1296  
  1297  func (s *MessageSender) getRandomEphemeralKey() *ecdsa.PrivateKey {
  1298  	k := rand.Intn(len(s.ephemeralKeys)) //nolint: gosec
  1299  	for _, key := range s.ephemeralKeys {
  1300  		if k == 0 {
  1301  			return key
  1302  		}
  1303  		k--
  1304  	}
  1305  	return nil
  1306  }
  1307  
  1308  func (s *MessageSender) GetEphemeralKey() (*ecdsa.PrivateKey, error) {
  1309  	s.ephemeralKeysMutex.Lock()
  1310  	if len(s.ephemeralKeys) >= maxMessageSenderEphemeralKeys {
  1311  		s.ephemeralKeysMutex.Unlock()
  1312  		return s.getRandomEphemeralKey(), nil
  1313  	}
  1314  	privateKey, err := crypto.GenerateKey()
  1315  	if err != nil {
  1316  		s.ephemeralKeysMutex.Unlock()
  1317  		return nil, err
  1318  	}
  1319  
  1320  	s.ephemeralKeys[types.EncodeHex(crypto.FromECDSAPub(&privateKey.PublicKey))] = privateKey
  1321  	s.ephemeralKeysMutex.Unlock()
  1322  	_, err = s.transport.LoadKeyFilters(privateKey)
  1323  	if err != nil {
  1324  		return nil, err
  1325  	}
  1326  
  1327  	return privateKey, nil
  1328  }
  1329  
  1330  func MessageSpecToWhisper(spec *encryption.ProtocolMessageSpec) (*types.NewMessage, error) {
  1331  	var newMessage *types.NewMessage
  1332  
  1333  	payload, err := proto.Marshal(spec.Message)
  1334  	if err != nil {
  1335  		return newMessage, err
  1336  	}
  1337  
  1338  	newMessage = &types.NewMessage{
  1339  		TTL:       whisperTTL,
  1340  		Payload:   payload,
  1341  		PowTarget: calculatePoW(payload),
  1342  		PowTime:   whisperPoWTime,
  1343  	}
  1344  	return newMessage, nil
  1345  }
  1346  
  1347  // calculatePoW returns the PoWTarget to be used.
  1348  // We check the size and arbitrarily set it to a lower PoW if the packet is
  1349  // greater than 50KB. We do this as the defaultPoW is too high for clients to send
  1350  // large messages.
  1351  func calculatePoW(payload []byte) float64 {
  1352  	if len(payload) > largeSizeInBytes {
  1353  		return whisperLargeSizePoW
  1354  	}
  1355  	return whisperDefaultPoW
  1356  }
  1357  
  1358  func (s *MessageSender) StopDatasync() {
  1359  	if s.datasync != nil {
  1360  		s.datasync.Stop()
  1361  	}
  1362  }
  1363  
  1364  // GetCurrentKeyForGroup returns the latest key timestampID belonging to a key group
  1365  func (s *MessageSender) GetCurrentKeyForGroup(groupID []byte) (*encryption.HashRatchetKeyCompatibility, error) {
  1366  	return s.protocol.GetCurrentKeyForGroup(groupID)
  1367  }
  1368  
  1369  // GetKeyIDsForGroup returns a slice of key IDs belonging to a given group ID
  1370  func (s *MessageSender) GetKeysForGroup(groupID []byte) ([]*encryption.HashRatchetKeyCompatibility, error) {
  1371  	return s.protocol.GetKeysForGroup(groupID)
  1372  }
  1373  
  1374  func (s *MessageSender) CleanupHashRatchetEncryptedMessages() error {
  1375  	monthAgo := time.Now().AddDate(0, -1, 0).Unix()
  1376  
  1377  	err := s.persistence.DeleteHashRatchetMessagesOlderThan(monthAgo)
  1378  	if err != nil {
  1379  		return err
  1380  	}
  1381  
  1382  	return nil
  1383  }