aboutsummaryrefslogtreecommitdiffstats
path: root/src/routing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routing.rs')
-rw-r--r--src/routing.rs19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/routing.rs b/src/routing.rs
index a9b618d..dad9bb5 100644
--- a/src/routing.rs
+++ b/src/routing.rs
@@ -140,10 +140,8 @@ impl KBucket {
/// Add a contact to the replacement cache.
fn add_to_cache(&mut self, peer: PeerInfo) {
// Update if already in cache
- if let Some(pos) = self
- .replacements
- .iter()
- .position(|r| r.id == peer.id)
+ if let Some(pos) =
+ self.replacements.iter().position(|r| r.id == peer.id)
{
self.replacements.remove(pos);
self.replacements.push(peer);
@@ -368,7 +366,9 @@ impl RoutingTable {
/// Record a communication failure for a peer.
/// If the peer becomes stale (exceeds threshold),
/// tries to replace it with a cached contact.
- /// Returns the evicted NodeId if replacement happened.
+ /// If no replacement is available, removes the stale
+ /// peer outright to avoid phantom entries.
+ /// Returns the evicted NodeId if removal happened.
pub fn record_failure(&mut self, id: &NodeId) -> Option<NodeId> {
// Never mark pinned nodes as stale
if self.pinned.contains(id) {
@@ -377,7 +377,14 @@ impl RoutingTable {
let idx = self.bucket_index(id)?;
let became_stale = self.buckets[idx].record_failure(id);
if became_stale {
- self.buckets[idx].try_replace_stale(id)
+ // Try replacement cache first; if empty, just
+ // remove the dead peer so it doesn't linger.
+ let evicted = self.buckets[idx].try_replace_stale(id);
+ if evicted.is_none() {
+ self.remove(id);
+ return Some(*id);
+ }
+ evicted
} else {
None
}