Skip to content

Commit 3fe2380

Browse files
committed
[esplora] Support proxies in EsploraBlockchain
1 parent a685b22 commit 3fe2380

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
## [v0.11.0] - [v0.10.0]
1010

1111
- Added `flush` method to the `Database` trait to explicitly flush to disk latest changes on the db.
12+
- Add support for proxies in `EsploraBlockchain`
1213

1314
## [v0.10.0] - [v0.9.0]
1415

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ rpc = ["core-rpc"]
7777
async-interface = ["async-trait"]
7878
electrum = ["electrum-client"]
7979
# MUST ALSO USE `--no-default-features`.
80-
use-esplora-reqwest = ["esplora", "reqwest", "futures"]
81-
use-esplora-ureq = ["esplora", "ureq"]
80+
use-esplora-reqwest = ["esplora", "reqwest", "reqwest/socks", "futures"]
81+
use-esplora-ureq = ["esplora", "ureq", "ureq/socks"]
8282
# Typical configurations will not need to use `esplora` feature directly.
8383
esplora = []
8484

src/blockchain/esplora/reqwest.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,17 @@ pub struct EsploraBlockchainConfig {
333333
///
334334
/// eg. `https://blockstream.info/api/`
335335
pub base_url: String,
336+
/// Optional URL of the proxy to use to make requests to the Esplora server
337+
///
338+
/// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
339+
///
340+
/// Note that the format of this value and the supported protocols change slightly between the
341+
/// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
342+
/// details check with the documentation of the two crates. Both of them are compiled with
343+
/// the `socks` feature enabled.
344+
///
345+
/// The proxy is ignored when targeting `wasm32`.
346+
pub proxy: Option<String>,
336347
/// Number of parallel requests sent to the esplora service (default: 4)
337348
pub concurrency: Option<u8>,
338349
/// Stop searching addresses for transactions after finding an unused gap of this length.
@@ -343,10 +354,19 @@ impl ConfigurableBlockchain for EsploraBlockchain {
343354
type Config = EsploraBlockchainConfig;
344355

345356
fn from_config(config: &Self::Config) -> Result<Self, Error> {
357+
let map_e = |e: reqwest::Error| Error::Esplora(Box::new(e.into()));
358+
346359
let mut blockchain = EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap);
347360
if let Some(concurrency) = config.concurrency {
348361
blockchain.url_client.concurrency = concurrency;
349-
};
362+
}
363+
#[cfg(not(target_arch = "wasm32"))]
364+
if let Some(proxy) = &config.proxy {
365+
blockchain.url_client.client = Client::builder()
366+
.proxy(reqwest::Proxy::all(proxy).map_err(map_e)?)
367+
.build()
368+
.map_err(map_e)?;
369+
}
350370
Ok(blockchain)
351371
}
352372
}

src/blockchain/esplora/ureq.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::time::Duration;
1919
#[allow(unused_imports)]
2020
use log::{debug, error, info, trace};
2121

22-
use ureq::{Agent, Response};
22+
use ureq::{Agent, Proxy, Response};
2323

2424
use bitcoin::consensus::{deserialize, serialize};
2525
use bitcoin::hashes::hex::{FromHex, ToHex};
@@ -59,7 +59,7 @@ impl std::convert::From<UrlClient> for EsploraBlockchain {
5959
}
6060

6161
impl EsploraBlockchain {
62-
/// Create a new instance of the client from a base URL and `stop_gap`.
62+
/// Create a new instance of the client from a base URL and the `stop_gap`.
6363
pub fn new(base_url: &str, stop_gap: usize) -> Self {
6464
EsploraBlockchain {
6565
url_client: UrlClient {
@@ -358,6 +358,17 @@ impl ElectrumLikeSync for UrlClient {
358358
pub struct EsploraBlockchainConfig {
359359
/// Base URL of the esplora service eg. `https://blockstream.info/api/`
360360
pub base_url: String,
361+
/// Optional URL of the proxy to use to make requests to the Esplora server
362+
///
363+
/// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
364+
///
365+
/// Note that the format of this value and the supported protocols change slightly between the
366+
/// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
367+
/// details check with the documentation of the two crates. Both of them are compiled with
368+
/// the `socks` feature enabled.
369+
///
370+
/// The proxy is ignored when targeting `wasm32`.
371+
pub proxy: Option<String>,
361372
/// Socket read timeout.
362373
pub timeout_read: u64,
363374
/// Socket write timeout.
@@ -370,10 +381,18 @@ impl ConfigurableBlockchain for EsploraBlockchain {
370381
type Config = EsploraBlockchainConfig;
371382

372383
fn from_config(config: &Self::Config) -> Result<Self, Error> {
373-
let agent: Agent = ureq::AgentBuilder::new()
384+
let mut agent_builder = ureq::AgentBuilder::new()
374385
.timeout_read(Duration::from_secs(config.timeout_read))
375-
.timeout_write(Duration::from_secs(config.timeout_write))
376-
.build();
377-
Ok(EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap).with_agent(agent))
386+
.timeout_write(Duration::from_secs(config.timeout_write));
387+
388+
if let Some(proxy) = &config.proxy {
389+
agent_builder = agent_builder
390+
.proxy(Proxy::new(proxy).map_err(|e| Error::Esplora(Box::new(e.into())))?);
391+
}
392+
393+
Ok(
394+
EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap)
395+
.with_agent(agent_builder.build()),
396+
)
378397
}
379398
}

0 commit comments

Comments
 (0)