Synchronisation of user data between mobile app and Desktop app #14
HenrikJannsen
started this conversation in
General
Replies: 1 comment 2 replies
-
I guess that having desktop and mobile client sync directly between themselves has been examined and discarded as an option? The bad: both mobile and desktop will need to be online at the same time for the sync to happen, and the user needs to be prompted to choose which one he will be using from then on: going out, will need to turn on pc and start on mobile to handshake, and give control to mobile. And viceversa when coming back home. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Based on the idea laid out at [1] I want to describe the concept in more detail.
Problem
A Bisq 2 user who installs the mobile application would like to use the same user profile on both Desktop and mobile, otherwise they cannot react to ongoing trades initiated on the Desktop app while being mobile, leading to frustration due not fulfilled expectations.
Furthermore for sellers who have invested in reputation it would be frustrating to need to build up new reputation when using the mobile app.
I think both those reasons make the requirement for syncing data between the 2 platforms a must-have requirement.
Data
We are persisting application date as protobuf files to disk. We use a fine-grained file structure where most data types have their dedicated data storage. E.g. for private chat messages there is one file only containing that. For trade messages the same.
Data is read only once at startup and updated when the data changes. At shutdown we ensure that pending changes get persisted. We keep data in memory and do not do queries as in typical DB use cases.
We use different directories/categories for storage:
Cache and network can be recovered from the network data and are only kept to reduce network traffic and improve performance.
Settings is used for UI settings like selected markets, user settings etc. It is to some extent Desktop-app specific (layout of app window). For mobile we likely do not need to re-use the settings.
Private is the only relevant directory which requires synchronization.
Identity related storage files:
Those data are written only once when the user identity is created. Thus synchronization is a one time effort. If the Desktop user creates multiple profiles though we need to update if we support multiple user profiles on mobile.
User data:
User account data. Can be updated any time thus needs sync.
Messages:
Those are the trade data, the trade messages, private messages as well as utility data for resilient message delivery.
Those need to be synced each time the user sends or receives those messages or trade state changes.
The file size of an app I used is about 50 KB in total. But if more trades and private messages are present that can become larger, but for most users it will be in the 50-500 KB range..
Synchronization
As the data are not on a central location we need to provide an update mechanism when the user switches to the other platform.
We do not support parallel usage which would also cause issues with network behavior (Tor would be confused if 2 hidden services are running - messages would get sent randomly to one or the other node). To avoid accidental parallel usage we need a lock mechanism.
Bisq sync service
We introduce a http server which accepts requests for storing compressed and encrypted data, secured by a pub key and a signature. It also provides versioning and locking.
The model is very similar to that of the
AuthenticatedDataStorageService
in the Bisq 2 network storage system.The below data definitions are just for the purpose of concept discussion and will likely be more complex structure like at
AuthenticatedData
. It is assumed that most of the existingAuthenticatedDataStorageService
code can be used as template.Messages
AddDataRequest
payload
(encrypted data (size limited)pubKey
signature
(signed message = hash ofpayload
+sequenceNumber
)date
sequenceNumber
SyncRequest
pubKey
signature
(signed message =pubKeyHash
+date
)sequenceNumber
date
SyncResponse
serverPubKey
serverSignature
(signed message = hash ofpayload
)AddDataRequest
Maintenance
We do not remove the
AddDataRequest
as keeping the data after sync can be useful as backup mechanism.To avoid ever growing storage we apply a time to life after which expired data gets removed. 2 weeks might be a reasonable TTL.
Syncing process
Before the application reads the persisted data and connects to the network we do the syncing process.
Create and send SyncRequest
User checks if they have a local
sequenceNumber
, if so they use that otherwise it is 0.Tasks for server when receiving a
SyncRequest
:private
data directory and store it locallypubKeyHash
for lookup)pubKeyHash
for lookup)date
is in tolerance range (should be current date, but we allow +/- 2 hours)sequenceNumber
of data is higher than the requester'ssequenceNumber
SyncResponse
The server blocks other requests using the same
pubKey
to ensure atomic state change.If any task fails the server roll back to the initial state and send back a error message.
In case a dangling lock was detected the user can request to reset the lock after confirming that no other app is running.
Receive SyncResponse
Tasks for client when receiving the
SyncResponse
:serverPubKey
serverSignature
AddDataRequest
data:sequenceNumber
(must be higher thansequenceNumber
from request)pubKey
signature
payload
private
data directory to backup locationprivate
data directorysequenceNumber
with newsequenceNumber
Start normal application startup procedure
Read persisted data (containing now our updated data) and startup application.
User shuts down the app
At shut down we apply the normal shut down procedure but at the very last step before stopping the JVM we add the process for uploading our data to the sync service.
Send
AddDataRequest
Tasks for client:
private
data directory is different to the locally stored hash at startup. If it is the same no data has been changed and we shut down.private
data directorypayload
)sequenceNumber
payload
+sequenceNumber
AddDataRequest
Tasks for service when receiving a
AddDataRequest
:pubKeyHash
for lookup)date
is in tolerance range (should be current date, but we allow +/- 2 hours)pubKeyHash
for lookup), check ifsequenceNumber
of request is higher than thesequenceNumber
of the service's dataAddDataRequest
was present move it to a backup location.AddDataRequest
Once client received a success response they continue with shutdown. Otherwise it reacts to the error message.
Final shutdown
Now we are complete and can terminate the JVM.
Tor support
It would be good to use tor for the sync service, though that adds some complications as tor is not initialized at the moment where we would like to hook in that service. The current startup process is on a high level as follows:
Thus delaying the sync process after Tor has started (we do not need a hidden service on the Bisq add side for requesting the sync service) would become problematic.
The probably most feasible solution to that is to start tor before reading persisted data. This would not work for the very first start as the keys are generated later, but in that case we do not need the sync anyway. It would need more investigation in the code base is that approach is feasible.
Another approach would be to block any write operation until the syn service is completed and block initialization of other services. In case we got an updated from sync we could re-apply the reading of the persisted data and restart the service initialization.
Failure handling
To avoid risks of data corruption, loss, unintended locks we can add a few features which should make those risks manageable.
It should follow a transactional model where a change of state is an atomic operation.
[1] bisq-network/bisq2#2665 (reply in thread)
Beta Was this translation helpful? Give feedback.
All reactions