Skip to content

Commit b7ccdf7

Browse files
committed
fix(p2p): redial beacon bootnodes after disconnect
1 parent 08c71c0 commit b7ccdf7

1 file changed

Lines changed: 49 additions & 13 deletions

File tree

  • crates/networking/p2p/src/network/beacon

crates/networking/p2p/src/network/beacon/mod.rs

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub struct Network {
104104
request_id: u64,
105105
network_state: Arc<NetworkState>,
106106
peers_to_ping: HashSetDelay<PeerId>,
107+
bootnodes: Vec<Enr>,
107108
}
108109

109110
impl Network {
@@ -221,6 +222,7 @@ impl Network {
221222
request_id: 0,
222223
network_state,
223224
peers_to_ping: HashSetDelay::new(PING_INTERVAL_DURATION),
225+
bootnodes: config.discv5_config.bootnodes.clone(),
224226
};
225227

226228
network.start_network_worker(config).await?;
@@ -304,9 +306,19 @@ impl Network {
304306
manager_sender: UnboundedSender<ReamNetworkEvent>,
305307
mut p2p_receiver: UnboundedReceiver<P2PMessage>,
306308
) {
309+
let mut bootnode_redial_interval = interval(Duration::from_secs(20));
307310
let mut status_interval = interval(Duration::from_secs(30));
308311
loop {
309312
tokio::select! {
313+
_ = bootnode_redial_interval.tick() => {
314+
let bootnodes = self
315+
.bootnodes
316+
.iter()
317+
.cloned()
318+
.map(|bootnode| (bootnode, None))
319+
.collect();
320+
self.handle_discovered_peers(bootnodes);
321+
}
310322
Some(event) = self.swarm.next() => {
311323
if let Some(event) = self.parse_swarm_event(event).await && let Err(err) = manager_sender.send(event) {
312324
warn!("Failed to send event: {err:?}");
@@ -533,45 +545,69 @@ impl Network {
533545
fn handle_discovered_peers(&mut self, peers: HashMap<Enr, Option<Instant>>) {
534546
trace!("Discovered peers: {peers:?}");
535547
for (enr, _) in peers {
548+
let Some(peer_id) = peer_id_from_enr(&enr) else {
549+
trace!("Skipping peer with no peer id in ENR: {enr:?}");
550+
continue;
551+
};
552+
if peer_id == self.peer_id {
553+
trace!("Skipping self peer: {peer_id:?}");
554+
continue;
555+
}
556+
557+
let peer_state = self
558+
.network_state
559+
.peer_table
560+
.read()
561+
.get(&peer_id)
562+
.map(|peer| peer.state);
563+
if matches!(
564+
peer_state,
565+
Some(ConnectionState::Connected | ConnectionState::Connecting)
566+
) {
567+
trace!("Peer {peer_id:?} is already {peer_state:?}, skipping dial");
568+
continue;
569+
}
570+
536571
let mut multiaddrs: Vec<Multiaddr> = Vec::new();
537572
if let Some(ip) = enr.ip4()
538573
&& let Some(tcp) = enr.tcp4()
539574
{
540575
let mut multiaddr: Multiaddr = ip.into();
541576
multiaddr.push(Protocol::Tcp(tcp));
577+
multiaddr.push(Protocol::P2p(peer_id));
542578
multiaddrs.push(multiaddr);
543579
}
544580
if let Some(ip6) = enr.ip6()
545581
&& let Some(tcp6) = enr.tcp6()
546582
{
547583
let mut multiaddr: Multiaddr = ip6.into();
548584
multiaddr.push(Protocol::Tcp(tcp6));
585+
multiaddr.push(Protocol::P2p(peer_id));
549586
multiaddrs.push(multiaddr);
550587
}
551588

552-
let mut successfully_dialed = false;
589+
let mut dialed_address = None;
553590
for multiaddr in multiaddrs {
591+
let address = multiaddr.clone();
554592
if let Err(err) = self.swarm.dial(multiaddr) {
555593
warn!("Failed to dial peer: {err:?}");
556594
} else {
557-
successfully_dialed = true;
595+
dialed_address.get_or_insert(address);
558596
}
559597
}
560598

561-
if !successfully_dialed {
599+
let Some(address) = dialed_address else {
562600
trace!("Failed to dial any multiaddr for peer: {:?}", enr);
563601
continue;
564-
}
602+
};
565603

566-
if let Some(peer_id) = peer_id_from_enr(&enr) {
567-
self.network_state.upsert_peer(
568-
peer_id,
569-
None,
570-
ConnectionState::Connecting,
571-
Direction::Outbound,
572-
Some(enr.clone()),
573-
);
574-
}
604+
self.network_state.upsert_peer(
605+
peer_id,
606+
Some(address),
607+
ConnectionState::Connecting,
608+
Direction::Outbound,
609+
Some(enr.clone()),
610+
);
575611
}
576612
}
577613

0 commit comments

Comments
 (0)