diff options
Diffstat (limited to 'src/routing.rs')
| -rw-r--r-- | src/routing.rs | 19 |
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 } |