Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle history archive magnetlink messages #2585

Merged
merged 3 commits into from
May 10, 2022
Merged

Conversation

0x-r4bbit
Copy link
Member

This introduces the ability for status notes to handle community
history archive magnetlinks. To make this work, a few things are needed:

  1. A new database table has been introduced to store message archive
    hashes. This is necessary so status nodes can determine whether or
    not they need to download a certain archive
  2. The messenger's handleRetrievedMessages() has been exteded to take
    magnetlink messages into account
  3. New APIs were added to download torrent data given a magnetlink and
    also to extract messages from downloaded archives, which are then
    later fed to handleRetrievedMessages

Closes #2568

@ghost
Copy link

ghost commented Mar 14, 2022

Pull Request Checklist

  • Have you updated the documentation, if impacted (e.g. docs.status.im)?
  • Have you tested changes with mobile?
  • Have you tested changes with desktop?

@0x-r4bbit
Copy link
Member Author

This needs tests and some fine-tuning but should be in a reviewable shape.

@status-im-auto
Copy link
Member

status-im-auto commented Mar 14, 2022

Jenkins Builds

Click to see older builds (85)
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 81d88dc #1 2022-03-14 12:08:10 ~2 min linux 📦zip
✔️ 81d88dc #1 2022-03-14 12:09:40 ~4 min ios 📦zip
✔️ 81d88dc #1 2022-03-14 12:11:27 ~6 min android 📦aar
✔️ 7e39963 #2 2022-03-22 14:18:30 ~3 min linux 📦zip
✔️ 7e39963 #2 2022-03-22 14:19:51 ~4 min android 📦aar
✔️ 7e39963 #2 2022-03-22 14:20:45 ~5 min ios 📦zip
✔️ 83322d2 #3 2022-03-22 16:28:40 ~1 min linux 📦zip
✔️ 83322d2 #3 2022-03-22 16:30:10 ~3 min ios 📦zip
✔️ 83322d2 #3 2022-03-22 16:31:40 ~4 min android 📦aar
✔️ e8e7cbe #4 2022-03-23 18:28:06 ~2 min ios 📦zip
✔️ e8e7cbe #4 2022-03-23 18:30:49 ~5 min linux 📦zip
✔️ e8e7cbe #4 2022-03-23 18:31:10 ~5 min android 📦aar
✔️ dfdf2a9 #5 2022-03-25 11:30:04 ~8 min linux 📦zip
✔️ dfdf2a9 #5 2022-03-25 11:31:11 ~10 min ios 📦zip
✔️ dfdf2a9 #5 2022-03-25 11:31:28 ~10 min android 📦aar
✔️ 1c34352 #6 2022-03-25 17:05:28 ~2 min linux 📦zip
✔️ 1c34352 #6 2022-03-26 06:25:22 ~4 min ios 📦zip
✔️ 1c34352 #6 2022-03-26 10:56:38 ~3 min android 📦aar
✔️ eb4f9e3 #7 2022-03-28 15:55:08 ~4 min ios 📦zip
✔️ eb4f9e3 #7 2022-03-28 15:57:18 ~6 min android 📦aar
✔️ eb4f9e3 #7 2022-03-28 15:57:30 ~6 min linux 📦zip
✔️ 973d2ca #8 2022-03-28 16:21:45 ~4 min ios 📦zip
✔️ 973d2ca #8 2022-03-28 16:24:52 ~7 min linux 📦zip
✔️ 973d2ca #8 2022-03-28 16:25:13 ~7 min android 📦aar
✔️ ca4350c #9 2022-04-05 16:53:34 ~1 min linux 📦zip
✔️ ca4350c #9 2022-04-05 16:55:31 ~3 min android 📦aar
✔️ ca4350c #9 2022-04-05 16:56:21 ~4 min ios 📦zip
✔️ 7473f5a #10 2022-04-06 10:49:07 ~2 min ios 📦zip
✔️ 7473f5a #10 2022-04-06 10:49:33 ~2 min linux 📦zip
✔️ 7473f5a #10 2022-04-06 10:50:00 ~3 min android 📦aar
✔️ 7473f5a #11 2022-04-06 11:02:17 ~1 min linux 📦zip
✔️ 7473f5a #11 2022-04-06 11:02:25 ~1 min ios 📦zip
✔️ 7473f5a #11 2022-04-06 11:04:51 ~4 min android 📦aar
✔️ daaf9f6 #12 2022-04-06 11:06:51 ~1 min linux 📦zip
✔️ daaf9f6 #12 2022-04-06 11:08:26 ~2 min android 📦aar
✔️ daaf9f6 #12 2022-04-06 11:09:59 ~4 min ios 📦zip
✔️ bb7957e #13 2022-04-11 10:24:32 ~2 min ios 📦zip
✔️ bb7957e #13 2022-04-11 10:26:00 ~3 min android 📦aar
✔️ bb7957e #13 2022-04-11 10:26:56 ~4 min linux 📦zip
✔️ 81b5eab #14 2022-04-11 11:47:27 ~5 min android 📦aar
✔️ 81b5eab #14 2022-04-11 11:47:48 ~6 min linux 📦zip
✔️ 81b5eab #14 2022-04-11 11:53:22 ~11 min ios 📦zip
✔️ 57c063d #15 2022-04-12 08:48:13 ~2 min linux 📦zip
✔️ 57c063d #15 2022-04-12 08:48:41 ~2 min ios 📦zip
✔️ 57c063d #15 2022-04-12 08:49:30 ~3 min android 📦aar
✔️ b2cd346 #16 2022-04-12 09:22:14 ~1 min linux 📦zip
✔️ b2cd346 #16 2022-04-12 09:23:59 ~3 min android 📦aar
✔️ b2cd346 #16 2022-04-12 09:24:24 ~3 min ios 📦zip
✔️ a6e92f4 #17 2022-04-12 10:12:28 ~2 min ios 📦zip
✔️ c0426c5 #18 2022-04-12 10:20:32 ~4 min ios 📦zip
✔️ c0426c5 #18 2022-04-12 10:22:13 ~5 min linux 📦zip
✔️ c0426c5 #18 2022-04-12 10:25:16 ~8 min android 📦aar
c364972 #19 2022-04-22 07:39:02 ~1 min android 📄log
c364972 #19 2022-04-22 07:39:22 ~1 min ios 📄log
c364972 #19 2022-04-22 07:39:57 ~1 min linux 📄log
9d2e6c8 #20 2022-04-22 07:40:44 ~30 sec ios 📄log
9d2e6c8 #20 2022-04-22 07:40:49 ~35 sec linux 📄log
9d2e6c8 #20 2022-04-22 07:40:58 ~48 sec android 📄log
6ab8643 #21 2022-04-22 07:43:41 ~28 sec ios 📄log
6ab8643 #21 2022-04-22 07:43:48 ~35 sec linux 📄log
6ab8643 #21 2022-04-22 07:43:57 ~48 sec android 📄log
✔️ a655450 #22 2022-04-22 07:59:36 ~3 min linux 📦zip
✔️ a655450 #22 2022-04-22 07:59:46 ~3 min ios 📦zip
✔️ a655450 #22 2022-04-22 07:59:52 ~3 min android 📦aar
✔️ 2682a09 #23 2022-04-22 08:43:37 ~1 min linux 📦zip
✔️ 2682a09 #23 2022-04-22 08:44:03 ~1 min ios 📦zip
✔️ 2682a09 #23 2022-04-22 08:45:19 ~3 min android 📦aar
✔️ 0c8d798 #24 2022-05-04 12:16:48 ~2 min linux 📦zip
✔️ 0c8d798 #24 2022-05-04 12:17:40 ~2 min ios 📦zip
✔️ 0c8d798 #24 2022-05-04 12:18:28 ~3 min android 📦aar
✔️ 78cdfd0 #25 2022-05-04 13:52:04 ~2 min linux 📦zip
✔️ 78cdfd0 #25 2022-05-04 13:52:44 ~3 min ios 📦zip
✔️ 78cdfd0 #25 2022-05-04 13:53:59 ~4 min android 📦aar
✔️ 0c201b5 #26 2022-05-06 10:03:14 ~3 min linux 📦zip
✔️ 0c201b5 #26 2022-05-06 10:03:42 ~3 min ios 📦zip
✔️ 0c201b5 #26 2022-05-06 10:03:55 ~4 min android 📦aar
✔️ 9727028 #27 2022-05-06 10:06:06 ~2 min linux 📦zip
✔️ 9727028 #27 2022-05-06 10:06:42 ~2 min ios 📦zip
✔️ 9727028 #27 2022-05-06 10:06:55 ~2 min android 📦aar
✔️ ff46fe1 #28 2022-05-09 11:20:21 ~2 min linux 📦zip
✔️ ff46fe1 #28 2022-05-09 11:21:34 ~4 min ios 📦zip
✔️ ff46fe1 #28 2022-05-09 11:23:25 ~6 min android 📦aar
✔️ f7dea6d #29 2022-05-09 12:27:22 ~2 min ios 📦zip
✔️ f7dea6d #29 2022-05-09 12:27:55 ~2 min linux 📦zip
✔️ f7dea6d #29 2022-05-09 12:29:19 ~4 min android 📦aar
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 1b49784 #30 2022-05-10 06:53:03 ~2 min ios 📦zip
✔️ 1b49784 #30 2022-05-10 06:53:53 ~3 min linux 📦zip
✔️ 1b49784 #30 2022-05-10 06:54:15 ~4 min android 📦aar
✔️ b3fa110 #31 2022-05-10 09:13:34 ~1 min ios 📦zip
✔️ b3fa110 #31 2022-05-10 09:13:36 ~1 min linux 📦zip
✔️ b3fa110 #31 2022-05-10 09:14:58 ~3 min android 📦aar

}
m.torrentTasks[id] = ml.InfoHash

<-torrent.GotInfo()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here we're waiting for the magnetlink to emit its metadata (this is needed for us to know what files the torrent will have, so having this info is crucial).

During testing, I've experienced that it sometimes takes a long time to receive a signal, at which point nothing happens here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you are offline? We should probably timeout this if it could hang forever

<-torrent.GotInfo()
files := torrent.Files()

indexFile := files[1]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We always expect exactly two files data and index. So accessing [1] is safe, but we should probably still dynamically determine, in case we'll add more files to these torrent sin the future (maybe due to status-im/specs#167)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be that files is of different length? (say 1 or 0), even in cases where the torrent is malformed.
If that's the case, best to error check and return an error, since a panic would just crash the app, and if someone manages to push a malformed torrent for example, it would just crash all clients.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea good point. I'll update it so it'll search for an index file and if it doesn't exist it'll return early as the torrent is malformed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

return m.communitiesManager.UpdateMagnetlinkMessageClock(id, clock)
}
}
return nil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I had most of this logic inside communitiesManaegr, however because we need access to handleRetrievedMessages() I've moved this here. Lemme know if there's a different way to get access to messenger APIs inside communitiesManager otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use pub/sub, but we can have a look at it later

@@ -1853,7 +1853,7 @@ func (db sqlitePersistence) GetDeletes(messageID string, from string) ([]*Delete
}

func (db sqlitePersistence) SaveEdit(editMessage EditMessage) error {
_, err := db.db.Exec(`INSERT INTO user_messages_edits (clock, chat_id, message_id, text, source, id) VALUES(?,?,?,?,?,?)`, editMessage.Clock, editMessage.ChatId, editMessage.MessageId, editMessage.Text, editMessage.From, editMessage.ID)
_, err := db.db.Exec(`INSERT OR REPLACE INTO user_messages_edits (clock, chat_id, message_id, text, source, id) VALUES(?,?,?,?,?,?)`, editMessage.Clock, editMessage.ChatId, editMessage.MessageId, editMessage.Text, editMessage.From, editMessage.ID)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not what we want. I noticed that, when replaying history messages into the DB, message edits were causing SQL errors, saying that the entries have to be unique. So I've added this here to satisfy it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cammellos Would be cool if you could confirm whether this here is okay

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see, it should not matter, since all the fields are not modified after insertion, so it would just be replacing the same message.
Though if you make it not return an error, the code will process the edit multiple times, not sure whether that is an issue (in theory it should be fine), but we need to make sure we test edits before merging, just to make sure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per offline discussion, I wanted to changes this to leave out the OR REPLACE and check for the error, which can then be interpreted as "don't process this message".

While doing this, I realized I couldn't reproduce the error anymore. So I'll just remove this change for now.

@0x-r4bbit 0x-r4bbit force-pushed the issue/2567 branch 2 times, most recently from 5881a6d to 3e1eb0a Compare March 21, 2022 14:53
@0x-r4bbit 0x-r4bbit requested review from Samyoul and cammellos March 21, 2022 15:01
@0x-r4bbit
Copy link
Member Author

Please review the last commit of this PR

@0x-r4bbit 0x-r4bbit force-pushed the issue/2567 branch 2 times, most recently from 8b201d4 to cffda3f Compare March 30, 2022 07:41
@0x-r4bbit 0x-r4bbit force-pushed the issue/2567 branch 3 times, most recently from 0beba92 to eecb4af Compare April 5, 2022 13:46
@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch 3 times, most recently from 9d2e6c8 to 6ab8643 Compare April 22, 2022 07:42
@@ -5,6 +5,7 @@ import (
"database/sql"
"fmt"
"os"
"sort"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment here is just to ensure this file is being reviewed, as github collapses it due to the amount of changes.

@@ -219,5 +219,5 @@ func (db *Database) AddressExists(address types.Address) (exists bool, err error
}

func (db *Database) GetNodeConfig() (*params.NodeConfig, error) {
return nodecfg.GetNodeConfig(db.db)
return nodecfg.GetNodeConfigFromDB(db.db)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to make this change because GeNodeConfig no longer exists. @richard-ramos is that related to you changes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it was surprising that this wasnt caught by the CI

return nil, err
}

m.logger.Debug("Adding torrent via magnetlink for community", zap.Any("id", id), zap.Any("magnetlink", magnetlink))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use strings for zap zap.String("id", id.String()) or `zap.String("magnet", magnetlink.String()), so you get the hexencoded version (otherwise is going to be base encoded)

}
m.torrentTasks[id] = ml.InfoHash

<-torrent.GotInfo()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you are offline? We should probably timeout this if it could hang forever

m.logger.Debug("Downloading history archive index")
indexFile.Download()
for {
if indexFile.BytesCompleted() == indexFile.Length() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a busy loop, you want to wait you should use a different pattern (use a channel,select/polling etc)

startIndex := int(metadata.Offset) / pieceLength
endIndex := startIndex + int(metadata.Size)/pieceLength

m.logger.Debug("Downloading data for message archive", zap.Any("hash", hash))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use lowercase for log entries

}

for _, message := range archive.Messages {
filter := m.transport.FilterByTopic(message.Topic)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are you checking exactly here? meaning, you are checking the topic matches, but generally that's not enough to ensure the message is for you and you should process it.
Which messages should we process and in which case they should not be processed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function (ExtractMessagesFromHistoryArchive) aims to create a map[transport.Filter][]*types.Message from a downloaded archive, so they can be passed to handleRetrievedMessages.

Because we're only getting the topic from each archive message, we need to figure out what filter they belong to, so we can create the correct return type.
All messages extracted from an archive (and passed to handleRetrievedMessages) are considered to be processed.

}

if m.config.torrentConfig != nil && m.config.torrentConfig.Enabled && settings.HistoryArchiveSupportEnabled {
signedByOwnedCommunity, err := m.communitiesManager.IsAdminCommunity(communityPubKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a first glance, I think we should be using the key of the community to send this messages, rather than the admins? (there's arguments for both, but worth considering)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the message with the magnet link is signed by the community key.

However this part of the code is handling the magnet link messages. So what we're checking here is: Am I the admin/owner of this community? If yes, then I'm not interested in handling the magnet link because I'm expected to be node that has created the magnet link message from a history archive in the first place.

In other words: only members of the community are interested in this, not admins/owners

// We are only interested in a community archive magnet link
// if it originates from a community that the current account is
// part of and doesn't own the private key at the same time
if !signedByOwnedCommunity && joinedCommunity && clock >= lastClock {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering why we are not interested if we are the admin, is the assumption that we would have the same messages therefore is not useful/is redundant?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, the admin is the one that publishes the history archives via magnetlinks, so that node already has the history. Only members are downloading torrent data

return
}

_, err = m.handleRetrievedMessages(messagesToHandle, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit dangerous, we currently don't run handleRetrieveMessages in parallel, so weird things might happen

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.. I wonder what such weird things could be, given that handleRetrieveMessages has various checks for incoming messages and handling out of order messages etc.

Any suggestions on how else this should be done?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First thing that comes to mind is to have a channel, and handle retrieved messages it's called on it, so you have 2 producers (polling from the network, and torrent) and a single consumer, a bit more complex, but we don't have to think about the code running in parallel, as it might lead to difficult to find bugs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I'll see if I can make that happen. Thanks for your input!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to publish the response, otherwise the client will be in inconsistent state,

publishMessengerResponse(response)
, have you tested this on desktop to see if changes are reflected on the frontend?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In desktop, what we do is we listen for the HistoryDownloaded signal, and if that has happened we refetch messages from status-go for the current active channel.

return m.communitiesManager.UpdateMagnetlinkMessageClock(id, clock)
}
}
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use pub/sub, but we can have a look at it later

@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch from 2682a09 to 0c8d798 Compare May 4, 2022 12:14
archiveLogger, err := lc.Build()
if err != nil {
return nil, errors.Wrap(err, "failed to create a archive logger")
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a new logger so we get some output in stdout when archives are created/downloaded (easier for debugging, kinda hard when stuff only gets written to geth.log)

select {
case <-time.After(20 * time.Second):
return nil, errors.New("torrent has timed out")
case <-torrent.GotInfo():
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cammellos I've added a time out of 20 seconds here in case torrent.GotInfo() doesn't emit anything

defer ticker.Stop()
for {
select {
case <-ticker.C:
Copy link
Member Author

@0x-r4bbit 0x-r4bbit May 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make the busy loop less busy, we're now using a 200 ms ticker, which should be more than enough.

if err != nil {
logger.Error("failed to write history archive messages to database", err)
continue
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cammellos lemme know if this is what you had in mind

Copy link
Member

@richard-ramos richard-ramos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, but in general LGTM! 🎖️

@@ -443,6 +443,11 @@ func (p *Persistence) GetWakuMessagesByFilterTopic(topics []types.TopicType, fro
return messages, nil
}

func (p *Persistence) HasCommunityArchiveInfo(communityID types.HexBytes) (exists bool, err error) {
err = p.db.QueryRow(`SELECT count(1) FROM communities_archive_info WHERE community_id = ?`, communityID.String()).Scan(&exists)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's worth it, but depending on the number of rows in communities_archive_info, EXISTS is more efficient

Suggested change
err = p.db.QueryRow(`SELECT count(1) FROM communities_archive_info WHERE community_id = ?`, communityID.String()).Scan(&exists)
err = p.db.QueryRow(`SELECT EXISTS (SELECT 1 FROM communities_archive_info WHERE community_id = ?)`, communityID.String()).Scan(&exists)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is cool!

return err
}

if m.config.torrentConfig != nil && m.config.torrentConfig.Enabled && settings.HistoryArchiveSupportEnabled {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

settings can be null if communities_settings does not contain the id

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

if !signedByOwnedCommunity && joinedCommunity && clock >= lastClock {

m.communitiesManager.UnseedHistoryArchiveTorrent(id)
go func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a 'slow' operation? what happens if an user logouts while the goroutine is still executing? If it's important for the goroutine to finish before logout, maybe it's a good idea to add a sync.WaitGroup in messenger and wait for it in func (m *Messenger) Shutdown() (err error) (or maybe this is already handled somewhere else?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very good point. Adding this now

@richard-ramos
Copy link
Member

richard-ramos commented May 5, 2022

Please update the VERSION file

@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch from 78cdfd0 to 0c201b5 Compare May 6, 2022 09:59
@0x-r4bbit
Copy link
Member Author

@cammellos @richard-ramos thanks for all your comments.

  • I've updated the SELECT query for checking the existence of archive hash info
  • I've added a waitgroup to ensure shutting down the client waits for downloading torrent data to finish
  • I've reduced the time interval for checking whether the download of the torrent index file is done to 100ms
  • I've introduced a mutex lock for handleRetrievedMessages to ensure it doesn't conflict when executed via message archive protocol

@churik
Copy link
Member

churik commented May 9, 2022

If follow the processes (which are still TBD, but better to check twice) we need to check it on the mobile client-side briefly and on the desktop side as well.
Only in case, you're absolutely sure that it will not introduce any regression issues we can merge it as it is
cc @anastasiyaig

@anastasiyaig
Copy link
Contributor

@churik u may test it on mobile side and provide feedback. It was not yet tested on desktop, @elina2015 please check this today

@0x-r4bbit
Copy link
Member Author

@churik u may test it on mobile side and provide feedback. It was not yet tested on desktop

Just to let you know, this feature is completely turned off on mobile, so the only thing to test/check there is that it indeed doesn't create archives, nor downloads them.

@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch from 9727028 to ff46fe1 Compare May 9, 2022 11:17
@qoqobolo
Copy link

qoqobolo commented May 9, 2022

Just to let you know, this feature is completely turned off on mobile, so the only thing to test/check there is that it indeed doesn't create archives, nor downloads them.

Hey, thank you for the clarification!

But for context: in such cases, this is not really testing of the feature itself. It was decided (at least until there’s a better solution, suggestions are still welcome and appriciated) to create and test clones of Go pull requests in client repositories (Mobile and Desktop) in order to avoid issues that sometimes arise after PRs are merged without any testing on the Go side (discussion here).
So we just run e2e tests, sometimes do some smoke-testing using the corresponding PR in our repo, and then approve the Go PR.

Regarding this particular PR: looks good from the Mobile side, no issues found.

@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch from f7dea6d to 1b49784 Compare May 10, 2022 06:49
0x-r4bbit added 3 commits May 10, 2022 11:11
This introduces the ability for status notes to handle community
history archive magnetlinks. To make this work, a few things are needed:

1. A new database table has been introduced to store message archive
   hashes. This is necessary so status nodes can determine whether or
   not they need to download a certain archive
2. The messenger's `handleRetrievedMessages()` has been exteded to take
   magnetlink messages into account
3. New APIs were added to download torrent data given a magnetlink and
   also to extract messages from downloaded archives, which are then
   later fed to `handleRetrievedMessages`

Closes #2568
@0x-r4bbit 0x-r4bbit force-pushed the issue/2568-proper branch from 1b49784 to b3fa110 Compare May 10, 2022 09:11
@0x-r4bbit 0x-r4bbit merged commit d884749 into develop May 10, 2022
@0x-r4bbit 0x-r4bbit deleted the issue/2568-proper branch May 10, 2022 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle magnet link messages
7 participants