diff --git a/gossip-bin/src/ui/widgets/relay_entry.rs b/gossip-bin/src/ui/widgets/relay_entry.rs index 85f23d838..bd939a4a5 100644 --- a/gossip-bin/src/ui/widgets/relay_entry.rs +++ b/gossip-bin/src/ui/widgets/relay_entry.rs @@ -768,18 +768,54 @@ impl RelayEntry { if let Some(entry) = GLOBALS.relay_tests.get(&self.relay.url) { let pos = pos + vec2(0.0, NIP11_Y_SPACING); - let text = match entry.value() { - None => "Testing...".to_owned(), - Some(results) => if results.test_failed { - "Relay test failed.".to_owned() - } else { - format!("{} outbox, {} inbox, {} public_inbox", - results.outbox.tick(), - results.inbox.tick(), - results.public_inbox.tick()) + match entry.value() { + None => { + draw_text_at(ui, pos, "Testing...".into(), align, None, None); + } + Some(results) => { + if results.test_failed { + draw_text_at(ui, pos, "Relay test failed.".into(), align, None, None); + } else { + let text = format!("{} outbox,", results.outbox.tick()); + let hover = results.outbox.hover().unwrap_or("Ok"); + let (galley, response) = allocate_text_at( + ui, + pos, + text.into(), + align, + self.make_id("outbox_suitability"), + ); + draw_text_galley_at(ui, pos, galley, None, None); + response.on_hover_text(hover); + + let pos = pos + vec2(100.0, 0.0); + let text = format!("{} inbox,", results.inbox.tick()); + let hover = results.inbox.hover().unwrap_or("Ok"); + let (galley, response) = allocate_text_at( + ui, + pos, + text.into(), + align, + self.make_id("inbox_suitability"), + ); + draw_text_galley_at(ui, pos, galley, None, None); + response.on_hover_text(hover); + + let pos = pos + vec2(100.0, 0.0); + let text = format!("{} Public inbox,", results.public_inbox.tick()); + let hover = results.public_inbox.hover().unwrap_or("Ok"); + let (galley, response) = allocate_text_at( + ui, + pos, + text.into(), + align, + self.make_id("public_inbox_suitability"), + ); + draw_text_galley_at(ui, pos, galley, None, None); + response.on_hover_text(hover); + } } }; - draw_text_at(ui, pos, text.into(), align, None, None); } } } diff --git a/gossip-lib/src/overlord.rs b/gossip-lib/src/overlord.rs index d58b26318..ef93def34 100644 --- a/gossip-lib/src/overlord.rs +++ b/gossip-lib/src/overlord.rs @@ -16,7 +16,7 @@ use crate::people::{Person, PersonList}; use crate::relay; use crate::relay::Relay; use crate::relay_picker::RelayAssignment; -use crate::relay_test_results::{RelayTestResults, RelayTestResult}; +use crate::relay_test_results::{RelayTestResult, RelayTestResults}; use crate::storage::{PersonTable, Table}; use crate::RunState; use heed::RwTxn; @@ -2825,7 +2825,9 @@ impl Overlord { } Err(e) => { tracing::error!("{}", e); - GLOBALS.relay_tests.insert(relay_url, Some(RelayTestResults::fail())); + GLOBALS + .relay_tests + .insert(relay_url, Some(RelayTestResults::fail())); } } })); @@ -2860,17 +2862,23 @@ impl Overlord { // 1. posted_outbox conn1.authenticate_if_challenged().await?; - match conn1.post_event(outbox_event.clone(), Duration::from_secs(2)).await? { + match conn1 + .post_event(outbox_event.clone(), Duration::from_secs(2)) + .await? + { (true, _) => posted_outbox = RelayTestResult::Pass, (false, msg) => { if msg.starts_with("auth-required:") { conn1.authenticate_if_challenged().await?; - match conn1.post_event(outbox_event.clone(), Duration::from_secs(2)).await? { + match conn1 + .post_event(outbox_event.clone(), Duration::from_secs(2)) + .await? + { (true, _) => posted_outbox = RelayTestResult::Pass, - (false, _) => posted_outbox = RelayTestResult::Fail, + (false, msg) => posted_outbox = RelayTestResult::Fail(msg), } } else { - posted_outbox = RelayTestResult::Fail; + posted_outbox = RelayTestResult::Fail(msg); } } } @@ -2906,18 +2914,25 @@ impl Overlord { filter.add_author(&pkh); filter.since = Some(outbox_event.created_at); - let fetch_result = conn.fetch_events(vec![filter], Duration::from_secs(2)).await?; + let fetch_result = conn + .fetch_events(vec![filter], Duration::from_secs(2)) + .await?; + let close_msg = fetch_result.close_msg.clone(); if fetch_result.into_events().contains(&outbox_event) { anon_fetched_outbox = RelayTestResult::Pass; } else { - anon_fetched_outbox = RelayTestResult::Fail; + anon_fetched_outbox = + RelayTestResult::Fail(close_msg.unwrap_or("timed out".to_string())); } } // 3. anon_posted_inbox - match conn.post_event(inbox_event.clone(), Duration::from_secs(2)).await? { + match conn + .post_event(inbox_event.clone(), Duration::from_secs(2)) + .await? + { (true, _) => anon_posted_inbox = RelayTestResult::Pass, - (false, _) => anon_posted_inbox = RelayTestResult::Fail, + (false, msg) => anon_posted_inbox = RelayTestResult::Fail(msg), } let mut inbox_filter = Filter::new(); @@ -2928,33 +2943,39 @@ impl Overlord { // 4. anon_fetched_inbox if anon_posted_inbox == RelayTestResult::Pass { - let fetch_result = conn.fetch_events(vec![inbox_filter.clone()], Duration::from_secs(2)).await?; + let fetch_result = conn + .fetch_events(vec![inbox_filter.clone()], Duration::from_secs(2)) + .await?; + let close_msg = fetch_result.close_msg.clone(); if fetch_result.into_events().contains(&inbox_event) { anon_fetched_inbox = RelayTestResult::Pass; } else { - anon_fetched_inbox = RelayTestResult::Fail; + anon_fetched_inbox = + RelayTestResult::Fail(close_msg.unwrap_or("timed out".to_string())); } } // 5. fetched_inbox conn.authenticate_if_challenged().await?; - let fetch_result = conn.fetch_events(vec![inbox_filter.clone()], Duration::from_secs(2)).await?; + let fetch_result = conn + .fetch_events(vec![inbox_filter.clone()], Duration::from_secs(2)) + .await?; + let close_msg = fetch_result.close_msg.clone(); if fetch_result.into_events().contains(&inbox_event) { fetched_inbox = RelayTestResult::Pass; } else { - fetched_inbox = RelayTestResult::Fail; + fetched_inbox = RelayTestResult::Fail(close_msg.unwrap_or("timed out".to_string())); } conn.disconnect().await?; drop(conn); Ok(RelayTestResults { - outbox: posted_outbox + anon_fetched_outbox, - inbox: anon_posted_inbox + fetched_inbox, - public_inbox: anon_posted_inbox + anon_fetched_inbox, + outbox: posted_outbox.clone() + anon_fetched_outbox.clone(), + inbox: anon_posted_inbox.clone() + fetched_inbox.clone(), + public_inbox: anon_posted_inbox.clone() + anon_fetched_inbox.clone(), test_failed: false, }) - } /// Unlock the private key with the given passphrase so that gossip can use it. diff --git a/gossip-lib/src/relay_test_results.rs b/gossip-lib/src/relay_test_results.rs index 9919e085c..0ed1b0e41 100644 --- a/gossip-lib/src/relay_test_results.rs +++ b/gossip-lib/src/relay_test_results.rs @@ -1,11 +1,11 @@ use std::ops::Add; -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] pub enum RelayTestResult { #[default] Unknown, Pass, - Fail, + Fail(String), } impl Add for RelayTestResult { @@ -13,8 +13,8 @@ impl Add for RelayTestResult { fn add(self, other: RelayTestResult) -> RelayTestResult { match (self, other) { - (RelayTestResult::Fail, _) => RelayTestResult::Fail, - (_, RelayTestResult::Fail) => RelayTestResult::Fail, + (RelayTestResult::Fail(s), _) => RelayTestResult::Fail(s), + (_, RelayTestResult::Fail(s)) => RelayTestResult::Fail(s), (RelayTestResult::Unknown, _) => RelayTestResult::Unknown, (_, RelayTestResult::Unknown) => RelayTestResult::Unknown, _ => RelayTestResult::Pass, @@ -27,12 +27,20 @@ impl RelayTestResult { match *self { RelayTestResult::Unknown => '❓', RelayTestResult::Pass => '✅', - RelayTestResult::Fail => '❌', + RelayTestResult::Fail(_) => '❌', + } + } + + pub fn hover<'a>(&'a self) -> Option<&'a str> { + match *self { + RelayTestResult::Unknown => None, + RelayTestResult::Pass => None, + RelayTestResult::Fail(ref s) => Some(s), } } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Default)] pub struct RelayTestResults { pub outbox: RelayTestResult, pub inbox: RelayTestResult, @@ -42,7 +50,7 @@ pub struct RelayTestResults { impl RelayTestResults { pub fn dm(&self) -> RelayTestResult { - self.inbox + self.outbox + self.inbox.clone() + self.outbox.clone() } pub fn fail() -> RelayTestResults {