Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lwk_wollet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Add the `electrum_oidc` feature: `TokenProvider::Blockstream` support for `ElectrumClient` (automatic OAuth2 token fetch, plus invalidate and retry once when the server denies a call with an authentication error). Not available on wasm.
* `Wollet::assets_owned()` returns all assets ever owned instead of only unspent ones.
* `Contract` no longer contains public fields. To build a `Contract` for issuance, use `Contract::builder`.
* Esplora client: address history requests within a scan batch run concurrently, honoring `EsploraClientBuilder::concurrency` (default 1, so behavior is unchanged unless opted in).

## 0.18.0

Expand Down
17 changes: 11 additions & 6 deletions lwk_wollet/src/clients/asyncr/esplora.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use futures::lock::Mutex;
#[cfg(not(target_arch = "wasm32"))]
use tokio::sync::Mutex;

use futures::stream::{iter, StreamExt};
use futures::stream::{iter, StreamExt, TryStreamExt};
use reqwest::{Response, StatusCode};
use serde::Deserialize;
use std::sync::atomic::AtomicUsize;
Expand Down Expand Up @@ -217,11 +217,16 @@ impl EsploraClient {
&self,
addresses: &[Address],
) -> Result<Vec<Vec<History>>, Error> {
let mut result = vec![];
for address in addresses.iter() {
result.push(self.get_address_history(address).await?);
}
Ok(result)
// `buffered` (not `buffer_unordered`): callers map results back to
// derivation indices positionally (see `get_history`).
// Futures are created eagerly (inert until polled): an `&Address`-
// borrowing closure in the stream hits rust-lang/rust#89976 when
// async_trait consumers (e.g. lwk_boltz) need the future to be `Send`.
let futures: Vec<_> = addresses
.iter()
.map(|address| self.get_address_history(address))
.collect();
iter(futures).buffered(self.concurrency).try_collect().await
}

/// Fetch an address' unconfirmed transactions plus its full confirmed history.
Expand Down
6 changes: 5 additions & 1 deletion lwk_wollet/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,11 @@ async fn test_esplora_address_history_paging() {
first_page.len()
);

let mut client = clients::asyncr::EsploraClient::new(network, &url);
// concurrency(4) also exercises the ordered concurrent address walk.
let mut client = clients::asyncr::EsploraClientBuilder::new(&url, network)
.concurrency(4)
.build()
.unwrap();
for _ in 0..50 {
if let Some(update) = client.full_scan(&wollet).await.unwrap() {
wollet.apply_update(update).unwrap();
Expand Down
Loading