photon-sdk / photon-lib

A high level library for building bitcoin wallets with react native
https://docs.photonsdk.org
MIT License
53 stars 12 forks source link

Locking/safe sync of encrypted LDK channel state in iCloud/GDrive #38

Closed tanx closed 1 year ago

tanx commented 2 years ago

This is a draft PR to get feedback on syncing LDK channel state via iCloud/GDrive in a safe manner. Here's an overview of my thought process. Feedback welcome, as I am not entirely sure what I'm doing here is completely safe for all scenarios. I do believe however it is not possible to provide 100% safe/locking sync of channel state between two LDK nodes as each has its own state machine, which may make changes to local channel state before it can be detected that another device has initiated restore of channel state in its local LDK node from cloud storage. But here goes...

Basically a mutex is set in iCloud key/value store using a unique device ID so that only one device is allowed to read/write channel state at a time. In addition a mutex is set within the app to ensure thread safe access to the cloudstore from that device. When I open the app on a new device, I am asked if I want to “login” and the device ID of the new device is set as mutex to iCloud. Now only the new device can read/write to the cloudstore.

The only window of risk is really the latency time until the device id syncs to iCloud. But I’m assuming users aren't changing phones back and forth within seconds.

This way we can map channel state sync onto photon’s existing iCloud/GDrive storage backend. We also compare the backup timestamps before persisting to ensure an old channel state never overwrites a newer state. If I understand correctly, this would be in line with what Matt suggested with sequence numbers.

What’s still left is to stop LDK on Device A and prevent that device from starting LDK with old state when Device B takes control. That can be detected using the iCloudStoreDidChangeRemotely event, which is exposed in the api to wallets. In case the wallet is open on both devices at once, Device A can stop LDK and "logout" of the UI.

Granted it’s not a seemless multidevice UX, but it’s good enough for my user archetype that basically only uses a wallet on one device at a time. And I would personally prefer control of backups in my iCloud account rather than fully rely on a wallet vendor.

I also want to to raise the question if it is actually possible to fully mitigate the “risk window” even with an ACID compliant db backend. Because the LDK node on Device A could always make a change to channels locally until it is notified that Device B has taken control. If this is true, I actually see no advantage of using a custom ACID compliant backend over iCloud. There would only be the downside of having to trust the wallet vendor's server for channel storage. But please let me know where I am wrong in my thought process. Thanks :)

tanx commented 1 year ago

Thanks for the review @xsats and @ConorOkus 🙏