Skip to content

Commit 9d80f95

Browse files
Distribute required-on-Tails SOCKS5 proxy everywhere a TCP request is made
1 parent 27bb7ff commit 9d80f95

File tree

14 files changed

+160
-35
lines changed

14 files changed

+160
-35
lines changed

electrum-pool/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use backoff::{Error as BackoffError, ExponentialBackoff};
2-
use bdk_electrum::electrum_client::{Client, ConfigBuilder, ElectrumApi, Error};
2+
use bdk_electrum::electrum_client::{Client, ConfigBuilder, ElectrumApi, Error, Socks5Config};
33
use bdk_electrum::BdkElectrumClient;
44
use bitcoin::Transaction;
55
use futures::future::join_all;
66
use once_cell::sync::OnceCell;
7+
use std::borrow::Cow;
78
use std::sync::atomic::{AtomicUsize, Ordering};
89
use std::sync::{Arc, RwLock};
910
use std::time::Duration;
@@ -546,13 +547,16 @@ pub struct ElectrumBalancerConfig {
546547
pub request_timeout: u8,
547548
/// Minimum number of retry attempts across all nodes
548549
pub min_retries: usize,
550+
/// Address of SOCKS5 proxy in `127.0.0.1:9050` format
551+
pub socks5: Option<Cow<'static, str>>,
549552
}
550553

551554
impl Default for ElectrumBalancerConfig {
552555
fn default() -> Self {
553556
Self {
554557
request_timeout: 15,
555558
min_retries: 15,
559+
socks5: None,
556560
}
557561
}
558562
}
@@ -573,6 +577,7 @@ impl ElectrumClientFactory<BdkElectrumClient<Client>> for BdkElectrumClientFacto
573577
) -> Result<Arc<BdkElectrumClient<Client>>, Error> {
574578
let client_config = ConfigBuilder::new()
575579
.timeout(Some(config.request_timeout))
580+
.socks5(config.socks5.as_ref().map(Socks5Config::new))
576581
.retry(0)
577582
.build();
578583

@@ -947,6 +952,7 @@ mod tests {
947952
let config = ElectrumBalancerConfig {
948953
request_timeout: 5,
949954
min_retries: 0,
955+
socks5: None,
950956
};
951957

952958
let balancer = ElectrumBalancer::new_with_config_and_factory(urls, config, factory.clone())
@@ -1020,6 +1026,7 @@ mod tests {
10201026
let config = ElectrumBalancerConfig {
10211027
request_timeout: 5,
10221028
min_retries: 1,
1029+
socks5: None,
10231030
};
10241031

10251032
let balancer = ElectrumBalancer::new_with_config_and_factory(urls, config, factory.clone())
@@ -1162,6 +1169,7 @@ mod tests {
11621169
let config = ElectrumBalancerConfig {
11631170
request_timeout: 15,
11641171
min_retries: 7,
1172+
socks5: None,
11651173
};
11661174

11671175
let factory = Arc::new(MockElectrumClientFactory::new());

monero-rpc/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ jsonrpc_client = { version = "0.7", features = ["reqwest"] }
1212
monero = { workspace = true }
1313
monero-epee-bin-serde = "1"
1414
rand = { workspace = true }
15-
reqwest = { workspace = true }
15+
reqwest = { workspace = true, features = ["socks"] }
1616
rust_decimal = { workspace = true }
1717
serde = { workspace = true }
1818
serde_json = { workspace = true }
19+
swap-tor = { path = "../swap-tor" }
1920
tracing = { workspace = true }
2021

2122
[dev-dependencies]

monero-rpc/src/monerod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ impl Client {
3030
}
3131

3232
fn new(host: String, port: u16) -> Result<Self> {
33+
let mut client = reqwest::Client::builder().connection_verbose(true);
34+
if let Some(proxy) = swap_tor::TOR_ENVIRONMENT.and_then(|ste| ste.reqwest_proxy()) {
35+
client = client.proxy(reqwest::Proxy::all(proxy)?);
36+
}
3337
Ok(Self {
34-
inner: reqwest::ClientBuilder::new()
35-
.connection_verbose(true)
36-
.build()?,
38+
inner: client.build()?,
3739
base_url: format!("http://{}:{}/json_rpc", host, port)
3840
.parse()
3941
.context("url is well formed")?,

monero-rpc/src/wallet.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ impl Client {
5858

5959
/// Constructs a monero-wallet-rpc client with `url` endpoint.
6060
pub fn new(url: reqwest::Url) -> Result<Self> {
61+
let mut client = reqwest::Client::builder().connection_verbose(true);
62+
if let Some(proxy) = swap_tor::TOR_ENVIRONMENT.and_then(|ste| ste.reqwest_proxy()) {
63+
client = client.proxy(reqwest::Proxy::all(proxy)?);
64+
}
6165
Ok(Self {
62-
inner: reqwest::ClientBuilder::new()
63-
.connection_verbose(true)
64-
.build()?,
66+
inner: client.build()?,
6567
base_url: url,
6668
})
6769
}

monero-sys/src/lib.rs

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,19 @@ impl WalletHandle {
233233
pub async fn open_or_create(
234234
path: String,
235235
daemon: Daemon,
236+
proxy_address: &str,
236237
network: monero::Network,
237238
background_sync: bool,
238239
) -> anyhow::Result<Self> {
239-
Self::open_or_create_with_password(path, None, daemon, network, background_sync).await
240+
Self::open_or_create_with_password(
241+
path,
242+
None,
243+
daemon,
244+
proxy_address,
245+
network,
246+
background_sync,
247+
)
248+
.await
240249
}
241250

242251
/// Common implementation used by all `open_*` helpers.
@@ -307,10 +316,12 @@ impl WalletHandle {
307316
path: String,
308317
password: impl Into<Option<String>>,
309318
daemon: Daemon,
319+
proxy_address: impl Into<String>,
310320
network: monero::Network,
311321
background_sync: bool,
312322
) -> anyhow::Result<Self> {
313323
let password = password.into();
324+
let proxy_address = proxy_address.into();
314325

315326
Self::open_with(path.clone(), daemon.clone(), move |manager| {
316327
manager.open_or_create_wallet(
@@ -319,6 +330,7 @@ impl WalletHandle {
319330
network,
320331
background_sync,
321332
daemon.clone(),
333+
&proxy_address,
322334
)
323335
})
324336
.await
@@ -334,10 +346,20 @@ impl WalletHandle {
334346
restore_height: u64,
335347
background_sync: bool,
336348
daemon: Daemon,
349+
proxy_address: impl Into<String>,
337350
) -> anyhow::Result<Self> {
351+
let proxy_address = proxy_address.into();
352+
338353
Self::open_with(path.clone(), daemon.clone(), move |manager| {
339354
if manager.wallet_exists(&path) {
340-
manager.open_or_create_wallet(&path, None, network, background_sync, daemon.clone())
355+
manager.open_or_create_wallet(
356+
&path,
357+
None,
358+
network,
359+
background_sync,
360+
daemon.clone(),
361+
&proxy_address,
362+
)
341363
} else {
342364
manager.recover_wallet(
343365
&path,
@@ -347,6 +369,7 @@ impl WalletHandle {
347369
restore_height,
348370
background_sync,
349371
daemon.clone(),
372+
&proxy_address,
350373
)
351374
}
352375
})
@@ -367,7 +390,10 @@ impl WalletHandle {
367390
restore_height: u64,
368391
background_sync: bool,
369392
daemon: Daemon,
393+
proxy_address: impl Into<String>,
370394
) -> anyhow::Result<Self> {
395+
let proxy_address = proxy_address.into();
396+
371397
Self::open_with(path.clone(), daemon.clone(), move |manager| {
372398
manager.open_or_create_wallet_from_keys(
373399
&path,
@@ -379,6 +405,7 @@ impl WalletHandle {
379405
restore_height,
380406
background_sync,
381407
daemon.clone(),
408+
&proxy_address,
382409
)
383410
})
384411
.await
@@ -1112,6 +1139,7 @@ impl WalletManager {
11121139
network: monero::Network,
11131140
background_sync: bool,
11141141
daemon: Daemon,
1142+
proxy_address: &str,
11151143
) -> anyhow::Result<FfiWallet> {
11161144
tracing::debug!(%path, "Opening or creating wallet");
11171145

@@ -1126,6 +1154,7 @@ impl WalletManager {
11261154
network,
11271155
background_sync,
11281156
daemon,
1157+
proxy_address,
11291158
Box::new(TraceListener::new(path.to_string())),
11301159
)
11311160
.context(format!("Failed to open wallet `{}`", &path));
@@ -1158,7 +1187,7 @@ impl WalletManager {
11581187
}
11591188

11601189
let raw_wallet = RawWallet::new(wallet_pointer);
1161-
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon)
1190+
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon, proxy_address)
11621191
.context(format!("Failed to initialize wallet `{}`", &path))?;
11631192

11641193
Ok(wallet)
@@ -1177,6 +1206,7 @@ impl WalletManager {
11771206
restore_height: u64,
11781207
background_sync: bool,
11791208
daemon: Daemon,
1209+
proxy_address: &str,
11801210
) -> Result<FfiWallet> {
11811211
tracing::debug!(%path, "Creating wallet from keys");
11821212

@@ -1190,6 +1220,7 @@ impl WalletManager {
11901220
network,
11911221
background_sync,
11921222
daemon.clone(),
1223+
proxy_address,
11931224
Box::new(TraceListener::new(path.to_string())),
11941225
)
11951226
.context(format!("Failed to open wallet `{}`", &path));
@@ -1242,7 +1273,7 @@ impl WalletManager {
12421273

12431274
let raw_wallet = RawWallet::new(wallet_pointer);
12441275
tracing::debug!(path=%path, "Created wallet from keys, initializing");
1245-
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon)
1276+
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon, proxy_address)
12461277
.context(format!("Failed to initialize wallet `{}` from keys", &path))?;
12471278

12481279
Ok(wallet)
@@ -1259,6 +1290,7 @@ impl WalletManager {
12591290
restore_height: u64,
12601291
background_sync: bool,
12611292
daemon: Daemon,
1293+
proxy_address: &str,
12621294
) -> anyhow::Result<FfiWallet> {
12631295
tracing::debug!(%path, "Recovering wallet from seed");
12641296

@@ -1283,7 +1315,7 @@ impl WalletManager {
12831315
.context("Failed to recover wallet from seed: FFI call failed with exception")?;
12841316

12851317
let raw_wallet = RawWallet::new(wallet_pointer);
1286-
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon)
1318+
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon, proxy_address)
12871319
.context(format!("Failed to initialize wallet `{}` from seed", &path))?;
12881320

12891321
Ok(wallet)
@@ -1313,6 +1345,7 @@ impl WalletManager {
13131345
network_type: monero::Network,
13141346
background_sync: bool,
13151347
daemon: Daemon,
1348+
proxy_address: &str,
13161349
listener: Box<dyn WalletEventListener>,
13171350
) -> anyhow::Result<FfiWallet> {
13181351
tracing::debug!(%path, "Opening wallet");
@@ -1340,7 +1373,7 @@ impl WalletManager {
13401373

13411374
let raw_wallet = RawWallet::new(wallet_pointer);
13421375

1343-
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon)
1376+
let wallet = FfiWallet::new(raw_wallet, background_sync, daemon, proxy_address)
13441377
.context("Failed to initialize re-opened wallet")?;
13451378

13461379
wallet.add_listener(listener);
@@ -1472,7 +1505,12 @@ impl FfiWallet {
14721505
const MAIN_ACCOUNT_INDEX: u32 = 0;
14731506

14741507
/// Create and initialize new wallet from a raw C++ wallet pointer.
1475-
fn new(inner: RawWallet, background_sync: bool, daemon: Daemon) -> anyhow::Result<Self> {
1508+
fn new(
1509+
inner: RawWallet,
1510+
background_sync: bool,
1511+
daemon: Daemon,
1512+
proxy_address: &str,
1513+
) -> anyhow::Result<Self> {
14761514
if inner.inner.is_null() {
14771515
anyhow::bail!("Failed to create wallet: got null pointer");
14781516
}
@@ -1492,7 +1530,7 @@ impl FfiWallet {
14921530
backoff(None, None),
14931531
|| {
14941532
wallet
1495-
.init(&daemon)
1533+
.init(&daemon, proxy_address)
14961534
.context("Failed to initialize wallet")
14971535
.map_err(backoff::Error::transient)
14981536
},
@@ -1571,15 +1609,15 @@ impl FfiWallet {
15711609
}
15721610

15731611
/// Initialize the wallet and download initial values from the remote node.
1574-
/// Does not actuallyt sync the wallet, use any of the refresh methods to do that.
1575-
fn init(&mut self, daemon: &Daemon) -> anyhow::Result<()> {
1612+
/// Does not actually sync the wallet, use any of the refresh methods to do that.
1613+
fn init(&mut self, daemon: &Daemon, proxy_address: &str) -> anyhow::Result<()> {
15761614
let daemon_address = format!("{}:{}", daemon.hostname, daemon.port);
15771615
tracing::debug!(%daemon_address, ssl=%daemon.ssl, "Initializing wallet");
15781616

15791617
let_cxx_string!(daemon_address = daemon_address);
15801618
let_cxx_string!(daemon_username = "");
15811619
let_cxx_string!(daemon_password = "");
1582-
let_cxx_string!(proxy_address = "");
1620+
let_cxx_string!(proxy_address = proxy_address);
15831621

15841622
let raw_wallet = &mut self.inner;
15851623

src-gui/src/renderer/components/modal/updater/UpdaterDialog.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ import {
1313
Link,
1414
} from "@mui/material";
1515
import SystemUpdateIcon from "@mui/icons-material/SystemUpdate";
16-
import { check, Update, DownloadEvent } from "@tauri-apps/plugin-updater";
16+
import {
17+
check,
18+
CheckOptions,
19+
Update,
20+
DownloadEvent,
21+
} from "@tauri-apps/plugin-updater";
1722
import { useSnackbar } from "notistack";
23+
import { getUpdaterProxy } from "renderer/rpc";
1824
import { relaunch } from "@tauri-apps/plugin-process";
1925

2026
const GITHUB_RELEASES_URL = "https://github.com/eigenwallet/core/releases";
@@ -56,15 +62,16 @@ function LinearProgressWithLabel(
5662
);
5763
}
5864

65+
const proxy = await getUpdaterProxy();
5966
export default function UpdaterDialog() {
6067
const [availableUpdate, setAvailableUpdate] = useState<Update | null>(null);
6168
const [downloadProgress, setDownloadProgress] =
6269
useState<DownloadProgress | null>(null);
6370
const { enqueueSnackbar } = useSnackbar();
6471

6572
useEffect(() => {
66-
// Check for updates when component mounts
67-
check()
73+
// Check, CheckOptions for updates when component mounts
74+
check({ proxy })
6875
.then((updateResponse) => {
6976
console.log("updateResponse", updateResponse);
7077
setAvailableUpdate(updateResponse);

src-gui/src/renderer/rpc.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ export async function getTorForcedExcuse(): Promise<string> {
308308
return await invokeNoArgs<string>("get_tor_forced_excuse");
309309
}
310310

311+
export async function getUpdaterProxy(): Promise<string | null> {
312+
return await invokeNoArgs<string | null>("get_updater_proxy");
313+
}
314+
311315
export async function getLogsOfSwap(
312316
swapId: string,
313317
redact: boolean,

src-tauri/src/commands.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ macro_rules! generate_command_handlers {
7171
change_monero_node,
7272
get_context_status,
7373
get_tor_forced_excuse,
74+
get_updater_proxy,
7475
]
7576
};
7677
}
@@ -205,6 +206,11 @@ pub async fn get_tor_forced_excuse(_: tauri::State<'_, State>) -> Result<String,
205206
.unwrap_or(String::new()))
206207
}
207208

209+
#[tauri::command]
210+
pub async fn get_updater_proxy(_: tauri::State<'_, State>) -> Result<Option<&'static str>, String> {
211+
Ok(swap_tor::TOR_ENVIRONMENT.and_then(|ste| ste.reqwest_proxy()))
212+
}
213+
208214
#[tauri::command]
209215
pub async fn resolve_approval_request(
210216
args: ResolveApprovalArgs,

0 commit comments

Comments
 (0)