bark: Add lock_manager for named cross-process locks

This MR adds a LockManager to bark which ensures that two tasks/process can't race on the same resource.

A key breaking change is that Wallet::create now requires the developer to specify a LockingManager. This PR provides a reasonable default for each platform. Note, that we need this on web to ensure that multiple browser tabs cannot race against eachother.

The LockManager can be used as follow

let lock_manager = bark::lock_manager::MemoryLockManager::new();
// Wait for the lock to become available on round-id 1 for wallet with fingerprint 00000000


let guard_1 = lock_manager.lock("0000000.round.1", std::time::Duration::MAX).await;
let guard_2 = lock_manager.try_lock("000000.round.2").expect("Can grab the round");

A LockManager comes with an enforcement scope and a different scope might be picked depending on the deployment. The LockManager::platform_default should provide a reasonable choice on each platform.

The current barkd approach is to only allow to open a single wallet at a time. If multiple processes want to open the same wallet an error will occur. This behavior is used for android, ios, linux, windows and macOS. I opted for this behavior because it is the most fool proof. We warn the user early if something dangerous happens. It doesn't come with footguns such as notifications not firing because another process triggered them.

For web we implemented a WebLockManager which uses web-locks under the hood. This is required because a wallet will be opened in each tab. In this case the enforcement corresponds to the browsers origin.

In this MR I did not take the following actions. I propose to keep them as a follow-up

  • Enforce that we open the wallet always using the same LockManager. The dev is responsible for this
  • Implement the LockManager on all flows such as lightning receive, lightning pay, ark send, etc..
  • Provide LockManagers that support multi-process
Edited by Erik De Smedt

Merge request reports

Loading