diff --git a/Cargo.lock b/Cargo.lock index 8f98a9ae83..794419adca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4267,9 +4267,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -4308,9 +4308,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", diff --git a/network/src/network.rs b/network/src/network.rs index bc19edf9ac..a3bd129079 100644 --- a/network/src/network.rs +++ b/network/src/network.rs @@ -1115,7 +1115,7 @@ impl NetworkService { let bootnodes = self.network_state.with_peer_store_mut(|peer_store| { let count = max((config.max_outbound_peers >> 1) as usize, 1); let mut addrs: Vec<_> = peer_store - .fetch_addrs_to_attempt(count, *target) + .fetch_addrs_to_attempt(count, *target, |_| true) .into_iter() .map(|paddr| paddr.addr) .collect(); diff --git a/network/src/peer_store/peer_store_impl.rs b/network/src/peer_store/peer_store_impl.rs index a8078b8877..f18c0e87c3 100644 --- a/network/src/peer_store/peer_store_impl.rs +++ b/network/src/peer_store/peer_store_impl.rs @@ -157,7 +157,15 @@ impl PeerStore { } /// Get peers for outbound connection, this method randomly return recently connected peer addrs - pub fn fetch_addrs_to_attempt(&mut self, count: usize, required_flags: Flags) -> Vec { + pub fn fetch_addrs_to_attempt( + &mut self, + count: usize, + required_flags: Flags, + filter: F, + ) -> Vec + where + F: Fn(&AddrInfo) -> bool, + { // Get info: // 1. Not already connected // 2. Connected within 3 days @@ -167,9 +175,10 @@ impl PeerStore { let addr_expired_ms = now_ms.saturating_sub(ADDR_TRY_TIMEOUT_MS); let filter = |peer_addr: &AddrInfo| { - extract_peer_id(&peer_addr.addr) - .map(|peer_id| !peers.contains_key(&peer_id)) - .unwrap_or_default() + filter(peer_addr) + && extract_peer_id(&peer_addr.addr) + .map(|peer_id| !peers.contains_key(&peer_id)) + .unwrap_or_default() && peer_addr .connected(|t| t > addr_expired_ms && t <= now_ms.saturating_sub(DIAL_INTERVAL)) && required_flags_filter(required_flags, Flags::from_bits_truncate(peer_addr.flags)) @@ -181,7 +190,10 @@ impl PeerStore { /// Get peers for feeler connection, this method randomly return peer addrs that we never /// connected to. - pub fn fetch_addrs_to_feeler(&mut self, count: usize) -> Vec { + pub fn fetch_addrs_to_feeler(&mut self, count: usize, filter: F) -> Vec + where + F: Fn(&AddrInfo) -> bool, + { // Get info: // 1. Not already connected // 2. Not already tried in a minute @@ -192,9 +204,10 @@ impl PeerStore { let peers = &self.connected_peers; let filter = |peer_addr: &AddrInfo| { - extract_peer_id(&peer_addr.addr) - .map(|peer_id| !peers.contains_key(&peer_id)) - .unwrap_or_default() + filter(peer_addr) + && extract_peer_id(&peer_addr.addr) + .map(|peer_id| !peers.contains_key(&peer_id)) + .unwrap_or_default() && !peer_addr.tried_in_last_minute(now_ms) && !peer_addr.connected(|t| t > addr_expired_ms) }; diff --git a/network/src/protocols/tests/mod.rs b/network/src/protocols/tests/mod.rs index 663ebf1dad..89b1276901 100644 --- a/network/src/protocols/tests/mod.rs +++ b/network/src/protocols/tests/mod.rs @@ -488,7 +488,7 @@ fn test_discovery_behavior() { let mut locked = node1.network_state.peer_store.lock(); locked - .fetch_addrs_to_feeler(6) + .fetch_addrs_to_feeler(6, |_| true) .into_iter() .map(|peer| peer.addr) .flat_map(|addr| { diff --git a/network/src/services/outbound_peer.rs b/network/src/services/outbound_peer.rs index 0836bbabbb..ff5c268d1f 100644 --- a/network/src/services/outbound_peer.rs +++ b/network/src/services/outbound_peer.rs @@ -55,8 +55,23 @@ impl OutboundPeerService { fn dial_feeler(&mut self) { let now_ms = unix_time_as_millis(); + let filter: Box bool> = match self.transport_type { + TransportType::Tcp => Box::new(|_| true), + TransportType::Ws => Box::new(|peer_addr: &AddrInfo| { + peer_addr + .addr + .iter() + .any(|p| matches!(p, Protocol::Dns4(_) | Protocol::Dns6(_) | Protocol::Tcp(_))) + }), + TransportType::Wss => Box::new(|peer_addr: &AddrInfo| { + peer_addr + .addr + .iter() + .any(|p| matches!(p, Protocol::Dns4(_) | Protocol::Dns6(_))) + }), + }; let attempt_peers = self.network_state.with_peer_store_mut(|peer_store| { - let paddrs = peer_store.fetch_addrs_to_feeler(FEELER_CONNECTION_COUNT); + let paddrs = peer_store.fetch_addrs_to_feeler(FEELER_CONNECTION_COUNT, filter); for paddr in paddrs.iter() { // mark addr as tried if let Some(paddr) = peer_store.mut_addr_manager().get_mut(&paddr.addr) { @@ -97,8 +112,24 @@ impl OutboundPeerService { let target = &self.network_state.required_flags; + let filter: Box bool> = match self.transport_type { + TransportType::Tcp => Box::new(|_| true), + TransportType::Ws => Box::new(|peer_addr: &AddrInfo| { + peer_addr + .addr + .iter() + .any(|p| matches!(p, Protocol::Dns4(_) | Protocol::Dns6(_) | Protocol::Tcp(_))) + }), + TransportType::Wss => Box::new(|peer_addr: &AddrInfo| { + peer_addr + .addr + .iter() + .any(|p| matches!(p, Protocol::Dns4(_) | Protocol::Dns6(_))) + }), + }; + let f = |peer_store: &mut PeerStore, number: usize, now_ms: u64| -> Vec { - let paddrs = peer_store.fetch_addrs_to_attempt(number, *target); + let paddrs = peer_store.fetch_addrs_to_attempt(number, *target, filter); for paddr in paddrs.iter() { // mark addr as tried if let Some(paddr) = peer_store.mut_addr_manager().get_mut(&paddr.addr) { diff --git a/network/src/tests/peer_store.rs b/network/src/tests/peer_store.rs index 85881b278e..1832315f02 100644 --- a/network/src/tests/peer_store.rs +++ b/network/src/tests/peer_store.rs @@ -31,17 +31,17 @@ fn test_add_addr() { let mut peer_store: PeerStore = Default::default(); assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 0 ); let addr = random_addr(); peer_store.add_addr(addr, Flags::COMPATIBILITY).unwrap(); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 1); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 1); // we have not connected yet, so return 0 assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 0 ); @@ -141,14 +141,14 @@ fn test_attempt_ban() { assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 1 ); peer_store.ban_addr(&addr, 10_000, "no reason".into()); assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 0 ); @@ -161,7 +161,7 @@ fn test_fetch_addrs_to_attempt() { let mut peer_store: PeerStore = Default::default(); assert!(peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .is_empty()); let addr = random_addr(); peer_store @@ -176,13 +176,13 @@ fn test_fetch_addrs_to_attempt() { assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 1 ); peer_store.add_connected_peer(addr, SessionType::Outbound); assert!(peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .is_empty()); } @@ -199,18 +199,18 @@ fn test_fetch_addrs_to_attempt_or_feeler() { assert_eq!( peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .len(), 1 ); - assert!(peer_store.fetch_addrs_to_feeler(2).is_empty()); + assert!(peer_store.fetch_addrs_to_feeler(2, |_| true).is_empty()); _faketime_guard.set_faketime(100_000 + ADDR_TRY_TIMEOUT_MS + 1); assert!(peer_store - .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(2, Flags::COMPATIBILITY, |_| true) .is_empty()); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 1); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 1); } #[test] @@ -229,14 +229,14 @@ fn test_fetch_addrs_to_attempt_in_last_minutes() { paddr.mark_tried(now); } assert!(peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .is_empty()); // after 60 seconds if let Some(paddr) = peer_store.mut_addr_manager().get_mut(&addr) { paddr.mark_tried(now - 60_001); } assert!(peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .is_empty()); peer_store .mut_addr_manager() @@ -247,7 +247,7 @@ fn test_fetch_addrs_to_attempt_in_last_minutes() { assert_eq!( peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .len(), 1 ); @@ -256,7 +256,7 @@ fn test_fetch_addrs_to_attempt_in_last_minutes() { } assert_eq!( peer_store - .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY) + .fetch_addrs_to_attempt(1, Flags::COMPATIBILITY, |_| true) .len(), 1 ); @@ -265,18 +265,18 @@ fn test_fetch_addrs_to_attempt_in_last_minutes() { #[test] fn test_fetch_addrs_to_feeler() { let mut peer_store: PeerStore = Default::default(); - assert!(peer_store.fetch_addrs_to_feeler(1).is_empty()); + assert!(peer_store.fetch_addrs_to_feeler(1, |_| true).is_empty()); let addr = random_addr(); // add an addr peer_store .add_addr(addr.clone(), Flags::COMPATIBILITY) .unwrap(); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 1); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 1); // ignores connected peers' addrs peer_store.add_connected_peer(addr.clone(), SessionType::Outbound); - assert!(peer_store.fetch_addrs_to_feeler(1).is_empty()); + assert!(peer_store.fetch_addrs_to_feeler(1, |_| true).is_empty()); // peer does not need feeler if it connected to us recently peer_store @@ -285,7 +285,7 @@ fn test_fetch_addrs_to_feeler() { .unwrap() .last_connected_at_ms = ckb_systemtime::unix_time_as_millis(); peer_store.remove_disconnected_peer(&addr); - assert!(peer_store.fetch_addrs_to_feeler(1).is_empty()); + assert!(peer_store.fetch_addrs_to_feeler(1, |_| true).is_empty()); } #[test] @@ -581,10 +581,10 @@ fn test_addr_unique() { .unwrap(); peer_store.add_addr(addr_1, Flags::COMPATIBILITY).unwrap(); assert_eq!(peer_store.addr_manager().addrs_iter().count(), 2); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 2); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 2); peer_store.add_addr(addr, Flags::COMPATIBILITY).unwrap(); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 2); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 2); assert_eq!(peer_store.addr_manager().addrs_iter().count(), 2); } @@ -597,8 +597,8 @@ fn test_only_tcp_store() { peer_store .add_addr(addr.clone(), Flags::COMPATIBILITY) .unwrap(); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 1); - assert_eq!(peer_store.fetch_addrs_to_feeler(1)[0].addr, { + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 1); + assert_eq!(peer_store.fetch_addrs_to_feeler(1, |_| true)[0].addr, { addr.pop(); addr }); @@ -618,6 +618,6 @@ fn test_support_dns_store() { peer_store .add_addr(addr.clone(), Flags::COMPATIBILITY) .unwrap(); - assert_eq!(peer_store.fetch_addrs_to_feeler(2).len(), 1); - assert_eq!(peer_store.fetch_addrs_to_feeler(1)[0].addr, addr); + assert_eq!(peer_store.fetch_addrs_to_feeler(2, |_| true).len(), 1); + assert_eq!(peer_store.fetch_addrs_to_feeler(1, |_| true)[0].addr, addr); }