@@ -25,18 +25,16 @@ use std::{
2525 collections:: { BTreeSet , HashMap } ,
2626 fmt,
2727 net:: IpAddr ,
28- num:: NonZeroUsize ,
2928 task:: { Context , Poll } ,
30- time:: Duration ,
29+ time:: { Duration , Instant } ,
3130} ;
3231
3332use futures:: StreamExt ;
3433use futures_ticker:: Ticker ;
35- use lru :: LruCache ;
34+ use hashlink :: LinkedHashMap ;
3635use prometheus_client:: registry:: Registry ;
3736use rand:: { seq:: SliceRandom , thread_rng} ;
3837
39- use instant:: Instant ;
4038use libp2p:: core:: { multiaddr:: Protocol :: Ip4 , multiaddr:: Protocol :: Ip6 , Endpoint , Multiaddr } ;
4139use libp2p:: identity:: Keypair ;
4240use libp2p:: identity:: PeerId ;
@@ -78,8 +76,11 @@ use std::{cmp::Ordering::Equal, fmt::Debug};
7876#[ cfg( test) ]
7977mod tests;
8078
81- /// IDONTWANT Cache capacity.
82- const IDONTWANT_CAP : usize = 100 ;
79+ /// IDONTWANT cache capacity.
80+ const IDONTWANT_CAP : usize = 10_000 ;
81+
82+ /// IDONTWANT timeout before removal.
83+ const IDONTWANT_TIMEOUT : Duration = Duration :: new ( 3 , 0 ) ;
8384
8485/// Determines if published messages should be signed or not.
8586///
@@ -1377,6 +1378,11 @@ where
13771378 "IWANT: Peer has asked for message too many times; ignoring request"
13781379 ) ;
13791380 } else if let Some ( peer) = & mut self . connected_peers . get_mut ( peer_id) {
1381+ if peer. dont_send . get ( & id) . is_some ( ) {
1382+ tracing:: debug!( %peer_id, message=%id, "Peer already sent IDONTWANT for this message" ) ;
1383+ continue ;
1384+ }
1385+
13801386 tracing:: debug!( peer=%peer_id, "IWANT: Sending cached messages to peer" ) ;
13811387 if peer
13821388 . sender
@@ -2485,6 +2491,17 @@ where
24852491 }
24862492 self . failed_messages . shrink_to_fit ( ) ;
24872493
2494+ // Clear stale IDONTWANTs.
2495+ for peer in self . connected_peers . values_mut ( ) {
2496+ while let Some ( ( _front, instant) ) = peer. dont_send . front ( ) {
2497+ if ( * instant + IDONTWANT_TIMEOUT ) >= Instant :: now ( ) {
2498+ break ;
2499+ } else {
2500+ peer. dont_send . pop_front ( ) ;
2501+ }
2502+ }
2503+ }
2504+
24882505 tracing:: debug!( "Completed Heartbeat" ) ;
24892506 if let Some ( metrics) = self . metrics . as_mut ( ) {
24902507 let duration = u64:: try_from ( start. elapsed ( ) . as_millis ( ) ) . unwrap_or ( u64:: MAX ) ;
@@ -2677,9 +2694,18 @@ where
26772694 return ;
26782695 } ;
26792696
2680- let recipient_peers = mesh_peers. iter ( ) . filter ( |peer_id| {
2681- * peer_id != propagation_source && Some ( * peer_id) != message. source . as_ref ( )
2682- } ) ;
2697+ let iwant_peers = self
2698+ . peer_score
2699+ . as_ref ( )
2700+ . map ( |( _peer_score, .., gossip_promises) | gossip_promises. peers_for_message ( msg_id) )
2701+ . unwrap_or ( vec ! [ ] ) ;
2702+
2703+ let recipient_peers = mesh_peers
2704+ . iter ( )
2705+ . chain ( iwant_peers. iter ( ) )
2706+ . filter ( |peer_id| {
2707+ * peer_id != propagation_source && Some ( * peer_id) != message. source . as_ref ( )
2708+ } ) ;
26832709
26842710 for peer_id in recipient_peers {
26852711 let Some ( peer) = self . connected_peers . get_mut ( peer_id) else {
@@ -3121,7 +3147,7 @@ where
31213147 connections : vec ! [ ] ,
31223148 sender : RpcSender :: new ( self . config . connection_handler_queue_len ( ) ) ,
31233149 topics : Default :: default ( ) ,
3124- dont_send : LruCache :: new ( NonZeroUsize :: new ( IDONTWANT_CAP ) . unwrap ( ) ) ,
3150+ dont_send : LinkedHashMap :: new ( ) ,
31253151 } ) ;
31263152 // Add the new connection
31273153 connected_peer. connections . push ( connection_id) ;
@@ -3152,7 +3178,7 @@ where
31523178 connections : vec ! [ ] ,
31533179 sender : RpcSender :: new ( self . config . connection_handler_queue_len ( ) ) ,
31543180 topics : Default :: default ( ) ,
3155- dont_send : LruCache :: new ( NonZeroUsize :: new ( IDONTWANT_CAP ) . unwrap ( ) ) ,
3181+ dont_send : LinkedHashMap :: new ( ) ,
31563182 } ) ;
31573183 // Add the new connection
31583184 connected_peer. connections . push ( connection_id) ;
@@ -3319,7 +3345,11 @@ where
33193345 continue ;
33203346 } ;
33213347 for message_id in message_ids {
3322- peer. dont_send . push ( message_id, ( ) ) ;
3348+ peer. dont_send . insert ( message_id, Instant :: now ( ) ) ;
3349+ // Don't exceed capacity.
3350+ if peer. dont_send . len ( ) > IDONTWANT_CAP {
3351+ peer. dont_send . pop_front ( ) ;
3352+ }
33233353 }
33243354 }
33253355 }
0 commit comments