@@ -55,7 +55,7 @@ pub struct Behaviour {
5555 ///
5656 /// Storing these internally allows us to assist the [`libp2p_swarm::Swarm`] in dialing by
5757 /// returning addresses from [`NetworkBehaviour::handle_pending_outbound_connection`].
58- discovered_peers : HashMap < ( PeerId , Namespace ) , Vec < Multiaddr > > ,
58+ discovered_peers : HashMap < PeerId , HashMap < Namespace , Vec < Multiaddr > > > ,
5959
6060 registered_namespaces : HashMap < ( PeerId , Namespace ) , Ttl > ,
6161
@@ -310,13 +310,17 @@ impl NetworkBehaviour for Behaviour {
310310 Poll :: Pending => { }
311311 }
312312
313- if let Poll :: Ready ( Some ( expired_registration) ) =
313+ if let Poll :: Ready ( Some ( ( peer , expired_registration) ) ) =
314314 self . expiring_registrations . poll_next_unpin ( cx)
315315 {
316- self . discovered_peers . remove ( & expired_registration) ;
317- return Poll :: Ready ( ToSwarm :: GenerateEvent ( Event :: Expired {
318- peer : expired_registration. 0 ,
319- } ) ) ;
316+ let Some ( registrations) = self . discovered_peers . get_mut ( & peer) else {
317+ continue ;
318+ } ;
319+ registrations. remove ( & expired_registration) ;
320+ if registrations. is_empty ( ) {
321+ self . discovered_peers . remove ( & peer) ;
322+ }
323+ return Poll :: Ready ( ToSwarm :: GenerateEvent ( Event :: Expired { peer } ) ) ;
320324 }
321325
322326 return Poll :: Pending ;
@@ -330,20 +334,10 @@ impl NetworkBehaviour for Behaviour {
330334 _addresses : & [ Multiaddr ] ,
331335 _effective_role : Endpoint ,
332336 ) -> Result < Vec < Multiaddr > , ConnectionDenied > {
333- let peer = match maybe_peer {
334- None => return Ok ( vec ! [ ] ) ,
335- Some ( peer) => peer,
336- } ;
337-
338- let addresses = self
339- . discovered_peers
340- . iter ( )
341- . filter_map ( |( ( candidate, _) , addresses) | ( candidate == & peer) . then_some ( addresses) )
342- . flatten ( )
343- . cloned ( )
344- . collect ( ) ;
345-
346- Ok ( addresses)
337+ let addrs = maybe_peer
338+ . map ( |peer| self . discovered_peer_addrs ( & peer) . cloned ( ) . collect ( ) )
339+ . unwrap_or_default ( ) ;
340+ Ok ( addrs)
347341 }
348342}
349343
@@ -375,101 +369,86 @@ impl Behaviour {
375369 ) -> Option < Event > {
376370 match response {
377371 RegisterResponse ( Ok ( ttl) ) => {
378- if let Some ( ( rendezvous_node, namespace) ) =
379- self . waiting_for_register . remove ( request_id)
380- {
381- self . registered_namespaces
382- . insert ( ( rendezvous_node, namespace. clone ( ) ) , ttl) ;
383-
384- return Some ( Event :: Registered {
385- rendezvous_node,
386- ttl,
387- namespace,
388- } ) ;
389- }
390-
391- None
372+ let ( rendezvous_node, namespace) = self . waiting_for_register . remove ( request_id) ?;
373+ self . registered_namespaces
374+ . insert ( ( rendezvous_node, namespace. clone ( ) ) , ttl) ;
375+
376+ Some ( Event :: Registered {
377+ rendezvous_node,
378+ ttl,
379+ namespace,
380+ } )
392381 }
393382 RegisterResponse ( Err ( error_code) ) => {
394- if let Some ( ( rendezvous_node, namespace) ) =
395- self . waiting_for_register . remove ( request_id)
396- {
397- return Some ( Event :: RegisterFailed {
398- rendezvous_node,
399- namespace,
400- error : error_code,
401- } ) ;
402- }
403-
404- None
383+ let ( rendezvous_node, namespace) = self . waiting_for_register . remove ( request_id) ?;
384+ Some ( Event :: RegisterFailed {
385+ rendezvous_node,
386+ namespace,
387+ error : error_code,
388+ } )
405389 }
406390 DiscoverResponse ( Ok ( ( registrations, cookie) ) ) => {
407- if let Some ( ( rendezvous_node, _ns) ) = self . waiting_for_discovery . remove ( request_id)
408- {
409- self . events
410- . extend ( registrations. iter ( ) . flat_map ( |registration| {
411- let peer_id = registration. record . peer_id ( ) ;
412- registration
413- . record
414- . addresses ( )
415- . iter ( )
416- . filter ( |addr| {
417- !self . discovered_peers . iter ( ) . any (
418- |( ( discovered_peer_id, _) , addrs) | {
419- * discovered_peer_id == peer_id && addrs. contains ( addr)
420- } ,
421- )
422- } )
423- . map ( |address| ToSwarm :: NewExternalAddrOfPeer {
424- peer_id,
425- address : address. clone ( ) ,
426- } )
427- . collect :: < Vec < _ > > ( )
428- } ) ) ;
429-
430- self . discovered_peers
431- . extend ( registrations. iter ( ) . map ( |registration| {
432- let peer_id = registration. record . peer_id ( ) ;
433- let namespace = registration. namespace . clone ( ) ;
434-
435- let addresses = registration. record . addresses ( ) . to_vec ( ) ;
436-
437- ( ( peer_id, namespace) , addresses)
438- } ) ) ;
439-
440- self . expiring_registrations
441- . extend ( registrations. iter ( ) . cloned ( ) . map ( |registration| {
442- async move {
443- // if the timer errors we consider it expired
444- futures_timer:: Delay :: new ( Duration :: from_secs ( registration. ttl ) )
445- . await ;
446-
447- ( registration. record . peer_id ( ) , registration. namespace )
391+ let ( rendezvous_node, _ns) = self . waiting_for_discovery . remove ( request_id) ?;
392+ registrations. iter ( ) . for_each ( |registration| {
393+ let peer_id = registration. record . peer_id ( ) ;
394+ let addresses = registration. record . addresses ( ) ;
395+ let namespace = registration. namespace . clone ( ) ;
396+ let ttl = registration. ttl ;
397+
398+ // Emit events for all newly discovered addresses.
399+ let new_addr_events = addresses
400+ . iter ( )
401+ . filter_map ( |address| {
402+ if self . discovered_peer_addrs ( & peer_id) . any ( |a| a == address) {
403+ return None ;
448404 }
449- . boxed ( )
450- } ) ) ;
451-
452- return Some ( Event :: Discovered {
453- rendezvous_node,
454- registrations,
455- cookie,
456- } ) ;
457- }
458-
459- None
405+ Some ( ToSwarm :: NewExternalAddrOfPeer {
406+ peer_id,
407+ address : address. clone ( ) ,
408+ } )
409+ } )
410+ . collect :: < Vec < _ > > ( ) ;
411+ self . events . extend ( new_addr_events) ;
412+
413+ // Update list of discovered peers.
414+ self . discovered_peers
415+ . entry ( peer_id)
416+ . or_default ( )
417+ . insert ( namespace. clone ( ) , addresses. to_owned ( ) ) ;
418+
419+ // Push registration expiry future.
420+ self . expiring_registrations . push (
421+ async move {
422+ // if the timer errors we consider it expired
423+ futures_timer:: Delay :: new ( Duration :: from_secs ( ttl) ) . await ;
424+ ( peer_id, namespace)
425+ }
426+ . boxed ( ) ,
427+ ) ;
428+ } ) ;
429+
430+ Some ( Event :: Discovered {
431+ rendezvous_node,
432+ registrations,
433+ cookie,
434+ } )
460435 }
461436 DiscoverResponse ( Err ( error_code) ) => {
462- if let Some ( ( rendezvous_node, ns) ) = self . waiting_for_discovery . remove ( request_id) {
463- return Some ( Event :: DiscoverFailed {
464- rendezvous_node,
465- namespace : ns,
466- error : error_code,
467- } ) ;
468- }
469-
470- None
437+ let ( rendezvous_node, ns) = self . waiting_for_discovery . remove ( request_id) ?;
438+ Some ( Event :: DiscoverFailed {
439+ rendezvous_node,
440+ namespace : ns,
441+ error : error_code,
442+ } )
471443 }
472444 _ => unreachable ! ( "rendezvous clients never receive requests" ) ,
473445 }
474446 }
447+
448+ fn discovered_peer_addrs ( & self , peer : & PeerId ) -> impl Iterator < Item = & Multiaddr > {
449+ self . discovered_peers
450+ . get ( peer)
451+ . map ( |addrs| addrs. values ( ) . flatten ( ) )
452+ . unwrap_or_default ( )
453+ }
475454}
0 commit comments