Listen for delivered messages (#2150)

This commit is contained in:
Volodymyr Kozieiev 2021-02-23 17:47:45 +02:00 committed by GitHub
parent 730f540a0b
commit c38439e664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 301 additions and 168 deletions

View File

@ -1 +1 @@
0.71.4
0.71.5

1
go.sum
View File

@ -203,6 +203,7 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=

View File

@ -76,6 +76,7 @@ func (c *CommandParameters) IsTokenTransfer() bool {
const (
OutgoingStatusSending = "sending"
OutgoingStatusSent = "sent"
OutgoingStatusDelivered = "delivered"
)
// Message represents a message record in the database,
@ -95,7 +96,7 @@ type Message struct {
Identicon string `json:"identicon"`
// The chat id to be stored locally
LocalChatID string `json:"localChatId"`
// Seen set to true when user have read this message already
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`

View File

@ -130,7 +130,7 @@ func (p *MessageProcessor) SetHandleSharedSecrets(handler func([]*sharedsecret.S
func (p *MessageProcessor) SendPrivate(
ctx context.Context,
recipient *ecdsa.PublicKey,
rawMessage RawMessage,
rawMessage *RawMessage,
) ([]byte, error) {
p.logger.Debug(
"sending a private message",
@ -149,7 +149,7 @@ func (p *MessageProcessor) SendPrivate(
rawMessage.Sender = p.identity
}
return p.sendPrivate(ctx, recipient, &rawMessage)
return p.sendPrivate(ctx, recipient, rawMessage)
}
// SendGroup takes encoded data, encrypts it and sends through the wire,
@ -209,10 +209,11 @@ func (p *MessageProcessor) sendPrivate(
if p.featureFlags.Datasync && rawMessage.ResendAutomatically {
// No need to call transport tracking.
// It is done in a data sync dispatch step.
if err := p.addToDataSync(recipient, wrappedMessage); err != nil {
datasyncID, err := p.addToDataSync(recipient, wrappedMessage)
if err != nil {
return nil, errors.Wrap(err, "failed to send message with datasync")
}
rawMessage.DataSyncID = datasyncID
} else if rawMessage.SkipEncryption {
// When SkipEncryption is set we don't pass the message to the encryption layer
messageIDs := [][]byte{messageID}
@ -396,20 +397,45 @@ func (p *MessageProcessor) SendPublic(
return messageID, nil
}
// unwrapDatasyncMessage tries to unwrap message as datasync one and in case of success
// returns cloned messages with replaced payloads
func unwrapDatasyncMessage(m *v1protocol.StatusMessage, datasync *datasync.DataSync) ([]*v1protocol.StatusMessage, [][]byte, error) {
var statusMessages []*v1protocol.StatusMessage
payloads, acks, err := datasync.UnwrapPayloadsAndAcks(
m.SigPubKey(),
m.DecryptedPayload,
)
if err != nil {
return nil, nil, err
}
for _, payload := range payloads {
message, err := m.Clone()
if err != nil {
return nil, nil, err
}
message.DecryptedPayload = payload
statusMessages = append(statusMessages, message)
}
return statusMessages, acks, nil
}
// HandleMessages expects a whisper message as input, and it will go through
// a series of transformations until the message is parsed into an application
// layer message, or in case of Raw methods, the processing stops at the layer
// before.
// It returns an error only if the processing of required steps failed.
func (p *MessageProcessor) HandleMessages(shhMessage *types.Message, applicationLayer bool) ([]*v1protocol.StatusMessage, error) {
func (p *MessageProcessor) HandleMessages(shhMessage *types.Message, applicationLayer bool) ([]*v1protocol.StatusMessage, [][]byte, error) {
logger := p.logger.With(zap.String("site", "handleMessages"))
hlogger := logger.With(zap.ByteString("hash", shhMessage.Hash))
var statusMessage v1protocol.StatusMessage
var statusMessages []*v1protocol.StatusMessage
err := statusMessage.HandleTransport(shhMessage)
if err != nil {
hlogger.Error("failed to handle transport layer message", zap.Error(err))
return nil, err
return nil, nil, err
}
err = p.handleEncryptionLayer(context.Background(), &statusMessage)
@ -417,9 +443,11 @@ func (p *MessageProcessor) HandleMessages(shhMessage *types.Message, application
hlogger.Debug("failed to handle an encryption message", zap.Error(err))
}
statusMessages, err := statusMessage.HandleDatasync(p.datasync)
statusMessages, acks, err := unwrapDatasyncMessage(&statusMessage, p.datasync)
if err != nil {
hlogger.Debug("failed to handle datasync message", zap.Error(err))
//that wasn't a datasync message, so use the original payload
statusMessages = append(statusMessages, &statusMessage)
}
for _, statusMessage := range statusMessages {
@ -436,7 +464,7 @@ func (p *MessageProcessor) HandleMessages(shhMessage *types.Message, application
}
}
return statusMessages, nil
return statusMessages, acks, nil
}
// fetchDecryptionKey returns the private key associated with this public key, and returns true if it's an ephemeral key
@ -513,24 +541,24 @@ func (p *MessageProcessor) wrapMessageV1(rawMessage *RawMessage) ([]byte, error)
return wrappedMessage, nil
}
func (p *MessageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) error {
func (p *MessageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) ([]byte, error) {
groupID := datasync.ToOneToOneGroupID(&p.identity.PublicKey, publicKey)
peerID := datasyncpeer.PublicKeyToPeerID(*publicKey)
exist, err := p.datasync.IsPeerInGroup(groupID, peerID)
if err != nil {
return errors.Wrap(err, "failed to check if peer is in group")
return nil, errors.Wrap(err, "failed to check if peer is in group")
}
if !exist {
if err := p.datasync.AddPeer(groupID, peerID); err != nil {
return errors.Wrap(err, "failed to add peer")
return nil, errors.Wrap(err, "failed to add peer")
}
}
_, err = p.datasync.AppendMessage(groupID, message)
id, err := p.datasync.AppendMessage(groupID, message)
if err != nil {
return errors.Wrap(err, "failed to append message to datasync")
return nil, errors.Wrap(err, "failed to append message to datasync")
}
return nil
return id[:], nil
}
// sendDataSync sends a message scheduled by the data sync layer.

View File

@ -115,7 +115,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
message.Sig = crypto.FromECDSAPub(&relayerKey.PublicKey)
message.Payload = wrappedPayload
decodedMessages, err := s.processor.HandleMessages(message, true)
decodedMessages, _, err := s.processor.HandleMessages(message, true)
s.Require().NoError(err)
s.Require().Equal(1, len(decodedMessages))
@ -151,7 +151,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
message.Sig = crypto.FromECDSAPub(&relayerKey.PublicKey)
message.Payload = marshalledDataSyncMessage
decodedMessages, err := s.processor.HandleMessages(message, true)
decodedMessages, _, err := s.processor.HandleMessages(message, true)
s.Require().NoError(err)
// We send two messages, the unwrapped one will be attributed to the relayer, while the wrapped one will be attributed to the author
@ -215,7 +215,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
message.Sig = crypto.FromECDSAPub(&relayerKey.PublicKey)
message.Payload = encryptedPayload
decodedMessages, err := s.processor.HandleMessages(message, true)
decodedMessages, _, err := s.processor.HandleMessages(message, true)
s.Require().NoError(err)
// We send two messages, the unwrapped one will be attributed to the relayer,

View File

@ -21,6 +21,7 @@ type RawMessage struct {
Payload []byte
Sender *ecdsa.PrivateKey
Recipients []*ecdsa.PublicKey
DataSyncID []byte
SkipGroupMessageWrap bool
SendOnPersonalTopic bool
}

View File

@ -2,6 +2,7 @@ package datasync
import (
"crypto/ecdsa"
"errors"
"github.com/golang/protobuf/proto"
datasyncnode "github.com/vacp2p/mvds/node"
@ -24,28 +25,35 @@ func New(node *datasyncnode.Node, transport *NodeTransport, sendingEnabled bool,
return &DataSync{Node: node, NodeTransport: transport, sendingEnabled: sendingEnabled, logger: logger}
}
func (d *DataSync) Handle(sender *ecdsa.PublicKey, payload []byte) [][]byte {
// UnwrapPayloadsAndAcks tries to unwrap datasync message and return messages payloads
// and acknowledgements for previously sent messages
func (d *DataSync) UnwrapPayloadsAndAcks(sender *ecdsa.PublicKey, payload []byte) ([][]byte, [][]byte, error) {
var payloads [][]byte
var acks [][]byte
logger := d.logger.With(zap.String("site", "Handle"))
datasyncMessage, err := unwrap(payload)
// If it failed to decode is not a protobuf message, if it successfully decoded but body is empty, is likedly a protobuf wrapped message
if err != nil || !datasyncMessage.IsValid() {
logger.Debug("handling non-datasync message", zap.Error(err), zap.Bool("datasyncMessage.IsValid()", datasyncMessage.IsValid()), zap.Any("message", datasyncMessage))
// Not a datasync message, return unchanged
payloads = append(payloads, payload)
if err != nil {
logger.Debug("Unwrapping datasync message failed", zap.Error(err))
return nil, nil, err
} else if !datasyncMessage.IsValid() {
return nil, nil, errors.New("handling non-datasync message")
} else {
logger.Debug("handling datasync message")
// datasync message
for _, message := range datasyncMessage.Messages {
payloads = append(payloads, message.Body)
}
acks = append(acks, datasyncMessage.Acks...)
if d.sendingEnabled {
d.add(sender, datasyncMessage)
}
}
return payloads
return payloads, acks, nil
}
func (d *DataSync) Stop() {

View File

@ -825,7 +825,7 @@ func (m *Messenger) publishOrgInvitation(org *communities.Community, invitation
SkipEncryption: true,
MessageType: protobuf.ApplicationMetadataMessage_COMMUNITY_INVITATION,
}
_, err = m.processor.SendPrivate(context.Background(), pk, rawMessage)
_, err = m.processor.SendPrivate(context.Background(), pk, &rawMessage)
return err
}
@ -1583,7 +1583,7 @@ func (m *Messenger) SendGroupChatInvitationRequest(ctx context.Context, chatID s
return nil, err
}
id, err := m.processor.SendPrivate(ctx, adminpk, spec)
id, err := m.processor.SendPrivate(ctx, adminpk, &spec)
if err != nil {
return nil, err
}
@ -1654,7 +1654,7 @@ func (m *Messenger) SendGroupChatInvitationRejection(ctx context.Context, invita
return nil, err
}
id, err := m.processor.SendPrivate(ctx, userpk, spec)
id, err := m.processor.SendPrivate(ctx, userpk, &spec)
if err != nil {
return nil, err
}
@ -2235,7 +2235,7 @@ func (m *Messenger) sendToPairedDevices(ctx context.Context, spec common.RawMess
hasPairedDevices := m.hasPairedDevices()
// We send a message to any paired device
if hasPairedDevices {
_, err := m.processor.SendPrivate(ctx, &m.identity.PublicKey, spec)
_, err := m.processor.SendPrivate(ctx, &m.identity.PublicKey, &spec)
if err != nil {
return err
}
@ -2277,15 +2277,19 @@ func (m *Messenger) dispatchMessage(ctx context.Context, spec common.RawMessage)
if err != nil {
return nil, err
}
//SendPrivate will alter message identity and possibly datasyncid, so we save an unchanged
//message for sending to paired devices later
specCopyForPairedDevices := spec
if !common.IsPubKeyEqual(publicKey, &m.identity.PublicKey) {
id, err = m.processor.SendPrivate(ctx, publicKey, spec)
id, err = m.processor.SendPrivate(ctx, publicKey, &spec)
if err != nil {
return nil, err
}
}
err = m.sendToPairedDevices(ctx, spec)
err = m.sendToPairedDevices(ctx, specCopyForPairedDevices)
if err != nil {
return nil, err
@ -2753,6 +2757,33 @@ type ReceivedMessageState struct {
Timesource common.TimeSource
}
func (m *Messenger) markDeliveredMessages(acks [][]byte) {
for _, ack := range acks {
//get message ID from database by datasync ID
messageID, err := m.persistence.RawMessageIDFromDatasyncID(ack)
if err != nil {
m.logger.Info("got datasync acknowledge for message we don't have in db", zap.String("ack", hex.EncodeToString(ack)))
continue
}
//mark messages as delivered
err = m.UpdateMessageOutgoingStatus(messageID, common.OutgoingStatusDelivered)
if err != nil {
m.logger.Debug("Can't set message status as delivered", zap.Error(err))
}
//send signal to client that message status updated
if m.config.messageDeliveredHandler != nil {
message, err := m.persistence.MessageByID(messageID)
if err != nil {
m.logger.Debug("Can't get message from database", zap.Error(err))
continue
}
m.config.messageDeliveredHandler(message.LocalChatID, messageID)
}
}
}
// addNewMessageNotification takes a common.Message and generates a new MessageNotificationBody and appends it to the
// []Response.Notifications if the message is m.New
func (r *ReceivedMessageState) addNewMessageNotification(m *common.Message) error {
@ -2798,16 +2829,18 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
}
logger := m.logger.With(zap.String("site", "RetrieveAll"))
for _, messages := range chatWithMessages {
var processedMessages []string
for _, shhMessage := range messages {
// Indicates tha all messages in the batch have been processed correctly
allMessagesProcessed := true
statusMessages, err := m.processor.HandleMessages(shhMessage, true)
statusMessages, acks, err := m.processor.HandleMessages(shhMessage, true)
if err != nil {
logger.Info("failed to decode messages", zap.Error(err))
continue
}
m.markDeliveredMessages(acks)
logger.Debug("processing messages further", zap.Int("count", len(statusMessages)))
@ -2826,6 +2859,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
if _, ok := messageState.AllContacts[senderID]; ok && messageState.AllContacts[senderID].IsBlocked() {
continue
}
// Don't process duplicates
messageID := types.EncodeHex(msg.ID)
exists, err := m.handler.messageExists(messageID, messageState.ExistingMessagesMap)
@ -2859,6 +2893,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
}
if msg.ParsedMessage != nil {
logger.Debug("Handling parsed message")
switch msg.ParsedMessage.Interface().(type) {
case protobuf.MembershipUpdateMessage:

View File

@ -14,6 +14,8 @@ import (
"github.com/status-im/status-go/services/mailservers"
)
type MessageDeliveredHandler func(string, string)
type config struct {
// This needs to be exposed until we move here mailserver logic
// as otherwise the client is not notified of a new filter and
@ -41,6 +43,8 @@ type config struct {
pushNotificationClientConfig *pushnotificationclient.Config
logger *zap.Logger
messageDeliveredHandler MessageDeliveredHandler
}
type Option func(*config) error
@ -144,3 +148,10 @@ func WithEnvelopesMonitorConfig(emc *transport.EnvelopesMonitorConfig) Option {
return nil
}
}
func WithDeliveredHandler(h MessageDeliveredHandler) Option {
return func(c *config) error {
c.messageDeliveredHandler = h
return nil
}
}

View File

@ -23,6 +23,7 @@
// 1610117927_add_message_cache.up.sql (142B)
// 1610959908_add_dont_wrap_to_raw_messages.up.sql (83B)
// 1610960912_add_send_on_personal_topic.up.sql (82B)
// 1612870480_add_datasync_id.up.sql (111B)
// README.md (554B)
// doc.go (850B)
@ -44,7 +45,7 @@ import (
func bindataRead(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("read %q: %v", name, err)
return nil, fmt.Errorf("read %q: %w", name, err)
}
var buf bytes.Buffer
@ -52,7 +53,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
clErr := gz.Close()
if err != nil {
return nil, fmt.Errorf("read %q: %v", name, err)
return nil, fmt.Errorf("read %q: %w", name, err)
}
if clErr != nil {
return nil, err
@ -108,7 +109,7 @@ func _000001_initDownDbSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "000001_init.down.db.sql", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)}
info := bindataFileInfo{name: "000001_init.down.db.sql", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5e, 0xbb, 0x3f, 0x1, 0x75, 0x19, 0x70, 0x86, 0xa7, 0x34, 0x40, 0x17, 0x34, 0x3e, 0x18, 0x51, 0x79, 0xd4, 0x22, 0xad, 0x8f, 0x80, 0xcc, 0xa6, 0xcc, 0x6, 0x2b, 0x62, 0x2, 0x47, 0xba, 0xf9}}
return a, nil
}
@ -128,7 +129,7 @@ func _000001_initUpDbSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "000001_init.up.db.sql", size: 2719, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)}
info := bindataFileInfo{name: "000001_init.up.db.sql", size: 2719, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x60, 0xdc, 0xeb, 0xe, 0xc2, 0x4f, 0x75, 0xa, 0xf6, 0x3e, 0xc7, 0xc4, 0x4, 0xe2, 0xe1, 0xa4, 0x73, 0x2f, 0x4a, 0xad, 0x1a, 0x0, 0xc3, 0x93, 0x9d, 0x77, 0x3e, 0x31, 0x91, 0x77, 0x2e, 0xc8}}
return a, nil
}
@ -148,7 +149,7 @@ func _000002_add_last_ens_clock_valueUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "000002_add_last_ens_clock_value.up.sql", size: 77, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)}
info := bindataFileInfo{name: "000002_add_last_ens_clock_value.up.sql", size: 77, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4d, 0x3, 0x8f, 0xd5, 0x85, 0x83, 0x47, 0xbe, 0xf9, 0x82, 0x7e, 0x81, 0xa4, 0xbd, 0xaa, 0xd5, 0x98, 0x18, 0x5, 0x2d, 0x82, 0x42, 0x3b, 0x3, 0x50, 0xc3, 0x1e, 0x84, 0x35, 0xf, 0xb6, 0x2b}}
return a, nil
}
@ -168,7 +169,7 @@ func _1586358095_add_replaceUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1586358095_add_replace.up.sql", size: 224, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)}
info := bindataFileInfo{name: "1586358095_add_replace.up.sql", size: 224, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0xb3, 0xa9, 0xc7, 0x7f, 0x9d, 0x8f, 0x43, 0x8c, 0x9e, 0x58, 0x8d, 0x44, 0xbc, 0xfa, 0x6b, 0x5f, 0x3f, 0x5a, 0xbe, 0xe8, 0xb1, 0x16, 0xf, 0x91, 0x2a, 0xa0, 0x71, 0xbb, 0x8d, 0x6b, 0xcb}}
return a, nil
}
@ -188,7 +189,7 @@ func _1588665364_add_image_dataUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1588665364_add_image_data.up.sql", size: 186, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)}
info := bindataFileInfo{name: "1588665364_add_image_data.up.sql", size: 186, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd6, 0xc6, 0x35, 0xb4, 0x4c, 0x39, 0x96, 0x29, 0x30, 0xda, 0xf4, 0x8f, 0xcb, 0xf1, 0x9f, 0x84, 0xdc, 0x88, 0xd4, 0xd5, 0xbc, 0xb6, 0x5b, 0x46, 0x78, 0x67, 0x76, 0x1a, 0x5, 0x36, 0xdc, 0xe5}}
return a, nil
}
@ -208,7 +209,7 @@ func _1589365189_add_pow_targetUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1589365189_add_pow_target.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)}
info := bindataFileInfo{name: "1589365189_add_pow_target.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4e, 0x3a, 0xe2, 0x2e, 0x7d, 0xaf, 0xbb, 0xcc, 0x21, 0xa1, 0x7a, 0x41, 0x9a, 0xd0, 0xbb, 0xa9, 0xc8, 0x35, 0xf9, 0x32, 0x34, 0x46, 0x44, 0x9a, 0x86, 0x40, 0x7c, 0xb9, 0x23, 0xc7, 0x3, 0x3f}}
return a, nil
}
@ -228,7 +229,7 @@ func _1591277220_add_index_messagesUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1591277220_add_index_messages.up.sql", size: 240, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)}
info := bindataFileInfo{name: "1591277220_add_index_messages.up.sql", size: 240, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9c, 0xfe, 0xbe, 0xd5, 0xb8, 0x8f, 0xdd, 0xef, 0xbb, 0xa8, 0xad, 0x7f, 0xed, 0x5b, 0x5b, 0x2f, 0xe6, 0x82, 0x27, 0x78, 0x1f, 0xb9, 0x57, 0xdc, 0x8, 0xc2, 0xb2, 0xa9, 0x9a, 0x4, 0xe1, 0x7a}}
return a, nil
}
@ -248,7 +249,7 @@ func _1593087212_add_mute_chat_and_raw_message_fieldsUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1593087212_add_mute_chat_and_raw_message_fields.up.sql", size: 215, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1593087212_add_mute_chat_and_raw_message_fields.up.sql", size: 215, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x73, 0x99, 0x61, 0xd1, 0xaa, 0xb4, 0xbf, 0xaf, 0xd7, 0x20, 0x17, 0x40, 0xf9, 0x2, 0xfb, 0xcc, 0x40, 0x2a, 0xd, 0x86, 0x36, 0x30, 0x88, 0x89, 0x25, 0x80, 0x42, 0xb0, 0x5b, 0xe9, 0x73, 0x78}}
return a, nil
}
@ -268,7 +269,7 @@ func _1595862781_add_audio_dataUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1595862781_add_audio_data.up.sql", size: 246, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1595862781_add_audio_data.up.sql", size: 246, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0xd2, 0xee, 0x55, 0xfb, 0x36, 0xa4, 0x92, 0x66, 0xe, 0x81, 0x62, 0x1e, 0x7a, 0x69, 0xa, 0xd5, 0x4b, 0xa5, 0x6a, 0x8d, 0x1d, 0xce, 0xf3, 0x3e, 0xc0, 0x5f, 0x9c, 0x66, 0x1b, 0xb4, 0xed}}
return a, nil
}
@ -288,7 +289,7 @@ func _1595865249_create_emoji_reactions_tableUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xc5, 0x43, 0x5c, 0x3d, 0x53, 0x43, 0x2c, 0x1a, 0xa5, 0xb6, 0xbf, 0x7, 0x4, 0x5a, 0x3e, 0x40, 0x8b, 0xa4, 0x57, 0x12, 0x58, 0xbc, 0x42, 0xe2, 0xc3, 0xde, 0x76, 0x98, 0x80, 0xe2, 0xbe}}
return a, nil
}
@ -308,7 +309,7 @@ func _1596805115_create_group_chat_invitations_tableUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1596805115_create_group_chat_invitations_table.up.sql", size: 231, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1596805115_create_group_chat_invitations_table.up.sql", size: 231, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6d, 0xb1, 0x14, 0x6d, 0x54, 0x28, 0x67, 0xc3, 0x23, 0x6a, 0xfc, 0x80, 0xdf, 0x9e, 0x4c, 0x35, 0x36, 0xf, 0xf8, 0xf3, 0x5f, 0xae, 0xad, 0xb, 0xc1, 0x51, 0x8e, 0x17, 0x7, 0xe5, 0x7f, 0x91}}
return a, nil
}
@ -328,7 +329,7 @@ func _1597322655_add_invitation_admin_chat_fieldUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1597322655_add_invitation_admin_chat_field.up.sql", size: 54, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1597322655_add_invitation_admin_chat_field.up.sql", size: 54, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x7a, 0xa0, 0xf2, 0xdb, 0x13, 0x91, 0x91, 0xa8, 0x34, 0x1a, 0xa1, 0x49, 0x68, 0xd5, 0xae, 0x2c, 0xd8, 0xd5, 0xea, 0x8f, 0x8c, 0xc7, 0x2, 0x4e, 0x58, 0x2c, 0x3a, 0x14, 0xd4, 0x4f, 0x2c}}
return a, nil
}
@ -348,7 +349,7 @@ func _1597757544_add_nicknameUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1597757544_add_nickname.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1597757544_add_nickname.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xa2, 0x64, 0x50, 0xc5, 0x4, 0xb9, 0x8b, 0xd1, 0x18, 0x9b, 0xc3, 0x91, 0x36, 0x2a, 0x1f, 0xc3, 0x6c, 0x2d, 0x92, 0xf8, 0x5e, 0xff, 0xb1, 0x59, 0x61, 0x2, 0x1c, 0xe1, 0x85, 0x90, 0xa4}}
return a, nil
}
@ -368,7 +369,7 @@ func _1598955122_add_mentionsUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1598955122_add_mentions.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1598955122_add_mentions.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8d, 0x22, 0x17, 0x92, 0xd2, 0x11, 0x4e, 0x7, 0x93, 0x9a, 0x55, 0xfd, 0xb, 0x97, 0xc4, 0x63, 0x6a, 0x81, 0x97, 0xcd, 0xb2, 0xf8, 0x4b, 0x5f, 0x3c, 0xfa, 0x3a, 0x38, 0x53, 0x10, 0xed, 0x9d}}
return a, nil
}
@ -388,7 +389,7 @@ func _1599641390_add_emoji_reactions_indexUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1599641390_add_emoji_reactions_index.up.sql", size: 126, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1599641390_add_emoji_reactions_index.up.sql", size: 126, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf9, 0xd8, 0xdc, 0xa7, 0xb, 0x92, 0x7a, 0x61, 0x37, 0x24, 0x1c, 0x77, 0x5e, 0xe, 0x7e, 0xfc, 0x9f, 0x98, 0x7b, 0x65, 0xe7, 0xf9, 0x71, 0x57, 0x89, 0x2d, 0x90, 0x1b, 0xf6, 0x5e, 0x37, 0xe8}}
return a, nil
}
@ -408,7 +409,7 @@ func _1599720851_add_seen_index_remove_long_messagesUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1599720851_add_seen_index_remove_long_messages.up.sql", size: 150, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1599720851_add_seen_index_remove_long_messages.up.sql", size: 150, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x24, 0x1c, 0xc4, 0x78, 0x91, 0xc7, 0xeb, 0xfe, 0xc8, 0xa0, 0xd8, 0x13, 0x27, 0x97, 0xc8, 0x96, 0x56, 0x97, 0x33, 0x2c, 0x1e, 0x16, 0x8a, 0xd3, 0x49, 0x99, 0x3, 0xe9, 0xbb, 0xc4, 0x5, 0x3c}}
return a, nil
}
@ -428,7 +429,7 @@ func _1603198582_add_profile_chat_fieldUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1603198582_add_profile_chat_field.up.sql", size: 45, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1603198582_add_profile_chat_field.up.sql", size: 45, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xaa, 0xca, 0xe, 0x46, 0xa0, 0x9, 0x9d, 0x47, 0x57, 0xe9, 0xfb, 0x17, 0xeb, 0x9c, 0xf6, 0xb8, 0x1d, 0xe9, 0xd, 0x0, 0xd5, 0xe5, 0xd8, 0x9e, 0x60, 0xa, 0xbf, 0x32, 0x2c, 0x52, 0x7f, 0x6a}}
return a, nil
}
@ -448,7 +449,7 @@ func _1603816533_add_linksUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1603816533_add_links.up.sql", size: 48, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1603816533_add_links.up.sql", size: 48, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0x24, 0xd6, 0x1d, 0xa, 0x83, 0x1e, 0x4d, 0xf, 0xae, 0x4d, 0x8c, 0x51, 0x32, 0xa8, 0x37, 0xb0, 0x14, 0xfb, 0x32, 0x34, 0xc8, 0xc, 0x4e, 0x5b, 0xc5, 0x15, 0x65, 0x73, 0x0, 0x0, 0x1d}}
return a, nil
}
@ -468,7 +469,7 @@ func _1603888149_create_chat_identity_last_published_tableUpSql() (*asset, error
return nil, err
}
info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 407, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 407, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7f, 0x9, 0xf, 0xfb, 0xdb, 0x3c, 0x86, 0x70, 0x82, 0xda, 0x10, 0x25, 0xe2, 0x4e, 0x40, 0x45, 0xab, 0x8b, 0x1c, 0x91, 0x7c, 0xf1, 0x70, 0x2e, 0x81, 0xf3, 0x71, 0x45, 0xda, 0xe2, 0xa4, 0x57}}
return a, nil
}
@ -488,7 +489,7 @@ func _1605075346_add_communitiesUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1605075346_add_communities.up.sql", size: 6971, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1605075346_add_communities.up.sql", size: 6971, mode: os.FileMode(0644), modTime: time.Unix(1610097152, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1f, 0x64, 0xea, 0xb4, 0xae, 0x9e, 0xdb, 0x9, 0x58, 0xb6, 0x5c, 0x7a, 0x50, 0xc5, 0xfe, 0x93, 0x5d, 0x36, 0x85, 0x5d, 0x6a, 0xba, 0xc9, 0x7e, 0x84, 0xd7, 0xbf, 0x2a, 0x53, 0xf3, 0x97, 0xf1}}
return a, nil
}
@ -508,7 +509,7 @@ func _1610117927_add_message_cacheUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1610117927_add_message_cache.up.sql", size: 142, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "1610117927_add_message_cache.up.sql", size: 142, mode: os.FileMode(0644), modTime: time.Unix(1613123938, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0xf1, 0xf0, 0x82, 0x79, 0x28, 0x19, 0xc2, 0x39, 0x6a, 0xa5, 0x96, 0x59, 0x23, 0xa0, 0xed, 0x60, 0x58, 0x86, 0x9, 0xb9, 0xad, 0xfb, 0xa, 0xe3, 0x47, 0x6e, 0xa1, 0x18, 0xe8, 0x39, 0x2c}}
return a, nil
}
@ -528,7 +529,7 @@ func _1610959908_add_dont_wrap_to_raw_messagesUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1610959908_add_dont_wrap_to_raw_messages.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1611646365, 0)}
info := bindataFileInfo{name: "1610959908_add_dont_wrap_to_raw_messages.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1613123938, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x71, 0x2, 0x9a, 0xca, 0xd4, 0x38, 0x44, 0x30, 0x2b, 0xa8, 0x27, 0x32, 0x63, 0x53, 0x22, 0x60, 0x59, 0x84, 0x23, 0x96, 0x77, 0xf0, 0x56, 0xd7, 0x94, 0xe0, 0x95, 0x28, 0x6, 0x1d, 0x4e, 0xb1}}
return a, nil
}
@ -548,11 +549,31 @@ func _1610960912_add_send_on_personal_topicUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1610960912_add_send_on_personal_topic.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1611646381, 0)}
info := bindataFileInfo{name: "1610960912_add_send_on_personal_topic.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1613123938, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0xac, 0x2f, 0xc4, 0xd, 0xa7, 0x1b, 0x37, 0x30, 0xc2, 0x68, 0xee, 0xde, 0x54, 0x5e, 0xbf, 0x3f, 0xa0, 0xd6, 0xc6, 0x9f, 0xd4, 0x34, 0x12, 0x76, 0x1e, 0x66, 0x4a, 0xfc, 0xf, 0xee, 0xc9}}
return a, nil
}
var __1612870480_add_datasync_idUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x28\x4a\x2c\x8f\xcf\x4d\x2d\x2e\x4e\x4c\x4f\x2d\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x48\x49\x2c\x49\x2c\xae\xcc\x4b\x8e\xcf\x4c\x51\x70\xf2\xf1\x77\xb2\xe6\x72\x0e\x72\x75\x0c\x71\x55\xf0\xf4\x73\x71\x8d\x50\xc8\x4c\xa9\x88\x4f\x49\x2c\x81\xa9\xf0\xf7\x43\x31\x48\x03\x49\xb7\xa6\x35\x20\x00\x00\xff\xff\x27\x9d\xbe\x49\x6f\x00\x00\x00")
func _1612870480_add_datasync_idUpSqlBytes() ([]byte, error) {
return bindataRead(
__1612870480_add_datasync_idUpSql,
"1612870480_add_datasync_id.up.sql",
)
}
func _1612870480_add_datasync_idUpSql() (*asset, error) {
bytes, err := _1612870480_add_datasync_idUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1612870480_add_datasync_id.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1613649828, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0x9a, 0xbc, 0xfa, 0xaa, 0x8c, 0x9c, 0x37, 0x67, 0x15, 0x9c, 0x7e, 0x78, 0x75, 0x66, 0x82, 0x18, 0x72, 0x10, 0xbc, 0xd4, 0xab, 0x44, 0xfe, 0x57, 0x85, 0x6d, 0x19, 0xf5, 0x96, 0x8a, 0xbe}}
return a, nil
}
var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00")
func readmeMdBytes() ([]byte, error) {
@ -568,7 +589,7 @@ func readmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "README.md", size: 554, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)}
info := bindataFileInfo{name: "README.md", size: 554, mode: os.FileMode(0644), modTime: time.Unix(1610097152, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1c, 0x6e, 0xfb, 0xcc, 0x81, 0x94, 0x4d, 0x8c, 0xa0, 0x3b, 0x5, 0xb0, 0x18, 0xd6, 0xbb, 0xb3, 0x79, 0xc8, 0x8f, 0xff, 0xc1, 0x10, 0xf9, 0xf, 0x20, 0x1b, 0x4a, 0x74, 0x96, 0x42, 0xd7, 0xa8}}
return a, nil
}
@ -588,7 +609,7 @@ func docGo() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "doc.go", size: 850, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)}
info := bindataFileInfo{name: "doc.go", size: 850, mode: os.FileMode(0644), modTime: time.Unix(1608547984, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa0, 0xcc, 0x41, 0xe1, 0x61, 0x12, 0x97, 0xe, 0x36, 0x8c, 0xa7, 0x9e, 0xe0, 0x6e, 0x59, 0x9e, 0xee, 0xd5, 0x4a, 0xcf, 0x1e, 0x60, 0xd6, 0xc3, 0x3a, 0xc9, 0x6c, 0xf2, 0x86, 0x5a, 0xb4, 0x1e}}
return a, nil
}
@ -685,56 +706,36 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"000001_init.down.db.sql": _000001_initDownDbSql,
"000001_init.up.db.sql": _000001_initUpDbSql,
"000002_add_last_ens_clock_value.up.sql": _000002_add_last_ens_clock_valueUpSql,
"1586358095_add_replace.up.sql": _1586358095_add_replaceUpSql,
"1588665364_add_image_data.up.sql": _1588665364_add_image_dataUpSql,
"1589365189_add_pow_target.up.sql": _1589365189_add_pow_targetUpSql,
"1591277220_add_index_messages.up.sql": _1591277220_add_index_messagesUpSql,
"1593087212_add_mute_chat_and_raw_message_fields.up.sql": _1593087212_add_mute_chat_and_raw_message_fieldsUpSql,
"1595862781_add_audio_data.up.sql": _1595862781_add_audio_dataUpSql,
"1595865249_create_emoji_reactions_table.up.sql": _1595865249_create_emoji_reactions_tableUpSql,
"1596805115_create_group_chat_invitations_table.up.sql": _1596805115_create_group_chat_invitations_tableUpSql,
"1597322655_add_invitation_admin_chat_field.up.sql": _1597322655_add_invitation_admin_chat_fieldUpSql,
"1597757544_add_nickname.up.sql": _1597757544_add_nicknameUpSql,
"1598955122_add_mentions.up.sql": _1598955122_add_mentionsUpSql,
"1599641390_add_emoji_reactions_index.up.sql": _1599641390_add_emoji_reactions_indexUpSql,
"1599720851_add_seen_index_remove_long_messages.up.sql": _1599720851_add_seen_index_remove_long_messagesUpSql,
"1603198582_add_profile_chat_field.up.sql": _1603198582_add_profile_chat_fieldUpSql,
"1603816533_add_links.up.sql": _1603816533_add_linksUpSql,
"1603888149_create_chat_identity_last_published_table.up.sql": _1603888149_create_chat_identity_last_published_tableUpSql,
"1605075346_add_communities.up.sql": _1605075346_add_communitiesUpSql,
"1610117927_add_message_cache.up.sql": _1610117927_add_message_cacheUpSql,
"1610959908_add_dont_wrap_to_raw_messages.up.sql": _1610959908_add_dont_wrap_to_raw_messagesUpSql,
"1610960912_add_send_on_personal_topic.up.sql": _1610960912_add_send_on_personal_topicUpSql,
"1612870480_add_datasync_id.up.sql": _1612870480_add_datasync_idUpSql,
"README.md": readmeMd,
"doc.go": docGo,
}
// AssetDebug is true if the assets were built with the debug flag enabled.
const AssetDebug = false
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
@ -776,31 +777,32 @@ type bintree struct {
}
var _bintree = &bintree{nil, map[string]*bintree{
"000001_init.down.db.sql": &bintree{_000001_initDownDbSql, map[string]*bintree{}},
"000001_init.up.db.sql": &bintree{_000001_initUpDbSql, map[string]*bintree{}},
"000002_add_last_ens_clock_value.up.sql": &bintree{_000002_add_last_ens_clock_valueUpSql, map[string]*bintree{}},
"1586358095_add_replace.up.sql": &bintree{_1586358095_add_replaceUpSql, map[string]*bintree{}},
"1588665364_add_image_data.up.sql": &bintree{_1588665364_add_image_dataUpSql, map[string]*bintree{}},
"1589365189_add_pow_target.up.sql": &bintree{_1589365189_add_pow_targetUpSql, map[string]*bintree{}},
"1591277220_add_index_messages.up.sql": &bintree{_1591277220_add_index_messagesUpSql, map[string]*bintree{}},
"1593087212_add_mute_chat_and_raw_message_fields.up.sql": &bintree{_1593087212_add_mute_chat_and_raw_message_fieldsUpSql, map[string]*bintree{}},
"1595862781_add_audio_data.up.sql": &bintree{_1595862781_add_audio_dataUpSql, map[string]*bintree{}},
"1595865249_create_emoji_reactions_table.up.sql": &bintree{_1595865249_create_emoji_reactions_tableUpSql, map[string]*bintree{}},
"1596805115_create_group_chat_invitations_table.up.sql": &bintree{_1596805115_create_group_chat_invitations_tableUpSql, map[string]*bintree{}},
"1597322655_add_invitation_admin_chat_field.up.sql": &bintree{_1597322655_add_invitation_admin_chat_fieldUpSql, map[string]*bintree{}},
"1597757544_add_nickname.up.sql": &bintree{_1597757544_add_nicknameUpSql, map[string]*bintree{}},
"1598955122_add_mentions.up.sql": &bintree{_1598955122_add_mentionsUpSql, map[string]*bintree{}},
"1599641390_add_emoji_reactions_index.up.sql": &bintree{_1599641390_add_emoji_reactions_indexUpSql, map[string]*bintree{}},
"1599720851_add_seen_index_remove_long_messages.up.sql": &bintree{_1599720851_add_seen_index_remove_long_messagesUpSql, map[string]*bintree{}},
"1603198582_add_profile_chat_field.up.sql": &bintree{_1603198582_add_profile_chat_fieldUpSql, map[string]*bintree{}},
"1603816533_add_links.up.sql": &bintree{_1603816533_add_linksUpSql, map[string]*bintree{}},
"1603888149_create_chat_identity_last_published_table.up.sql": &bintree{_1603888149_create_chat_identity_last_published_tableUpSql, map[string]*bintree{}},
"1605075346_add_communities.up.sql": &bintree{_1605075346_add_communitiesUpSql, map[string]*bintree{}},
"1610117927_add_message_cache.up.sql": &bintree{_1610117927_add_message_cacheUpSql, map[string]*bintree{}},
"1610959908_add_dont_wrap_to_raw_messages.up.sql": &bintree{_1610959908_add_dont_wrap_to_raw_messagesUpSql, map[string]*bintree{}},
"1610960912_add_send_on_personal_topic.up.sql": &bintree{_1610960912_add_send_on_personal_topicUpSql, map[string]*bintree{}},
"README.md": &bintree{readmeMd, map[string]*bintree{}},
"doc.go": &bintree{docGo, map[string]*bintree{}},
"000001_init.down.db.sql": {_000001_initDownDbSql, map[string]*bintree{}},
"000001_init.up.db.sql": {_000001_initUpDbSql, map[string]*bintree{}},
"000002_add_last_ens_clock_value.up.sql": {_000002_add_last_ens_clock_valueUpSql, map[string]*bintree{}},
"1586358095_add_replace.up.sql": {_1586358095_add_replaceUpSql, map[string]*bintree{}},
"1588665364_add_image_data.up.sql": {_1588665364_add_image_dataUpSql, map[string]*bintree{}},
"1589365189_add_pow_target.up.sql": {_1589365189_add_pow_targetUpSql, map[string]*bintree{}},
"1591277220_add_index_messages.up.sql": {_1591277220_add_index_messagesUpSql, map[string]*bintree{}},
"1593087212_add_mute_chat_and_raw_message_fields.up.sql": {_1593087212_add_mute_chat_and_raw_message_fieldsUpSql, map[string]*bintree{}},
"1595862781_add_audio_data.up.sql": {_1595862781_add_audio_dataUpSql, map[string]*bintree{}},
"1595865249_create_emoji_reactions_table.up.sql": {_1595865249_create_emoji_reactions_tableUpSql, map[string]*bintree{}},
"1596805115_create_group_chat_invitations_table.up.sql": {_1596805115_create_group_chat_invitations_tableUpSql, map[string]*bintree{}},
"1597322655_add_invitation_admin_chat_field.up.sql": {_1597322655_add_invitation_admin_chat_fieldUpSql, map[string]*bintree{}},
"1597757544_add_nickname.up.sql": {_1597757544_add_nicknameUpSql, map[string]*bintree{}},
"1598955122_add_mentions.up.sql": {_1598955122_add_mentionsUpSql, map[string]*bintree{}},
"1599641390_add_emoji_reactions_index.up.sql": {_1599641390_add_emoji_reactions_indexUpSql, map[string]*bintree{}},
"1599720851_add_seen_index_remove_long_messages.up.sql": {_1599720851_add_seen_index_remove_long_messagesUpSql, map[string]*bintree{}},
"1603198582_add_profile_chat_field.up.sql": {_1603198582_add_profile_chat_fieldUpSql, map[string]*bintree{}},
"1603816533_add_links.up.sql": {_1603816533_add_linksUpSql, map[string]*bintree{}},
"1603888149_create_chat_identity_last_published_table.up.sql": {_1603888149_create_chat_identity_last_published_tableUpSql, map[string]*bintree{}},
"1605075346_add_communities.up.sql": {_1605075346_add_communitiesUpSql, map[string]*bintree{}},
"1610117927_add_message_cache.up.sql": {_1610117927_add_message_cacheUpSql, map[string]*bintree{}},
"1610959908_add_dont_wrap_to_raw_messages.up.sql": {_1610959908_add_dont_wrap_to_raw_messagesUpSql, map[string]*bintree{}},
"1610960912_add_send_on_personal_topic.up.sql": {_1610960912_add_send_on_personal_topicUpSql, map[string]*bintree{}},
"1612870480_add_datasync_id.up.sql": {_1612870480_add_datasync_idUpSql, map[string]*bintree{}},
"README.md": {readmeMd, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}},
}}
// RestoreAsset restores an asset under the given directory.

View File

@ -0,0 +1,2 @@
ALTER TABLE raw_messages ADD COLUMN datasync_id BLOB;
CREATE INDEX idx_datsync_id ON raw_messages(datasync_id);

View File

@ -593,9 +593,10 @@ func (db sqlitePersistence) SaveRawMessage(message *common.RawMessage) error {
send_push_notification,
skip_group_message_wrap,
send_on_personal_topic,
payload
payload,
datasync_id
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
message.ID,
message.LocalChatID,
message.LastSent,
@ -608,7 +609,8 @@ func (db sqlitePersistence) SaveRawMessage(message *common.RawMessage) error {
message.SendPushNotification,
message.SkipGroupMessageWrap,
message.SendOnPersonalTopic,
message.Payload)
message.Payload,
message.DataSyncID)
return err
}
@ -633,7 +635,8 @@ func (db sqlitePersistence) RawMessageByID(id string) (*common.RawMessage, error
send_push_notification,
skip_group_message_wrap,
send_on_personal_topic,
payload
payload,
datasync_id
FROM
raw_messages
WHERE
@ -653,6 +656,7 @@ func (db sqlitePersistence) RawMessageByID(id string) (*common.RawMessage, error
&skipGroupMessageWrap,
&sendOnPersonalTopic,
&message.Payload,
&message.DataSyncID,
)
if err != nil {
return nil, err
@ -739,6 +743,28 @@ func (db sqlitePersistence) ExpiredEmojiReactionsIDs(maxSendCount int) ([]string
return ids, nil
}
func (db sqlitePersistence) RawMessageIDFromDatasyncID(datasyncID []byte) (id string, err error) {
row := db.db.QueryRow(
`SELECT
id
FROM
raw_messages
WHERE
datasync_id = ?
`, datasyncID)
err = row.Scan(&id)
switch err {
case sql.ErrNoRows:
return "", common.ErrRecordNotFound
case nil:
return id, nil
default:
return "", err
}
}
func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error) {
if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})

View File

@ -777,6 +777,28 @@ func TestHideMessage(t *testing.T) {
require.True(t, actualSeen)
}
func TestDatasyncIdSaved(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)
p := sqlitePersistence{db: db}
messageID := "message-id"
messageDataSyncID := []byte("message-datasync-id")
_, err = p.RawMessageIDFromDatasyncID(messageDataSyncID)
require.Error(t, err)
//save message with datasync id
rawChatMessage := minimalRawMessage(messageID, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
rawChatMessage.DataSyncID = messageDataSyncID
err = p.SaveRawMessage(rawChatMessage)
require.NoError(t, err)
id, err := p.RawMessageIDFromDatasyncID(messageDataSyncID)
require.NoError(t, err)
require.Equal(t, messageID, id)
}
func TestDeactivatePublicChat(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)

View File

@ -1272,7 +1272,7 @@ func (c *Client) registerWithServer(registration *protobuf.PushNotificationRegis
SkipEncryption: true,
}
_, err = c.messageProcessor.SendPrivate(context.Background(), server.PublicKey, rawMessage)
_, err = c.messageProcessor.SendPrivate(context.Background(), server.PublicKey, &rawMessage)
if err != nil {
return err
@ -1374,7 +1374,7 @@ func (c *Client) sendNotification(publicKey *ecdsa.PublicKey, installationIDs []
MessageType: protobuf.ApplicationMetadataMessage_PUSH_NOTIFICATION_REQUEST,
}
_, err = c.messageProcessor.SendPrivate(context.Background(), serverPublicKey, rawMessage)
_, err = c.messageProcessor.SendPrivate(context.Background(), serverPublicKey, &rawMessage)
if err != nil {
return nil, err

View File

@ -110,7 +110,7 @@ func (s *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey,
SkipEncryption: true,
}
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, rawMessage)
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, &rawMessage)
return err
}
@ -133,7 +133,7 @@ func (s *Server) HandlePushNotificationQuery(publicKey *ecdsa.PublicKey, message
SkipEncryption: true,
}
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, rawMessage)
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, &rawMessage)
return err
}
@ -176,7 +176,7 @@ func (s *Server) HandlePushNotificationRequest(publicKey *ecdsa.PublicKey,
SkipEncryption: true,
}
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, rawMessage)
_, err = s.messageProcessor.SendPrivate(context.Background(), publicKey, &rawMessage)
return err
}

View File

@ -12,7 +12,6 @@ import (
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/datasync"
"github.com/status-im/status-go/protocol/encryption"
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/encryption/sharedsecret"
@ -143,28 +142,6 @@ func (m *StatusMessage) HandleEncryption(myKey *ecdsa.PrivateKey, senderKey *ecd
return nil
}
// HandleDatasync processes StatusMessage through data sync layer.
// This is optional and DataSync might be nil. In such a case,
// only one payload will be returned equal to DecryptedPayload.
func (m *StatusMessage) HandleDatasync(datasync *datasync.DataSync) ([]*StatusMessage, error) {
var statusMessages []*StatusMessage
payloads := datasync.Handle(
m.SigPubKey(),
m.DecryptedPayload,
)
for _, payload := range payloads {
message, err := m.Clone()
if err != nil {
return nil, err
}
message.DecryptedPayload = payload
statusMessages = append(statusMessages, message)
}
return statusMessages, nil
}
func (m *StatusMessage) HandleApplicationMetadata() error {
message, err := protobuf.Unmarshal(m.DecryptedPayload)
if err != nil {

View File

@ -153,7 +153,7 @@ func (s *Service) InitProtocol(identity *ecdsa.PrivateKey, db *sql.DB, multiAcco
s.multiAccountsDB = multiAccountDb
s.account = acc
options, err := buildMessengerOptions(s.config, identity, db, s.multiAccountsDB, acc, envelopesMonitorConfig, s.accountsDB, logger)
options, err := buildMessengerOptions(s.config, identity, db, s.multiAccountsDB, acc, envelopesMonitorConfig, s.accountsDB, logger, signal.SendMessageDelivered)
if err != nil {
return err
}
@ -467,6 +467,7 @@ func buildMessengerOptions(
envelopesMonitorConfig *transport.EnvelopesMonitorConfig,
accountsDB *accounts.Database,
logger *zap.Logger,
messageDeliveredHandler protocol.MessageDeliveredHandler,
) ([]protocol.Option, error) {
options := []protocol.Option{
protocol.WithCustomLogger(logger),
@ -477,7 +478,7 @@ func buildMessengerOptions(
protocol.WithAccount(account),
protocol.WithEnvelopesMonitorConfig(envelopesMonitorConfig),
protocol.WithOnNegotiatedFilters(onNegotiatedFilters),
}
protocol.WithDeliveredHandler(messageDeliveredHandler)}
if config.DataSyncEnabled {
options = append(options, protocol.WithDatasync())

View File

@ -0,0 +1,18 @@
package signal
const (
// EventMesssageDelivered triggered when we got acknowledge from datasync level, that means peer got message
EventMesssageDelivered = "message.delivered"
)
// MessageDeliveredSignal specifies chat and message that was delivered
type MessageDeliveredSignal struct {
ChatID string `json:"chatID"`
MessageID string `json:"messageID"`
}
// SendMessageDelivered notifies about delivered message
func SendMessageDelivered(chatID string, messageID string) {
send(EventMesssageDelivered, MessageDeliveredSignal{ChatID: chatID, MessageID: messageID})
}