An actor that manages the `bdk::Wallet` resource. It allows us to use
the wallet whilst the inevitably expensive on-chain sync is happening
in the background.
We would like to use the async version of `EsploraBlockchain`, but
bitcoindevkit/bdk#165 is still an issue.
The only hacky bit stems from the fact that we still have to implement
certain non-async foreign traits and to access any `bdk::Wallet`
resource we now have to go via async methods, since the actor is
async.
To do so, at some point we have to call an async function "from a sync
context". The natural way to do so (for me) would be to use
`runtime.block_on`, which schedules an async task and waits for it to
resolve, blocking the thread. *But*, these non-async foreign trait
methods are actually called elswhere in _async_ contexts. This leads
to `runtime.block_on` panicking because `tokio` is trying to prevent
us from blocking a thread in an async context. This is analogous to us
misusing async and doing an expensive CPU-bound computation in an
async context, but here `tokio` is able to "aid" us since `block_on`
is provided by `tokio`.
The solution is to use the following pattern:
```rust
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
// async code
})
});
```
From the documentation of `block_in_place`, we are able to run "the
provided blocking function on the current thread without blocking the
executor". We therefore avoid the panic, as we no longer block the
executor when calling `block_on`.
This has one final side-effect, which is that all `ln-dlc-node` async
tests now need to go back to using the `multi_thread` flavour.
`block_in_place` works by moving all scheduled tasks to a different
worker thread and without `multi_thread` there is only one worker
thread, so it just panics.
Co-authored-by: Mariusz Klochowicz <[email protected]>