Skip to content

Commit 9fb290d

Browse files
committed
net: be more aggresive wrt removing from known peers DB
Prior to this commit we end up trying to reconnect to peers every time we start up. Be more aggressive in removing bad peers from the DB list of known peers. Also make sure to re-add the seed node every time we start up, if we have an empty list of known peers.
1 parent e8e70e4 commit 9fb290d

File tree

2 files changed

+54
-27
lines changed

2 files changed

+54
-27
lines changed

lib/net/mod.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,25 @@ impl Net {
235235
}
236236
}
237237

238-
pub fn remove_active_peer(&self, addr: SocketAddr) {
239-
tracing::trace!(%addr, "remove active peer: starting");
238+
/// Removes a peer from the active peers list.
239+
#[instrument(skip_all, fields(addr))]
240+
pub fn remove_active_peer(
241+
&self,
242+
env: &heed::Env,
243+
addr: SocketAddr,
244+
) -> Result<(), Error> {
240245
let mut active_peers_write = self.active_peers.write();
241246
if let Some(peer_connection) = active_peers_write.remove(&addr) {
242247
drop(peer_connection);
243248
tracing::info!(%addr, "remove active peer: disconnected");
244249
}
250+
251+
let mut rwtxn = env.write_txn()?;
252+
self.known_peers.delete(&mut rwtxn, &addr)?;
253+
rwtxn.commit()?;
254+
tracing::info!(%addr, "remove active peer: removed from known peers");
255+
256+
Ok(())
245257
}
246258

247259
// TODO: This should have more context.
@@ -317,16 +329,8 @@ impl Net {
317329
match env.open_database(&rwtxn, Some("known_peers"))? {
318330
Some(known_peers) => known_peers,
319331
None => {
320-
let known_peers =
321-
env.create_database(&mut rwtxn, Some("known_peers"))?;
322-
const SEED_NODE_ADDR: SocketAddr = SocketAddr::new(
323-
std::net::IpAddr::V4(std::net::Ipv4Addr::new(
324-
172, 105, 148, 135,
325-
)),
326-
4000 + THIS_SIDECHAIN as u16,
327-
);
328-
known_peers.put(&mut rwtxn, &SEED_NODE_ADDR, &())?;
329-
known_peers
332+
tracing::info!("creating known peers database");
333+
env.create_database(&mut rwtxn, Some("known_peers"))?
330334
}
331335
};
332336
rwtxn.commit()?;
@@ -339,16 +343,33 @@ impl Net {
339343
peer_info_tx,
340344
known_peers,
341345
};
342-
#[allow(clippy::let_and_return)]
343346
let known_peers: Vec<_> = {
344-
let rotxn = env.read_txn()?;
347+
let mut txn = env.write_txn()?;
348+
349+
// important: we need to always have at least one peer. we
350+
// might end up with this peer misbehaving, causing us to
351+
// disconnect and delete it from the database. always try
352+
// and stick it back in, if it's missing!
353+
if net.known_peers.is_empty(&txn)? {
354+
const SEED_NODE_ADDR: SocketAddr = SocketAddr::new(
355+
std::net::IpAddr::V4(std::net::Ipv4Addr::new(
356+
172, 105, 148, 135,
357+
)),
358+
4000 + THIS_SIDECHAIN as u16,
359+
);
360+
361+
tracing::info!("empty list of known peers, adding seed node {SEED_NODE_ADDR}");
362+
net.known_peers.put(&mut txn, &SEED_NODE_ADDR, &())?;
363+
}
364+
345365
let known_peers = net
346366
.known_peers
347-
.iter(&rotxn)?
367+
.iter(&txn)?
348368
.transpose_into_fallible()
349369
.collect()?;
350370
known_peers
351371
};
372+
352373
let () = known_peers.into_iter().try_for_each(|(peer_addr, _)| {
353374
tracing::trace!(
354375
"new net: connecting to already known peer at {peer_addr}"
@@ -360,9 +381,7 @@ impl Net {
360381
tracing::warn!(
361382
%addr, "new net: known peer with invalid remote address, removing"
362383
);
363-
let mut tx = env.write_txn()?;
364-
net.known_peers.delete(&mut tx, &peer_addr)?;
365-
tx.commit()?;
384+
net.remove_active_peer(env, peer_addr)?;
366385

367386
tracing::info!(
368387
%addr,

lib/node/net_task.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ where
434434
if header.hash() != block_hash {
435435
// Invalid response
436436
tracing::warn!(%addr, ?req, ?resp,"Invalid response from peer; unexpected block hash");
437-
let () = ctxt.net.remove_active_peer(addr);
437+
let () = ctxt.net.remove_active_peer(&ctxt.env, addr)?;
438438
return Ok(());
439439
}
440440
{
@@ -567,13 +567,13 @@ where
567567
// check that the end header is as requested
568568
let Some(end_header) = headers.last() else {
569569
tracing::warn!(%addr, ?req, "Invalid response from peer; missing end header");
570-
let () = ctxt.net.remove_active_peer(addr);
570+
let () = ctxt.net.remove_active_peer(&ctxt.env, addr)?;
571571
return Ok(());
572572
};
573573
let end_header_hash = end_header.hash();
574574
if end_header_hash != end {
575575
tracing::warn!(%addr, ?req, ?end_header,"Invalid response from peer; unexpected end header");
576-
let () = ctxt.net.remove_active_peer(addr);
576+
let () = ctxt.net.remove_active_peer(&ctxt.env, addr)?;
577577
return Ok(());
578578
}
579579
// Must be at least one header due to previous check
@@ -583,7 +583,7 @@ where
583583
&& !start.contains(&start_hash)
584584
{
585585
tracing::warn!(%addr, ?req, %start_hash, "Invalid response from peer; invalid start hash");
586-
let () = ctxt.net.remove_active_peer(addr);
586+
let () = ctxt.net.remove_active_peer(&ctxt.env, addr)?;
587587
return Ok(());
588588
}
589589
// check that the end header height is as expected
@@ -602,7 +602,8 @@ where
602602
};
603603
if end_height != height {
604604
tracing::warn!(%addr, ?req, ?start_hash, "Invalid response from peer; invalid end height");
605-
let () = ctxt.net.remove_active_peer(addr);
605+
let () =
606+
ctxt.net.remove_active_peer(&ctxt.env, addr)?;
606607
return Ok(());
607608
}
608609
}
@@ -611,7 +612,8 @@ where
611612
for header in &headers {
612613
if header.prev_side_hash != prev_side_hash {
613614
tracing::warn!(%addr, ?req, ?headers,"Invalid response from peer; non-sequential headers");
614-
let () = ctxt.net.remove_active_peer(addr);
615+
let () =
616+
ctxt.net.remove_active_peer(&ctxt.env, addr)?;
615617
return Ok(());
616618
}
617619
prev_side_hash = Some(header.hash());
@@ -669,7 +671,7 @@ where
669671
) => {
670672
// Invalid response
671673
tracing::warn!(%addr, ?req, ?resp,"Invalid response from peer");
672-
let () = ctxt.net.remove_active_peer(addr);
674+
let () = ctxt.net.remove_active_peer(&ctxt.env, addr)?;
673675
Ok(())
674676
}
675677
}
@@ -856,7 +858,10 @@ where
856858
MailboxItem::PeerInfo(Some((addr, None))) => {
857859
// peer connection is closed, remove it
858860
tracing::warn!(%addr, "Connection to peer closed");
859-
let () = self.ctxt.net.remove_active_peer(addr);
861+
let () = self
862+
.ctxt
863+
.net
864+
.remove_active_peer(&self.ctxt.env, addr)?;
860865
continue;
861866
}
862867
MailboxItem::PeerInfo(Some((addr, Some(peer_info)))) => {
@@ -865,7 +870,10 @@ where
865870
PeerConnectionInfo::Error(err) => {
866871
let err = anyhow::anyhow!(err);
867872
tracing::error!(%addr, err = format!("{err:#}"), "Peer connection error");
868-
let () = self.ctxt.net.remove_active_peer(addr);
873+
let () = self
874+
.ctxt
875+
.net
876+
.remove_active_peer(&self.ctxt.env, addr)?;
869877
}
870878
PeerConnectionInfo::NeedBmmVerification {
871879
main_hash,

0 commit comments

Comments
 (0)