|
14 | 14 | use std::sync::{Arc, Mutex}; |
15 | 15 |
|
16 | 16 | use anyhow::{anyhow, Result}; |
| 17 | +use payjoin::relay::{RelaySelector, SelectContext}; |
17 | 18 | use payjoin::Url; |
18 | 19 |
|
19 | 20 | use super::Config; |
20 | 21 |
|
21 | 22 | #[derive(Debug, Clone)] |
22 | 23 | pub struct MailroomManager { |
23 | 24 | config: Config, |
24 | | - failed_relays: Arc<Mutex<Vec<Url>>>, |
| 25 | + relay_selector: Arc<Mutex<RelaySelector>>, |
25 | 26 | failed_directories: Arc<Mutex<Vec<Url>>>, |
26 | 27 | } |
27 | 28 |
|
28 | 29 | impl MailroomManager { |
29 | | - pub fn new(config: Config) -> Self { |
30 | | - MailroomManager { |
| 30 | + pub fn new(config: Config) -> Result<Self> { |
| 31 | + let relay_selector = RelaySelector::new(config.v2()?.ohttp_relays.clone()); |
| 32 | + Ok(MailroomManager { |
31 | 33 | config, |
32 | | - failed_relays: Arc::new(Mutex::new(Vec::new())), |
| 34 | + relay_selector: Arc::new(Mutex::new(relay_selector)), |
33 | 35 | failed_directories: Arc::new(Mutex::new(Vec::new())), |
34 | | - } |
| 36 | + }) |
35 | 37 | } |
36 | 38 |
|
37 | 39 | pub fn add_failed_relay(&self, relay: Url) { |
38 | | - self.failed_relays.lock().expect("Lock should not be poisoned").push(relay); |
| 40 | + self.relay_selector.lock().expect("Lock should not be poisoned").mark_failed(&relay); |
39 | 41 | } |
40 | 42 |
|
41 | 43 | pub fn clear_failed_relays(&self) { |
42 | | - self.failed_relays.lock().expect("Lock should not be poisoned").clear(); |
| 44 | + self.relay_selector.lock().expect("Lock should not be poisoned").clear_failed(); |
43 | 45 | } |
44 | 46 |
|
45 | 47 | pub fn add_failed_directory(&self, directory: Url) { |
46 | 48 | self.failed_directories.lock().expect("Lock should not be poisoned").push(directory); |
47 | 49 | } |
48 | 50 |
|
49 | 51 | pub fn choose_relay(&self) -> Result<Url> { |
50 | | - use payjoin::bitcoin::secp256k1::rand::prelude::SliceRandom; |
51 | | - let relays = &self.config.v2()?.ohttp_relays; |
52 | | - let failed_relays = self.failed_relays.lock().expect("Lock should not be poisoned"); |
53 | | - let remaining_relays: Vec<_> = |
54 | | - relays.iter().filter(|r| !failed_relays.contains(r)).cloned().collect(); |
55 | | - |
56 | | - if remaining_relays.is_empty() { |
57 | | - return Err(anyhow!("No valid relays available")); |
58 | | - } |
59 | | - |
60 | | - remaining_relays |
61 | | - .choose(&mut payjoin::bitcoin::key::rand::thread_rng()) |
62 | | - .cloned() |
63 | | - .ok_or_else(|| anyhow!("Failed to select from remaining relays")) |
| 52 | + self.relay_selector |
| 53 | + .lock() |
| 54 | + .expect("Lock should not be poisoned") |
| 55 | + .select(&SelectContext::random(), &mut payjoin::bitcoin::key::rand::thread_rng()) |
| 56 | + .ok_or_else(|| anyhow!("No valid relays available")) |
64 | 57 | } |
65 | 58 |
|
66 | 59 | pub fn choose_directory(&self) -> Result<Url> { |
|
0 commit comments