Skip to content

Commit 114d784

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 114d784

File tree

2 files changed

+53
-24
lines changed

2 files changed

+53
-24
lines changed

lib/net/mod.rs

Lines changed: 36 additions & 15 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,15 +329,9 @@ impl Net {
317329
match env.open_database(&rwtxn, Some("known_peers"))? {
318330
Some(known_peers) => known_peers,
319331
None => {
332+
tracing::info!("creating known peers database");
320333
let known_peers =
321334
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, &())?;
329335
known_peers
330336
}
331337
};
@@ -339,16 +345,33 @@ impl Net {
339345
peer_info_tx,
340346
known_peers,
341347
};
342-
#[allow(clippy::let_and_return)]
343348
let known_peers: Vec<_> = {
344-
let rotxn = env.read_txn()?;
349+
let mut txn = env.write_txn()?;
350+
351+
// important: we need to always have at least one peer. we
352+
// might end up with this peer misbehaving, causing us to
353+
// disconnect and delete it from the database. always try
354+
// and stick it back in, if it's missing!
355+
if net.known_peers.is_empty(&txn)? {
356+
const SEED_NODE_ADDR: SocketAddr = SocketAddr::new(
357+
std::net::IpAddr::V4(std::net::Ipv4Addr::new(
358+
172, 105, 148, 135,
359+
)),
360+
4000 + THIS_SIDECHAIN as u16,
361+
);
362+
363+
tracing::info!("empty list of known peers, adding seed node {SEED_NODE_ADDR}");
364+
net.known_peers.put(&mut txn, &SEED_NODE_ADDR, &())?;
365+
}
366+
345367
let known_peers = net
346368
.known_peers
347-
.iter(&rotxn)?
369+
.iter(&txn)?
348370
.transpose_into_fallible()
349371
.collect()?;
350372
known_peers
351373
};
374+
352375
let () = known_peers.into_iter().try_for_each(|(peer_addr, _)| {
353376
tracing::trace!(
354377
"new net: connecting to already known peer at {peer_addr}"
@@ -360,9 +383,7 @@ impl Net {
360383
tracing::warn!(
361384
%addr, "new net: known peer with invalid remote address, removing"
362385
);
363-
let mut tx = env.write_txn()?;
364-
net.known_peers.delete(&mut tx, &peer_addr)?;
365-
tx.commit()?;
386+
net.remove_active_peer(env, peer_addr)?;
366387

367388
tracing::info!(
368389
%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)