Skip to content

Commit 79afac4

Browse files
committed
[esplora] Support proxies in EsploraBlockchain
1 parent 721748e commit 79afac4

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [Unreleased]
88

99
- Added `flush` method to the `Database` trait to explicitly flush to disk latest changes on the db.
10+
- Add support for proxies in `EsploraBlockchain`
1011

1112
## [v0.10.0] - [v0.9.0]
1213

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ rpc = ["core-rpc"]
7070
async-interface = ["async-trait"]
7171
electrum = ["electrum-client"]
7272
# MUST ALSO USE `--no-default-features`.
73-
use-esplora-reqwest = ["async-interface", "esplora", "reqwest", "futures"]
74-
use-esplora-ureq = ["esplora", "ureq"]
73+
use-esplora-reqwest = ["async-interface", "esplora", "reqwest", "reqwest/socks", "futures"]
74+
use-esplora-ureq = ["esplora", "ureq", "ureq/socks"]
7575
# Typical configurations will not need to use `esplora` feature directly.
7676
esplora = []
7777

src/blockchain/esplora/reqwest.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,15 @@ 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+
pub proxy: Option<String>,
336345
/// Number of parallel requests sent to the esplora service (default: 4)
337346
pub concurrency: Option<u8>,
338347
/// Stop searching addresses for transactions after finding an unused gap of this length.
@@ -343,10 +352,18 @@ impl ConfigurableBlockchain for EsploraBlockchain {
343352
type Config = EsploraBlockchainConfig;
344353

345354
fn from_config(config: &Self::Config) -> Result<Self, Error> {
355+
let map_e = |e: reqwest::Error| Error::Esplora(Box::new(e.into()));
356+
346357
let mut blockchain = EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap);
347358
if let Some(concurrency) = config.concurrency {
348359
blockchain.url_client.concurrency = concurrency;
349-
};
360+
}
361+
if let Some(proxy) = &config.proxy {
362+
blockchain.url_client.client = Client::builder()
363+
.proxy(reqwest::Proxy::all(proxy).map_err(map_e)?)
364+
.build()
365+
.map_err(map_e)?;
366+
}
350367
Ok(blockchain)
351368
}
352369
}

src/blockchain/esplora/ureq.rs

+23-6
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,15 @@ 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+
pub proxy: Option<String>,
361370
/// Socket read timeout.
362371
pub timeout_read: u64,
363372
/// Socket write timeout.
@@ -370,10 +379,18 @@ impl ConfigurableBlockchain for EsploraBlockchain {
370379
type Config = EsploraBlockchainConfig;
371380

372381
fn from_config(config: &Self::Config) -> Result<Self, Error> {
373-
let agent: Agent = ureq::AgentBuilder::new()
382+
let mut agent_builder = ureq::AgentBuilder::new()
374383
.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))
384+
.timeout_write(Duration::from_secs(config.timeout_write));
385+
386+
if let Some(proxy) = &config.proxy {
387+
agent_builder = agent_builder
388+
.proxy(Proxy::new(proxy).map_err(|e| Error::Esplora(Box::new(e.into())))?);
389+
}
390+
391+
Ok(
392+
EsploraBlockchain::new(config.base_url.as_str(), config.stop_gap)
393+
.with_agent(agent_builder.build()),
394+
)
378395
}
379396
}

0 commit comments

Comments
 (0)