From 4c8aa436695d849dfa6e9e83c21f0ccf6f0dcb0d Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Wed, 24 Jul 2024 13:33:18 +1200 Subject: [PATCH] Relay.score(); relay.should_avoid() now internally covers all avoid cases --- gossip-lib/src/overlord/mod.rs | 5 --- gossip-lib/src/relay.rs | 7 +--- gossip-lib/src/storage/types/relay3.rs | 46 ++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/gossip-lib/src/overlord/mod.rs b/gossip-lib/src/overlord/mod.rs index 94ff5352..a44ea1c2 100644 --- a/gossip-lib/src/overlord/mod.rs +++ b/gossip-lib/src/overlord/mod.rs @@ -397,11 +397,6 @@ impl Overlord { return Ok(()); } - // don't connect to rank=0 relays - if relay.rank == 0 { - return Ok(()); - } - let entry = GLOBALS.connected_relays.entry(url.clone()); if let Entry::Occupied(mut oe) = entry { diff --git a/gossip-lib/src/relay.rs b/gossip-lib/src/relay.rs index ee0452bf..d8174924 100644 --- a/gossip-lib/src/relay.rs +++ b/gossip-lib/src/relay.rs @@ -192,9 +192,6 @@ pub fn get_best_relays_with_score( // Load the relay so we can get more score-determining data let relay = GLOBALS.storage.read_or_create_relay(&pr.url, None)?; - if relay.rank == 0 { - continue; - } if relay.should_avoid() { continue; } @@ -272,9 +269,7 @@ pub fn get_dm_relays(pubkey: PublicKey) -> Result, Error> { let mut output: Vec = Vec::new(); for pr in GLOBALS.storage.get_person_relays(pubkey)?.drain(..) { let relay = GLOBALS.storage.read_or_create_relay(&pr.url, None)?; - if relay.rank == 0 { - continue; - } + if relay.should_avoid() { continue; } diff --git a/gossip-lib/src/storage/types/relay3.rs b/gossip-lib/src/storage/types/relay3.rs index a2960adf..e8b21fc0 100644 --- a/gossip-lib/src/storage/types/relay3.rs +++ b/gossip-lib/src/storage/types/relay3.rs @@ -162,7 +162,17 @@ impl Relay3 { } pub fn should_avoid(&self) -> bool { - if let Some(when) = self.avoid_until { + if self.rank == 0 { + true + } else if GLOBALS + .storage + .read_setting_relay_connection_requires_approval() + && self.allow_connect == Some(false) + { + true + } else if crate::storage::Storage::url_is_banned(&self.url) { + true + } else if let Some(when) = self.avoid_until { when >= Unixtime::now() } else { false @@ -180,13 +190,43 @@ impl Relay3 { || (self.rank > 0 && self.success_rate() > 0.50 && self.success_count > 15) } + /// This gives a pure score for the relay outside of context + /// + /// Output ranges from 0.0 (worst) to 1.0 (best) + /// + /// Typical good relays still only score about 0.3, simply because rank goes so high. + /// + /// If `None` is returned, do not use this relay. + pub fn score(&self) -> f32 { + if self.should_avoid() { + return 0.0; + } + + let mut score: f32 = 1.0; + + // Adjust by rank: + // 1 = 0.11111 + // 3 = 0.33333 + // 5 = 0.55555 + // 9 = 1.0 + score = score * self.rank as f32 / 9.0; + + // Adjust by success rate (max penalty of cutting in half) + score = score * (0.5 + 0.5 * self.success_rate()); + + // We don't penalize low-attempt relays even as they are less reliable + // because we want to let new relays establish. + + score + } + pub fn choose_relays(bits: u64, f: F) -> Result, Error> where F: Fn(&Relay3) -> bool, { GLOBALS .storage - .filter_relays(|r| r.has_usage_bits(bits) && r.rank != 0 && !r.should_avoid() && f(r)) + .filter_relays(|r| r.has_usage_bits(bits) && !r.should_avoid() && f(r)) } pub fn choose_relay_urls(bits: u64, f: F) -> Result, Error> @@ -195,7 +235,7 @@ impl Relay3 { { Ok(GLOBALS .storage - .filter_relays(|r| r.has_usage_bits(bits) && r.rank != 0 && !r.should_avoid() && f(r))? + .filter_relays(|r| r.has_usage_bits(bits) && !r.should_avoid() && f(r))? .iter() .map(|r| r.url.clone()) .collect())