Synchronization protocol

The swarm chat provides new possibilities for every device. Now, it’s possible to sync history between devices by sharing the related repository. Devices sync needs to be redefined to follow those changes.

A lot of scenarios are defined in the Swarm design document, however, this doesn’t imply for syncing conversations between devices for the same user. Some new scenarios must be written.

Old method

Device sync were done via the DHT. Because every value MUST NOT exceed 64k, conversations were not sent in device sync, nor member profiles, because it’s too heavy. This is a problem and MUST be improved.

In the old method, the daemon is listening on “inbox:DEVICE_ID” for DeviceSync values which contains the contact list to sync (cf AccountManager::startSync());

NOTE: The curretn DeviceSync value present on the DHT is deprecated with this draft.

New method

Since Jami has the ConnectionManager, using p2p socket is possible to perform sync quickly with big values (cause the socket is not limited in data)

Now, this is the scenario used to sync:

  1. When the device (A) goes online, it announces its presence via a DeviceAnnouncement like the OldMethod

  2. Other devices (!A) will detect that announce and will ask this device through the ConnectionManager to open a new channel named “sync://DEVICE_ID_A”. (Note: A will get announcement from other devices, so it will asks for sync channels too).

  3. As soon as this channel is opened, the device which is asking this channel will send a DeviceSync (cf next part) value containing its known conversations and contacts.

  4. A will check the DeviceSync value and:

    • Remove contacts if it detects removed contacts

    • Add contacts if it detects added contacts

    • Remove conversations if it detects removed conversations

    • Add conversations if it detects added conversations

    • Remove conversation’s requests if request is accepted (now in conversations)/declined

    • Add conversation’s requests if detected

Note: If A detects new conversations, it will asks the device which announced that conversation to clone the repository through a git channel (so like described in Swarm chat design)

Device Sync

This value is a JSON containing:

{
    "contacts": [/* Contacts (TODO) */],
    "conversation": [
        { "id":"convID", "created":TIMESTAMP, "removed":OPTIONAL_TIMESTAMP },
        { "id":"convID2", "created":TIMESTAMP2, "removed":OPTIONAL_TIMESTAMP2 } /* ... */
    ],
    "conversationsRequests": [
        { "id":"convID", "received":TIMESTAMP, "declined":OPTIONAL_TIMESTAMP,
          "members":[], "metadatas:[] },
        { "id":"convID2", "received":TIMESTAMP2, "declined":OPTIONAL_TIMESTAMP2
          "members":[], "metadatas:[] } /* ... */
    ],
}

User stories

Sync when adding device

  • Alice creates a conversation

  • (Optional) Alice add some messages

  • Alice adds another device

  • The other device should receives and sync the conversation previously created

Sync when connect a device

  • Alice creates a conversation

  • (Optional) Alice add some messages

  • Alice connects another device

  • The other device should receives and sync the conversation previously created

Sync between multiple devices

  • Alice got 2 devices

  • Alice creates a conversation

  • The other device should receives and sync the conversation created on one of the devices

Sync for detecting new requests

  • Alice receives a conversation’s request

  • Alice add a new device

  • The other device should retrieve the requests from device A

Sync for accepted requests

  • Alice has 2 devices

  • Alice accepts a conversation’s request

  • The other device should detect the accepted request

Sync for decline requests

  • Alice has 2 devices

  • Alice declines a conversation’s request

  • The other device should detect the declined request

Current implementation

gerrit#15584 implements this page