diff --git a/src/net/hosts/store.rs b/src/net/hosts/store.rs index 09bd9de87..b59d47784 100644 --- a/src/net/hosts/store.rs +++ b/src/net/hosts/store.rs @@ -950,6 +950,31 @@ impl Hosts { urls.iter().map(|&url| url.clone()).collect() } + /// Get up to n random anchorlist peers that match the given transport schemes. + pub async fn anchorlist_fetch_n_random_with_schemes( + &self, + schemes: &[String], + n: u32, + ) -> Vec<(Url, u64)> { + let n = n as usize; + if n == 0 { + return vec![] + } + trace!(target: "store::anchorlist_fetch_n_random_with_schemes", "[START]"); + + // Retrieve all peers corresponding to that transport schemes + let hosts = self.anchorlist_fetch_with_schemes(schemes, None).await; + if hosts.is_empty() { + debug!(target: "store::anchorlist_fetch_n_random_with_schemes", + "No such schemes found on anchorlist!"); + return hosts + } + + // Grab random ones + let urls = hosts.iter().choose_multiple(&mut OsRng, n.min(hosts.len())); + urls.iter().map(|&url| url.clone()).collect() + } + /// Get up to limit peers that don't match the given transport schemes from the greylist. /// If limit was not provided, return all matching peers. pub async fn greylist_fetch_excluding_schemes( diff --git a/src/net/protocol/protocol_address.rs b/src/net/protocol/protocol_address.rs index 70db20b0b..4b83e4e06 100644 --- a/src/net/protocol/protocol_address.rs +++ b/src/net/protocol/protocol_address.rs @@ -44,14 +44,17 @@ use crate::Result; /// The node selection logic for creating an AddrMessage is as follows: /// /// 1. First select nodes matching the requested transports from the -/// whitelist. These nodes have a high guarantee of being reachable, so we +/// anchorlist. These nodes have the highest guarantee of being reachable, so we /// prioritize them first. /// -/// 2. Then select whitelist nodes that don't match our transports. We do +/// 2. Then select nodes matching the requested transports from the +/// whitelist. +/// +/// 3. Next select whitelist nodes that don't match our transports. We do /// this so that nodes share and propagate nodes of different transports, /// even if they can't connect to them themselves. /// -/// 3. Finally, if there's still space available, fill the remaining vector +/// 4. Finally, if there's still space available, fill the remaining vector /// space with greylist entries. This is necessary in case this node does /// not support the transports of the requesting node (non-supported /// transports are stored on the greylist). @@ -149,15 +152,30 @@ impl ProtocolAddress { continue } - // First we grab address with the requested transports + // First we grab address with the requested transports from the anchorlist debug!(target: "net::protocol_address::handle_receive_get_addrs()", - "Fetching whitelist entries with schemes"); + "Fetching anchorlist entries with schemes"); let mut addrs = self .hosts - .whitelist_fetch_n_random_with_schemes(&get_addrs_msg.transports, get_addrs_msg.max) + .anchorlist_fetch_n_random_with_schemes( + &get_addrs_msg.transports, + get_addrs_msg.max, + ) .await; - // Then we grab addresses without the requested transports + // Then we grab address with the requested transports from the whitelist + debug!(target: "net::protocol_address::handle_receive_get_addrs()", + "Fetching whitelist entries with schemes"); + addrs.append( + &mut self.hosts + .whitelist_fetch_n_random_with_schemes( + &get_addrs_msg.transports, + get_addrs_msg.max, + ) + .await, + ); + + // Next we grab addresses without the requested transports // to fill a 2 * max length vector. debug!(target: "net::protocol_address::handle_receive_get_addrs()", "Fetching whitelist entries without schemes");