Skip to content

Commit 326b8a6

Browse files
author
EchoBT
committed
feat: Auto-retry bootstrap peer connection every 30 seconds
If the validator has no peers connected, it will automatically retry connecting to bootstrap peers every 30 seconds until successful. This ensures validators eventually connect to the network even if the bootnode is temporarily unavailable at startup.
1 parent 39f578d commit 326b8a6

File tree

1 file changed

+78
-4
lines changed

1 file changed

+78
-4
lines changed

crates/network/src/node.rs

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ pub struct NetworkNode {
9292
/// Connected peers
9393
peers: Arc<RwLock<HashSet<PeerId>>>,
9494

95+
/// Bootstrap peers to connect to
96+
bootstrap_peers: Vec<Multiaddr>,
97+
9598
/// Event sender
9699
event_tx: mpsc::Sender<NetworkEvent>,
97100

@@ -139,6 +142,7 @@ impl NetworkNode {
139142
swarm,
140143
local_peer_id,
141144
peers: Arc::new(RwLock::new(HashSet::new())),
145+
bootstrap_peers: config.bootstrap_peers.clone(),
142146
event_tx,
143147
event_rx: Some(event_rx),
144148
})
@@ -169,12 +173,36 @@ impl NetworkNode {
169173
info!("Listening on {:?}", config.listen_addr);
170174

171175
// Connect to bootstrap peers
172-
for addr in &config.bootstrap_peers {
176+
self.dial_bootstrap_peers();
177+
178+
Ok(())
179+
}
180+
181+
/// Dial all bootstrap peers
182+
pub fn dial_bootstrap_peers(&mut self) {
183+
for addr in self.bootstrap_peers.clone() {
173184
info!("Dialing bootstrap peer: {}", addr);
174-
self.swarm.dial(addr.clone())?;
185+
if let Err(e) = self.swarm.dial(addr.clone()) {
186+
warn!("Failed to dial bootstrap peer {}: {}", addr, e);
187+
}
175188
}
189+
}
176190

177-
Ok(())
191+
/// Check if connected to any bootstrap peer
192+
pub fn has_bootstrap_connection(&self) -> bool {
193+
if self.bootstrap_peers.is_empty() {
194+
return true; // No bootstrap peers configured
195+
}
196+
// Check if we have any peers connected
197+
!self.peers.read().is_empty()
198+
}
199+
200+
/// Retry connecting to bootstrap peers if not connected
201+
pub fn retry_bootstrap_if_needed(&mut self) {
202+
if !self.has_bootstrap_connection() {
203+
info!("No peers connected, retrying bootstrap peers...");
204+
self.dial_bootstrap_peers();
205+
}
178206
}
179207

180208
/// Broadcast a message via gossip
@@ -244,9 +272,55 @@ impl NetworkNode {
244272
}
245273

246274
/// Run the event loop (should be spawned as a task)
275+
/// Includes automatic retry of bootstrap peers every 30 seconds if not connected
247276
pub async fn run(&mut self) {
277+
let mut bootstrap_retry_interval = tokio::time::interval(Duration::from_secs(30));
278+
bootstrap_retry_interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
279+
248280
loop {
249-
self.process_next_event().await;
281+
tokio::select! {
282+
event = self.swarm.select_next_some() => {
283+
self.handle_swarm_event(event).await;
284+
}
285+
_ = bootstrap_retry_interval.tick() => {
286+
self.retry_bootstrap_if_needed();
287+
}
288+
}
289+
}
290+
}
291+
292+
/// Handle a swarm event
293+
async fn handle_swarm_event(&mut self, event: SwarmEvent<MiniChainBehaviourEvent>) {
294+
match event {
295+
SwarmEvent::Behaviour(event) => {
296+
self.handle_behaviour_event(event).await;
297+
}
298+
SwarmEvent::NewListenAddr { address, .. } => {
299+
info!("Listening on {}", address);
300+
}
301+
SwarmEvent::ConnectionEstablished { peer_id, .. } => {
302+
info!("Connected to peer: {}", peer_id);
303+
self.peers.write().insert(peer_id);
304+
let _ = self
305+
.event_tx
306+
.send(NetworkEvent::PeerConnected(peer_id))
307+
.await;
308+
}
309+
SwarmEvent::ConnectionClosed { peer_id, .. } => {
310+
info!("Disconnected from peer: {}", peer_id);
311+
self.peers.write().remove(&peer_id);
312+
let _ = self
313+
.event_tx
314+
.send(NetworkEvent::PeerDisconnected(peer_id))
315+
.await;
316+
}
317+
SwarmEvent::IncomingConnection { .. } => {}
318+
SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => {
319+
if let Some(peer_id) = peer_id {
320+
warn!("Failed to connect to {}: {}", peer_id, error);
321+
}
322+
}
323+
_ => {}
250324
}
251325
}
252326

0 commit comments

Comments
 (0)