Mailserver usage on desktop === ## How does the mailserver loop work? - **Initialization** - Before starting the loop, we read the fleets.json file to extract the mailservers for the current fleet - We obtain the list of custom mailservers created by the user - We merge the fleet mailservers and custom mailservers in a single sequence - We start the mailserver loop - **The mailserver loop is executed on a separate thread. Usage of task runner is required to communicate between main thread and mailserver thread - **Every 10 seconds we verify if we are connected to a mailserver or not.** - This verification is done by checking if `activeMailserver` is not empty, and if you are `Connected` to this mailserver. - `Connected` means that a node was received either in a `discovery.summary` or a `wakuv2.peerstats` signal. This node could also be part of the values returned by `admin_peers` RPC method which is executed during the initialization of desktop in `node/core.nim:55` - Each time one of these signals is emitted, the state of a mailserver will change to `Connected` or `Disconnected` depending if it is a peer or not. - If you are connected to a mailserver, the loop will sleep 10 seconds - If you are not connected to a mailserver: - If you have pinned a mailserver in the app settings, we will attempt to `connect` to that node - If there are no pinned mailservers, a new mailserver will be chosen - If there's an active mailserver, it will be marked as `Disconnected` - We drop the peer either calling `admin_removePeer` or `wakuext_dropPeerByID` depending if waku 1 or 2 is used - We set `activeMailserver` to empty - A new mailserver will be selected - **Mailserver selection:** - All the mailservers from the list created during initialization are pinged, expecting they'll reply back in < 500 ms. Mailservers that do not reply back in this time are ignored - For waku1 the RPC method used is "mailservers_ping" - For waku2 the RPC method used is "mailservers_multiAddressPing" - If no mailserver replied back, we stop. We'll try again in the next iteration of the loop - If the mailservers replied back, they are sorted by ascending reply time - We pick a random mailserver among the ones with the lowest latency. The pool size is 1/4 of the mailservers that were pinged succesfully - We attempt to `connect` to that mailserver using the node address - **Mailserver connection:** - The selected mailserver is verified, by checking if it is contained in the list created during initialization - `activeMailserver` is set to the node address or peer id if using waku2 - `mailserver:changed` event is emitted with the node address as argument - If the node is already connected to the mailserver, do nothing - If the node is not connected to the mailserver: - If using waku2: - Dial the peer (this is a blocking operation) - Execute `wakuext_setMailserver` and pass the multiaddress of the mailserver - We set the mailserver state as connected - If using waku1 - Execute `wakuext_updateMailserver` which interanlly executed to `setMailserver` and also attempts to add the peer - The state of the mailserver is changed to `Connecting` because adding a peer and marking it as connected can't be executed sync in WakuV1, because there's a delay between requesting a peer being added, and a signal being received after the peer was added. - Later, once the `discovery.summary` signal is emitted, if the activeMailserver with `Connecting` state appears in the list of peers returned by the signal, we'll mark the mailserver as `Connected` and emit the `mailserverAvailable` event - If we are already connected to the mailserver, the `mailserverAvailable` event is emitted ### Events - `mailserver:changed`: used to notify the UI what's the current mailserver being used. It can be seen on `Sync Settings` - `mailserverAvailable` - It's used to notify desktop that historic messages can be retrieved. This is done by invoking `wakuext_requestAllHistoricMessages`. - It's also used to retrieve pending community info via `wakuext_ requestCommunityInfoFromMailserver`. It's normal to see these events happening more than once in the same session, if you are offline. Currently your online/offline status depend on the number of peers. If you have 0 peers you're considered offline. ### Custom mailservers - Only available for WakuV1 - Require a name and a enode address ### Pinning a mailserver - Only available for WakuV1 - This will set an specific mailserver to be used for all the history requests in the next loop of the mailserver cycle (~10 seconds later) ## Problems with mailserver implementation - If you connect to a mailserver and the history it returns is incomplete, desktop and mobile is not able to request the history for that same period of time - Could [21/WAKU2-FAULT-TOLERANT-STORE](https://rfc.vac.dev/spec/21/) help with this somehow so store nodes can have a complete history? - What alternatives are there for waku1 - - Identifying offline periods is somewhat naive. Since we can't / shouldn't *phone home*, it's possible we miss periods of being offline, since it takes up to 20 seconds to notice that we are not connected to any peer. In that time it's possible some messages are not loaded. Also, it's possible that the offline period lasts less than 20 seconds, so the node might not even notice it's offline, and end up missing messages. - Should we constantly ping a random node from the fleet to know if we are online? what impact could this have in data usage? - @anthony's idea of making the history request timestamp contain extra time as buffer for loading messages is helpful - Could we every N minutes request message history for the last N minutes? (at least on desktop). Does it have a noticieable impact on the store nodes? - TODO: research how mobile devices and browsers notice when connection is lost - Mailserver gaps should be removed. Currently mailserver gaps are being displayed on the UI. Desktop should handle mailserver gaps automatically by executing wakuext_fillGaps as soon as a gap message is received. - We should get rid of the 'Fetch more messages' button. Issue is tracked here: https://github.com/status-im/status-desktop/issues/3027 , and it contains what should be the suggested behavior. ## Possible changes/improvements for waku2 - Instead of using the ping function from status-go, we can use ping protocol - Adding a custom node for waku2 means that the custom mailserver section must accept a multiaddress instead of a enode address - In the mailserver cycle, instead of using the fleet configuration, we should use the peerstore to obtain the list of peers that support the store protocol, and choose the store node from that list. THe same logic for choosing a node based on ping time could be used, however it requires additional conditions or a reputation mechanism to properly choose which node can be chosen.