@@ -12,10 +12,9 @@ use iroh::{Endpoint, NodeAddr, NodeId, PublicKey};
1212use iroh_blobs:: {
1313 api:: {
1414 blobs:: BlobStatus ,
15- downloader:: { DownloadRequest , Downloader } ,
15+ downloader:: { ContentDiscovery , DownloadRequest , Downloader , SplitStrategy } ,
1616 Store ,
1717 } ,
18- get:: Stats ,
1918 Hash , HashAndFormat ,
2019} ;
2120use iroh_gossip:: net:: Gossip ;
@@ -148,7 +147,7 @@ type SyncConnectRes = (
148147 Result < SyncFinished , ConnectError > ,
149148) ;
150149type SyncAcceptRes = Result < SyncFinished , AcceptError > ;
151- type DownloadRes = ( NamespaceId , Hash , Result < Stats , DownloadError > ) ;
150+ type DownloadRes = ( NamespaceId , Hash , Result < ( ) , anyhow :: Error > ) ;
152151
153152// Currently peers might double-sync in both directions.
154153pub struct LiveActor {
@@ -177,6 +176,8 @@ pub struct LiveActor {
177176 missing_hashes : HashSet < Hash > ,
178177 /// Content hashes queued in downloader.
179178 queued_hashes : QueuedHashes ,
179+ /// Nodes known to have a hash
180+ hash_providers : ProviderNodes ,
180181
181182 /// Subscribers to actor events
182183 subscribers : SubscribersMap ,
@@ -217,6 +218,7 @@ impl LiveActor {
217218 state : Default :: default ( ) ,
218219 missing_hashes : Default :: default ( ) ,
219220 queued_hashes : Default :: default ( ) ,
221+ hash_providers : Default :: default ( ) ,
220222 metrics,
221223 }
222224 }
@@ -629,7 +631,7 @@ impl LiveActor {
629631 }
630632 }
631633
632- async fn broadcast_neighbors ( & self , namespace : NamespaceId , op : & Op ) {
634+ async fn broadcast_neighbors ( & mut self , namespace : NamespaceId , op : & Op ) {
633635 if !self . state . is_syncing ( & namespace) {
634636 return ;
635637 }
@@ -651,7 +653,7 @@ impl LiveActor {
651653 & mut self ,
652654 namespace : NamespaceId ,
653655 hash : Hash ,
654- res : Result < Stats , DownloadError > ,
656+ res : Result < ( ) , anyhow :: Error > ,
655657 ) {
656658 let completed_namespaces = self . queued_hashes . remove_hash ( & hash) ;
657659 debug ! ( namespace=%namespace. fmt_short( ) , success=res. is_ok( ) , completed_namespaces=completed_namespaces. len( ) , "download ready" ) ;
@@ -758,12 +760,22 @@ impl LiveActor {
758760 self . missing_hashes . remove ( & hash) ;
759761 return ;
760762 }
763+ self . hash_providers
764+ . 0
765+ . lock ( )
766+ . expect ( "poisoned" )
767+ . entry ( hash)
768+ . or_default ( )
769+ . insert ( node) ;
761770 if self . queued_hashes . contains_hash ( & hash) {
762771 self . queued_hashes . insert ( hash, namespace) ;
763- self . downloader . nodes_have ( hash, vec ! [ node] ) . await ;
764772 } else if !only_if_missing || self . missing_hashes . contains ( & hash) {
765- let req = DownloadRequest :: new ( HashAndFormat :: raw ( hash) , vec ! [ node] ) ;
766- let handle = self . downloader . queue ( req) . await ;
773+ let req = DownloadRequest :: new (
774+ HashAndFormat :: raw ( hash) ,
775+ self . hash_providers . clone ( ) ,
776+ SplitStrategy :: None ,
777+ ) ;
778+ let handle = self . downloader . download_with_opts ( req) ;
767779
768780 self . queued_hashes . insert ( hash, namespace) ;
769781 self . missing_hashes . remove ( & hash) ;
@@ -885,6 +897,24 @@ struct QueuedHashes {
885897 by_namespace : HashMap < NamespaceId , HashSet < Hash > > ,
886898}
887899
900+ #[ derive( Debug , Clone , Default ) ]
901+ struct ProviderNodes ( Arc < std:: sync:: Mutex < HashMap < Hash , HashSet < NodeId > > > > ) ;
902+
903+ impl ContentDiscovery for ProviderNodes {
904+ fn find_providers ( & self , hash : HashAndFormat ) -> n0_future:: stream:: Boxed < NodeId > {
905+ let nodes = self
906+ . 0
907+ . lock ( )
908+ . expect ( "poisoned" )
909+ . get ( & hash. hash )
910+ . into_iter ( )
911+ . flatten ( )
912+ . cloned ( )
913+ . collect :: < Vec < _ > > ( ) ;
914+ Box :: pin ( n0_future:: stream:: iter ( nodes) )
915+ }
916+ }
917+
888918impl QueuedHashes {
889919 fn insert ( & mut self , hash : Hash , namespace : NamespaceId ) {
890920 self . by_hash . entry ( hash) . or_default ( ) . insert ( namespace) ;
0 commit comments