Skip to content

Commit

Permalink
feat: not dial back for peers in full kbucket
Browse files Browse the repository at this point in the history
  • Loading branch information
maqi authored and joshuef committed Dec 5, 2023
1 parent 8174150 commit a1e69fa
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
8 changes: 3 additions & 5 deletions sn_networking/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,9 @@ impl NetworkBuilder {
pending_get_closest_peers: Default::default(),
pending_requests: Default::default(),
pending_get_record: Default::default(),
// We use 63 here, as in practice the capacity will be rounded to the nearest 2^n-1.
// Source: https://users.rust-lang.org/t/the-best-ring-buffer-library/58489/8
// 63 will mean at least 63 most recent peers we have dialed, which should be allow for enough time for the
// `identify` protocol to kick in and get them in the routing table.
dialed_peers: CircularVec::new(63),
// We use 255 here which allows covering a network larger than 64k without any rotating.
// This is based on the libp2p kad::kBuckets peers distribution.
dialed_peers: CircularVec::new(255),
is_gossip_handler: false,
network_discovery: NetworkDiscovery::new(&peer_id),
};
Expand Down
31 changes: 23 additions & 8 deletions sn_networking/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,19 +271,34 @@ impl SwarmDriver {
// The dial shall trigger the same identify to be sent again and confirm
// peer is external accessable, hence safe to be added into RT.
if !self.local && peer_is_agent && !has_dialed {
info!(%peer_id, ?addrs, "not dailed but received identify info, dailed back to confirm external accesable");
if let Err(err) = self.swarm.dial(
DialOpts::peer_id(peer_id)
.condition(PeerCondition::NotDialing)
.addresses(addrs.iter().cloned().collect())
.build(),
) {
warn!(%peer_id, ?addrs, "dialing error: {err:?}");
// Only need to dial back for not fulfilled kbucket
let (kbucket_full, ilog2) = if let Some(kbucket) =
self.swarm.behaviour_mut().kademlia.kbucket(peer_id)
{
let ilog2 = kbucket.range().0.ilog2();
let num_peers = kbucket.num_entries();
(num_peers >= K_VALUE.into(), ilog2)
} else {
// Function will return `None` if the given key refers to self
// hence return true to skip further action.
(true, None)
};

if !kbucket_full {
info!(%peer_id, ?addrs, "received identify info from undialed peer for not full kbucket {:?}, dail back to confirm external accesable", ilog2);
self.dialed_peers
.push(peer_id)
.map_err(|_| Error::CircularVecPopFrontError)?;
if let Err(err) = self.swarm.dial(
DialOpts::peer_id(peer_id)
.condition(PeerCondition::NotDialing)
.addresses(addrs.iter().cloned().collect())
.build(),
) {
warn!(%peer_id, ?addrs, "dialing error: {err:?}");
}
}

trace!(
"SwarmEvent handled in {:?}: {event_string:?}",
start.elapsed()
Expand Down

0 comments on commit a1e69fa

Please sign in to comment.