diff --git a/src/node/retry.rs b/src/node/retry.rs index 5b25df2..0eb371d 100644 --- a/src/node/retry.rs +++ b/src/node/retry.rs @@ -259,6 +259,25 @@ impl Node { let peer_config = state.peer_config.clone(); + // Refresh the peer's overlay advert before retrying. The cache is + // read-only on hit (see fetch_advert), so every retry without a + // refetch dials the same cached endpoint — and the most common + // reason a peer ended up in retry_pending is that the cached + // endpoint just stopped working (NAT rebind, port change, peer + // restart on a different port). Without this refresh the retry + // loop dials the same dead address forever. + // + // refetch_advert_for_stale_check uses the relay's advert as + // ground truth: replaces the cache if there's a newer one, + // evicts if the relay has nothing, otherwise leaves it. Cheap + // (one Filter fetch with 2s timeout) and bounded by the retry + // backoff cadence. + if let Some(bootstrap) = self.nostr_discovery.clone() { + let _ = bootstrap + .refetch_advert_for_stale_check(&peer_config.npub) + .await; + } + match self.initiate_peer_connection(&peer_config).await { Ok(()) => { // Push retry_after_ms past the handshake timeout window so