mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 08:14:42 +00:00
Schedule retry on startup peer-init failure
When initiate_peer_connections() runs at boot, address resolution can fail for an entire peer (no operational transport for the configured transport types, all addresses unreachable, NAT rebind invalidated cached endpoints, etc.). Before this change the failure was logged and silently forgotten — the peer entry stayed in a dead state forever, accepting incoming pings but unable to answer them, until the daemon was manually restarted. The retry plumbing (schedule_retry / process_pending_retries with exponential backoff) already exists and is wired into the post-handshake failure paths (BootstrapEvent::Failed, MMP dead-link timeout, handshake timeout). The startup loop just wasn't calling it. Mirror the BootstrapEvent::Failed path: on a startup peer-init error, parse the peer's npub and call schedule_retry so the peer recovers without operator intervention. Includes a regression test that asserts retry_pending is populated when initiate_peer_connections() fails for a peer with no operational transport. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Johnathan Corgan
co-authored by
Claude Opus 4.7
parent
6ce1406664
commit
64cc30df12
@@ -952,6 +952,38 @@ fn test_promote_clears_retry_pending() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Initial peer-init failure at startup must enqueue a retry. Otherwise a peer
|
||||
/// whose addresses cannot be dialed at boot (no operational transport for the
|
||||
/// configured transport types, all addresses unreachable, NAT rebind, etc.)
|
||||
/// stays dead forever — pings arrive but cannot be answered until the daemon
|
||||
/// is manually restarted.
|
||||
#[tokio::test]
|
||||
async fn test_initiate_peer_connections_schedules_retry_on_no_transport() {
|
||||
let peer_identity = Identity::generate();
|
||||
let peer_npub = peer_identity.npub();
|
||||
let peer_node_addr = *PeerIdentity::from_npub(&peer_npub).unwrap().node_addr();
|
||||
|
||||
let mut config = Config::new();
|
||||
// udp address but no UDP transport registered on the node — every dial
|
||||
// attempt resolves to NodeError::NoTransportForType.
|
||||
config.peers.push(crate::config::PeerConfig::new(
|
||||
peer_npub,
|
||||
"udp",
|
||||
"10.0.0.2:2121",
|
||||
));
|
||||
|
||||
let mut node = Node::new(config).unwrap();
|
||||
assert!(node.retry_pending.is_empty());
|
||||
|
||||
node.initiate_peer_connections().await;
|
||||
|
||||
assert!(
|
||||
node.retry_pending.contains_key(&peer_node_addr),
|
||||
"startup peer-init failure must enqueue a retry so the peer can recover \
|
||||
without a daemon restart"
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// transport_mtu() — ISSUE-2026-0011 regression coverage
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user