taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

005-wallet-backup-sync.rst (12146B)


      1 XX 05: Wallet Backup and Sync
      2 #############################
      3 
      4 .. warning::
      5 
      6   This document is deprecated.  We have decided to first
      7   implement backup, and tackle sync later.
      8   The multi-device sync described in this document would lead
      9   to a bad/unexpected user experience that does not justify the
     10   conceptual / implementation complexity.
     11 
     12 Summary
     13 =======
     14 
     15 This document discusses considerations for backup and synchronization of wallets.
     16 
     17 
     18 Requirements
     19 ============
     20 
     21 * Backup and sync must not require any synchronous communication between the
     22   wallets
     23 * Wallets operating (payments/withdrawals/...) for longer periods of time without
     24   synchronizing should be handled well
     25 * Conflicts should be resolved automatically in pretty much all cases
     26 * One wallet can be enrolled with multiple sync servers, and a wallet can
     27   join
     28 * Other wallets connected to the sync server are trusted.
     29 
     30 Proposed Solution
     31 =================
     32 
     33 The blob stored on the backup/sync server is a compressed and encrypted JSON file.
     34 
     35 The various entity types managed by the wallet are modeled LWW-Sets (Last Write
     36 Wins Set CRDT).  Timestamps for inserts/deletes are are Lamport timestamps.  Concurrent, conflicting insert/delete
     37 operations are resolved in favor of "delete".
     38 
     39 The managed entities are:
     40 
     41 * set of exchanges with the data from /keys, /wire
     42 * set of directly trusted exchange public keys
     43 * set of trusted auditors for currencies
     44 * set of reserves together with reserve history
     45 * set of accepted bank withdrawal operations
     46 * set of coins together with coin history and blinding secret (both for normal withdrawal and refresh)
     47   and coin source info (refresh operation, reward, reserve)
     48 * set of purchases (contract terms, applied refunds, ...)
     49 * assignment of coins to their "primary wallet"
     50 
     51 (Some of these might be further split up to allow more efficient updates.)
     52 
     53 Entities that are **not** synchronized are:
     54 
     55 * purchases before the corresponding order has been claimed
     56 * withdrawal operations before they have been accepted by the user
     57 
     58 Entities that **could** be synchronized (to be decided):
     59 
     60 * private keys of other sync accounts
     61 * coin planchets
     62 * rewards before the corresponding coins have been withdrawn
     63 * refresh sessions (not only the "meta data" about the operation,
     64   but everything)
     65 
     66 
     67 Garbage collection
     68 ------------------
     69 
     70 There are two types of garbage collection involved:
     71 
     72 1. CRDT tombstones / other administrative data in the sync blob.  These can be deleted
     73    after we're sure all wallets enrolled in the sync server have a Lamport timestamp
     74    larger than the timestamp of the tombstone.  Wallets include their own Lamport timestamp
     75    in the sync blob:
     76 
     77    .. code:: javascript
     78 
     79      {
     80        clocks: {
     81          my_desktop_wallet: 5,
     82          my_phone_wallet: 3
     83        },
     84        ...
     85      }
     86 
     87    All tombstones / overwritten set elements with a timestamp smaller than the
     88    smallest clock value can be deleted.
     89 
     90 2. Normal wallet GC.  The deletion operations resulting from the wallet garbage
     91    collection (i.g. deleting legally expired denomination keys, coins, exchange
     92    signing keys, ...) are propagated to the respective CRDT set in the sync
     93    blob.
     94 
     95 
     96 Ghost Entities
     97 --------------
     98 
     99 Sometimes a wallet can learn about an operation that happened in another synced
    100 wallet **before** a sync over the sync server happens.  An example of this is a
    101 deposit operation.  When two synced wallets spend the same coin on something,
    102 one of them will receive an error from the exchange that proves the coin has
    103 been spent on something else.  The wallet will add a "ghost entry" for such an
    104 event, in order to be able to show a consistent history (i.e. all numbers
    105 adding up) to the user.
    106 
    107 When the two wallets sync later, the ghost entry is replaced by the actual
    108 purchase entity from the wallet that initiated the spending.
    109 
    110 Ghost entities are not added to the sync state.
    111 
    112 
    113 Multiple sync servers
    114 ---------------------
    115 
    116 When a wallet is connected to multiple sync servers, it automatically
    117 propagates changes it received from one sync server to the others.  Local
    118 changes made by the wallet are propagated to all sync servers.  The goal of
    119 this is to make the state of the sync servers converge.
    120 
    121 The different sync servers one wallet is enrolled with do not necessarily
    122 have the same set of other wallet enrolled.  Each sync server has a separate Lamport clock
    123 and contains a separate CRDT.
    124 
    125 Backup user flow
    126 ================
    127 
    128 .. graphviz::
    129 
    130    digraph G {
    131        nodesep=0.5;
    132        withdrawal [
    133            label = "First\nWithdrawal";
    134            shape = oval;
    135        ];
    136        has_backup [
    137            label = "Has backup\nconfigured?";
    138            shape = diamond;
    139        ];
    140        app_settings [
    141            label = "App\nSettings";
    142            shape = rect;
    143        ];
    144        backup_onboarding [
    145            label = "Backup\nOnboarding";
    146            shape = rect;
    147        ];
    148        backup_settings [
    149            label = "Backup Settings\n\n* time of last backup\n* current service";
    150            shape = rect;
    151        ];
    152        choose_backup_service [
    153            label = "Choose\nBackup Service";
    154            shape = rect;
    155        ];
    156        tos_accepted [
    157            label = "Current ToS\naccepted?";
    158            shape = diamond;
    159        ];
    160        tos [
    161            label = "ToS";
    162            shape = rect;
    163        ];
    164        payment_required [
    165            label = "Payment\nrequired?";
    166            shape = diamond;
    167        ];
    168        payment_confirmation [
    169            label = "Payment\nConfirmation";
    170            shape = rect;
    171        ];
    172        backup_secret [
    173            label = "Backup Secret\n\nStore or write down!";
    174            shape = rect;
    175        ];
    176 
    177        withdrawal -> has_backup;
    178        has_backup -> backup_onboarding [label="No"];
    179        backup_onboarding -> backup_settings;
    180        app_settings -> backup_settings;
    181        backup_settings -> backup_settings [label="Disable Backup"];
    182        backup_settings:w -> backup_settings:w [label="Sync now"];
    183        backup_settings -> choose_backup_service;
    184        choose_backup_service -> tos_accepted [label="Select Service"];
    185        tos_accepted -> tos [label="No"];
    186        tos_accepted -> payment_required [label="Yes"];
    187        choose_backup_service:w -> choose_backup_service [label="Remove current service"];
    188        choose_backup_service:n -> choose_backup_service:n [headlabel="Add new service", labeldistance=3.5];
    189        tos -> payment_required [label="Accept"];
    190        payment_required -> payment_confirmation [label="Yes"];
    191        payment_confirmation -> backup_secret [label="Paid"];
    192        backup_secret -> backup_settings [dir=both, label="Stored"];
    193        payment_required:s -> backup_secret:w [label="No"];
    194 
    195        { rank=same; has_backup; backup_onboarding; }
    196        { rank=same; withdrawal; app_settings; }
    197        { rank=same; tos_accepted; tos; }
    198        { rank=same; payment_required; payment_confirmation; }
    199    }
    200 
    201 Backup Settings Screen
    202 ----------------------
    203 
    204 * **Backup my wallet** [on/off]
    205 * **Backup services**
    206   No service active
    207   (shows time of last backup per service)
    208 * **Show backup secret**
    209   You need this secret to restore from backup
    210 * option to sync/backup now (hidden in action bar overflow menu)
    211 
    212 Choose Backup Service Screen
    213 ----------------------------
    214 This screen can be reached by pressing the **Backup services** setting
    215 in the Backup Settings Screen.
    216 It lists the currently active service and other services that can be used.
    217 The user has the option to add new services to the list.
    218 
    219 A backup service has
    220 
    221 * a name
    222 * a base URL
    223 * a fee per year in an explicit currency
    224 
    225 Clicking an active service shows the above service information as well as:
    226 
    227 * the service secret that is required to restore from backup
    228 * last payment date and next scheduled payment date
    229 * option to deactivate the backup service
    230 
    231 Clicking an inactive service allows the user to use the backup service
    232 (after accepting ToS and making the payment).
    233 
    234 Terms of Service Screen
    235 -----------------------
    236 This screen always appears when a backup provider is selected
    237 and the user did not yet accept the current version of its terms of service.
    238 
    239 It shows the terms of service text and an accept checkbox,
    240 as well as the usual back button.
    241 
    242 Payment Confirmation Screen
    243 ---------------------------
    244 This is the same screen that the user sees when doing other purchases.
    245 The only difference is that after successful payment,
    246 the user will be shown the service secret instead of the transaction list.
    247 
    248 Backup Secret Screen
    249 --------------------
    250 After setting up a backup service,
    251 the user needs to securely store the secret needed to restore from backup.
    252 The secret will be shown as a Taler URI in plain text.
    253 This has the form: ``taler://sync/$SYNC-DOMAIN/$SYNC-PATH#$PRIVATE-KEY``
    254 Additionally, the URI will be encoded as a QRcode.
    255 Depending on the platform, there should be an option to print or export (PDF) the secret.
    256 
    257 Backup Onboarding
    258 -----------------
    259 If no backup service was selected when the user makes the first withdrawal,
    260 an onboarding screen will be shown that takes the user to the backup configuration screen.
    261 
    262     Don't loose your money, use a backup service!
    263 
    264     Your wallet comes with a list of backup services
    265     that can store an encrypted copy of your wallet.
    266     Use one to keep your money safe!
    267 
    268     [Set backup up now]
    269 
    270 References
    271 ==========
    272 
    273 * Shapiro, M., PreguiƧa, N., Baquero, C., & Zawirski, M. (2011). A
    274   comprehensive study of convergent and commutative replicated data types. [`PDF <https://hal.inria.fr/inria-00555588/document>`__]
    275 
    276 Discussion / Q&A
    277 ================
    278 
    279 * Why is backup/sync not split into two services / use-cases?
    280 
    281   * For privacy reasons, we can't use some interactive sync service.  Thus we
    282     use the backup blob as a CRDT that also synchronization for us.
    283 
    284 * Do we need to handle backup/sync state becoming very large e.g. by many transactions
    285   and embedded product images potentially exceeding service quota?
    286 
    287 * Do we synchronize the list of other backup enrollments?  How
    288   do we handle distributing the different private keys for them?
    289 
    290   * If we automatically sync the sync enrollments and the old sync account
    291     is compromised, the new sync account would automatically be compromised as well!
    292 
    293   * If every wallet had its own sync key pair, we could select which existing wallets
    294     to roll over as well.
    295 
    296 * How do we handle a synced wallet that becomes malicious deleting all coins or purchased products?
    297 
    298   * This needs to balance the genuine need to permanently delete data.
    299 
    300   * Should the sync server allow to fetch previous versions of the sync blob?
    301     (If not, how to provide backup functionality?)
    302 
    303   * Should the individual wallets keep tombstones (i.e. entities just marked as deleted)
    304     around for some time, or should they delete and "sanitize" (delete data not needed for the CRDT)
    305     tombstones as soon as possible?
    306 
    307 * How do we make it easy to remove compromised devices from the sync group
    308   and prevent them from getting access to future funds and transactions?
    309 
    310   * We need to remove all sync connections on all connected devices
    311     and then individually (and manually) add all devices to the new backup account.
    312 
    313   * If we encrypted the key with each wallet's private sync key,
    314     we could choose which wallets we want to migrate to the new sync account.
    315 
    316   * Can we then roll-over wallets to the new account automatically
    317     or does it have to be manually on each device to prevent an attacker to roll us over?
    318 
    319 * How are wallets identified for backup/sync?
    320 
    321   * UUID / EdDSA pub and nick name?  When nickname clashes,
    322     some number is added based on lexical sort of the random id ("phone#1", "phone#2").
    323 
    324 * How do we explain users that it can take days for wallet state to synchronize to all devices?
    325 
    326 * How are people supposed to securely store their backup account key(s)?
    327 
    328   * There can be an option to print/export the QR code
    329   * They can manually write down the taler:// Uri containing the key.
    330   * Maybe encode the key in a different format such as
    331     `BIP39 <https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki>`__?
    332 
    333 * Do we have a passphrase for our backup account key(s)?
    334 
    335   * ???