summaryrefslogtreecommitdiff
path: root/design-documents/005-wallet-backup-sync.rst
diff options
context:
space:
mode:
Diffstat (limited to 'design-documents/005-wallet-backup-sync.rst')
-rw-r--r--design-documents/005-wallet-backup-sync.rst331
1 files changed, 331 insertions, 0 deletions
diff --git a/design-documents/005-wallet-backup-sync.rst b/design-documents/005-wallet-backup-sync.rst
new file mode 100644
index 00000000..26dbbf17
--- /dev/null
+++ b/design-documents/005-wallet-backup-sync.rst
@@ -0,0 +1,331 @@
+Design Doc 005: Wallet Backup and Sync
+######################################
+
+.. warning::
+
+ This is an unfinished draft.
+
+Summary
+=======
+
+This document discusses considerations for backup and synchronization of wallets.
+
+
+Requirements
+============
+
+* Backup and sync must not require any synchronous communication between the
+ wallets
+* Wallets operating (payments/withdrawals/...) for longer periods of time without
+ synchronizing should be handled well
+* Conflicts should be resolved automatically in pretty much all cases
+* One wallet can be enrolled with multiple sync servers, and a wallet can
+ join
+* Other wallets connected to the sync server are trusted.
+
+Proposed Solution
+=================
+
+The blob stored on the backup/sync server is a compressed and encrypted JSON file.
+
+The various entity types managed by the wallet are modeled LWW-Sets (Last Write
+Wins Set CRDT). Timestamps for inserts/deletes are are Lamport timestamps. Concurrent, conflicting insert/delete
+operations are resolved in favor of "delete".
+
+The managed entities are:
+
+* set of exchanges with the data from /keys, /wire
+* set of directly trusted exchange public keys
+* set of trusted auditors for currencies
+* set of reserves together with reserve history
+* set of accepted bank withdrawal operations
+* set of coins together with coin history and blinding secret (both for normal withdrawal and refresh)
+ and coin source info (refresh operation, tip, reserve)
+* set of purchases (contract terms, applied refunds, ...)
+* assignment of coins to their "primary wallet"
+
+(Some of these might be further split up to allow more efficient updates.)
+
+Entities that are **not** synchronized are:
+
+* purchases before the corresponding order has been claimed
+* withdrawal operations before they have been accepted by the user
+
+Entities that **could** be synchronized (to be decided):
+
+* private keys of other sync accounts
+* coin planchets
+* tips before the corresponding coins have been withdrawn
+* refresh sessions (not only the "meta data" about the operation,
+ but everything)
+
+
+Garbage collection
+------------------
+
+There are two types of garbage collection involved:
+
+1. CRDT tombstones / other administrative data in the sync blob. These can be deleted
+ after we're sure all wallets enrolled in the sync server have a Lamport timestamp
+ larger than the timestamp of the tombstone. Wallets include their own Lamport timestamp
+ in the sync blob:
+
+ .. code:: javascript
+
+ {
+ clocks: {
+ my_desktop_wallet: 5,
+ my_phone_wallet: 3
+ },
+ ...
+ }
+
+ All tombstones / overwritten set elements with a timestamp smaller than the
+ smallest clock value can be deleted.
+
+2. Normal wallet GC. The deletion operations resulting from the wallet garbage
+ collection (i.g. deleting legally expired denomination keys, coins, exchange
+ signing keys, ...) are propagated to the respective CRDT set in the sync
+ blob.
+
+
+Ghost Entities
+--------------
+
+Sometimes a wallet can learn about an operation that happened in another synced
+wallet **before** a sync over the sync server happens. An example of this is a
+deposit operation. When two synced wallets spend the same coin on something,
+one of them will receive an error from the exchange that proves the coin has
+been spent on something else. The wallet will add a "ghost entry" for such an
+event, in order to be able to show a consistent history (i.e. all numbers
+adding up) to the user.
+
+When the two wallets sync later, the ghost entry is replaced by the actual
+purchase entity from the wallet that initiated the spending.
+
+Ghost entities are not added to the sync state.
+
+
+Multiple sync servers
+---------------------
+
+When a wallet is connected to multiple sync servers, it automatically
+propagates changes it received from one sync server to the others. Local
+changes made by the wallet are propagated to all sync servers. The goal of
+this is to make the state of the sync servers converge.
+
+The different sync servers one wallet is enrolled with do not necessarily
+have the same set of other wallet enrolled. Each sync server has a separate Lamport clock
+and contains a separate CRDT.
+
+Backup user flow
+================
+
+.. graphviz::
+
+ digraph G {
+ nodesep=0.5;
+ withdrawal [
+ label = "First\nWithdrawal";
+ shape = oval;
+ ];
+ has_backup [
+ label = "Has backup\nconfigured?";
+ shape = diamond;
+ ];
+ app_settings [
+ label = "App\nSettings";
+ shape = rect;
+ ];
+ backup_onboarding [
+ label = "Backup\nOnboarding";
+ shape = rect;
+ ];
+ backup_settings [
+ label = "Backup Settings\n\n* time of last backup\n* current service";
+ shape = rect;
+ ];
+ choose_backup_service [
+ label = "Choose\nBackup Service";
+ shape = rect;
+ ];
+ tos_accepted [
+ label = "Current ToS\naccepted?";
+ shape = diamond;
+ ];
+ tos [
+ label = "ToS";
+ shape = rect;
+ ];
+ payment_required [
+ label = "Payment\nrequired?";
+ shape = diamond;
+ ];
+ payment_confirmation [
+ label = "Payment\nConfirmation";
+ shape = rect;
+ ];
+ backup_secret [
+ label = "Backup Secret\n\nStore or write down!";
+ shape = rect;
+ ];
+
+ withdrawal -> has_backup;
+ has_backup -> backup_onboarding [label="No"];
+ backup_onboarding -> backup_settings;
+ app_settings -> backup_settings;
+ backup_settings -> backup_settings [label="Disable Backup"];
+ backup_settings:w -> backup_settings:w [label="Sync now"];
+ backup_settings -> choose_backup_service;
+ choose_backup_service -> tos_accepted [label="Select Service"];
+ tos_accepted -> tos [label="No"];
+ tos_accepted -> payment_required [label="Yes"];
+ choose_backup_service:w -> choose_backup_service [label="Remove current service"];
+ choose_backup_service:n -> choose_backup_service:n [headlabel="Add new service", labeldistance=3.5];
+ tos -> payment_required [label="Accept"];
+ payment_required -> payment_confirmation [label="Yes"];
+ payment_confirmation -> backup_secret [label="Paid"];
+ backup_secret -> backup_settings [dir=both, label="Stored"];
+ payment_required:s -> backup_secret:w [label="No"];
+
+ { rank=same; has_backup; backup_onboarding; }
+ { rank=same; withdrawal; app_settings; }
+ { rank=same; tos_accepted; tos; }
+ { rank=same; payment_required; payment_confirmation; }
+ }
+
+Backup Settings Screen
+----------------------
+
+* **Backup my wallet** [on/off]
+* **Backup services**
+ No service active
+ (shows time of last backup per service)
+* **Show backup secret**
+ You need this secret to restore from backup
+* option to sync/backup now (hidden in action bar overflow menu)
+
+Choose Backup Service Screen
+----------------------------
+This screen can be reached by pressing the **Backup services** setting
+in the Backup Settings Screen.
+It lists the currently active service and other services that can be used.
+The user has the option to add new services to the list.
+
+A backup service has
+
+* a name
+* a base URL
+* a fee per year in an explicit currency
+
+Clicking an active service shows the above service information as well as:
+
+* the service secret that is required to restore from backup
+* last payment date and next scheduled payment date
+* option to deactivate the backup service
+
+Clicking an inactive service allows the user to use the backup service
+(after accepting ToS and making the payment).
+
+Terms of Service Screen
+-----------------------
+This screen always appears when a backup provider is selected
+and the user did not yet accept the current version of its terms of service.
+
+It shows the terms of service text and an accept checkbox,
+as well as the usual back button.
+
+Payment Confirmation Screen
+---------------------------
+This is the same screen that the user sees when doing other purchases.
+The only difference is that after successful payment,
+the user will be shown the service secret instead of the transaction list.
+
+Backup Secret Screen
+--------------------
+After setting up a backup service,
+the user needs to securely store the secret needed to restore from backup.
+The secret will be shown as a Taler URI in plain text.
+This has the form: ``taler://sync/$SYNC-DOMAIN/$SYNC-PATH#$PRIVATE-KEY``
+Additionally, the URI will be encoded as a QRcode.
+Depending on the platform, there should be an option to print or export (PDF) the secret.
+
+Backup Onboarding
+-----------------
+If no backup service was selected when the user makes the first withdrawal,
+an onboarding screen will be shown that takes the user to the backup configuration screen.
+
+ Don't loose your money, use a backup service!
+
+ Your wallet comes with a list of backup services
+ that can store an encrypted copy of your wallet.
+ Use one to keep your money safe!
+
+ [Set backup up now]
+
+References
+==========
+
+* Shapiro, M., PreguiƧa, N., Baquero, C., & Zawirski, M. (2011). A
+ comprehensive study of convergent and commutative replicated data types. [`PDF <https://hal.inria.fr/inria-00555588/document>`__]
+
+Discussion / Q&A
+================
+
+* Why is backup/sync not split into two services / use-cases?
+
+ * For privacy reasons, we can't use some interactive sync service. Thus we
+ use the backup blob as a CRDT that also synchronization for us.
+
+* Do we need to handle backup/sync state becoming very large e.g. by many transactions
+ and embedded product images potentially exceeding service quota?
+
+* Do we synchronize the list of other backup enrollments? How
+ do we handle distributing the different private keys for them?
+
+ * If we automatically sync the sync enrollments and the old sync account
+ is compromised, the new sync account would automatically be compromised as well!
+
+ * If every wallet had its own sync key pair, we could select which existing wallets
+ to roll over as well.
+
+* How do we handle a synced wallet that becomes malicious deleting all coins or purchased products?
+
+ * This needs to balance the genuine need to permanently delete data.
+
+ * Should the sync server allow to fetch previous versions of the sync blob?
+ (If not, how to provide backup functionality?)
+
+ * Should the individual wallets keep tombstones (i.e. entities just marked as deleted)
+ around for some time, or should they delete and "sanitize" (delete data not needed for the CRDT)
+ tombstones as soon as possible?
+
+* How do we make it easy to remove compromised devices from the sync group
+ and prevent them from getting access to future funds and transactions?
+
+ * We need to remove all sync connections on all connected devices
+ and then individually (and manually) add all devices to the new backup account.
+
+ * If we encrypted the key with each wallet's private sync key,
+ we could choose which wallets we want to migrate to the new sync account.
+
+ * Can we then roll-over wallets to the new account automatically
+ or does it have to be manually on each device to prevent an attacker to roll us over?
+
+* How are wallets identified for backup/sync?
+
+ * UUID / EdDSA pub and nick name? When nickname clashes,
+ some number is added based on lexical sort of the random id ("phone#1", "phone#2").
+
+* How do we explain users that it can take days for wallet state to synchronize to all devices?
+
+* How are people supposed to securely store their backup account key(s)?
+
+ * There can be an option to print/export the QR code
+ * They can manually write down the taler:// Uri containing the key.
+ * Maybe encode the key in a different format such as
+ `BIP39 <https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki>`__?
+
+* Do we have a passphrase for our backup account key(s)?
+
+ * ???