@@ -29,7 +29,6 @@ use crate::{
2929 handle:: KademliaCommand ,
3030 message:: KademliaMessage ,
3131 query:: { QueryAction , QueryEngine } ,
32- record:: ProviderRecord ,
3332 routing_table:: RoutingTable ,
3433 store:: { MemoryStore , MemoryStoreAction , MemoryStoreConfig } ,
3534 types:: { ConnectionType , KademliaPeer , Key } ,
@@ -61,7 +60,7 @@ pub use handle::{
6160 IncomingRecordValidationMode , KademliaEvent , KademliaHandle , Quorum , RoutingTableUpdateMode ,
6261} ;
6362pub use query:: QueryId ;
64- pub use record:: { Key as RecordKey , PeerRecord , Record } ;
63+ pub use record:: { ContentProvider , Key as RecordKey , PeerRecord , Record } ;
6564
6665/// Logging target for the file.
6766const LOG_TARGET : & str = "litep2p::ipfs::kademlia" ;
@@ -165,9 +164,6 @@ pub(crate) struct Kademlia {
165164 /// Default record TTL.
166165 record_ttl : Duration ,
167166
168- /// Provider record TTL.
169- provider_ttl : Duration ,
170-
171167 /// Query engine.
172168 engine : QueryEngine ,
173169
@@ -193,6 +189,7 @@ impl Kademlia {
193189 local_peer_id,
194190 MemoryStoreConfig {
195191 provider_refresh_interval : config. provider_refresh_interval ,
192+ provider_ttl : config. provider_ttl ,
196193 ..Default :: default ( )
197194 } ,
198195 ) ;
@@ -212,7 +209,6 @@ impl Kademlia {
212209 update_mode : config. update_mode ,
213210 validation_mode : config. validation_mode ,
214211 record_ttl : config. record_ttl ,
215- provider_ttl : config. provider_ttl ,
216212 replication_factor : config. replication_factor ,
217213 engine : QueryEngine :: new ( local_peer_id, config. replication_factor , PARALLELISM_FACTOR ) ,
218214 }
@@ -523,7 +519,7 @@ impl Kademlia {
523519 ) ,
524520 }
525521 }
526- KademliaMessage :: AddProvider { key, providers } => {
522+ KademliaMessage :: AddProvider { key, mut providers } => {
527523 tracing:: trace!(
528524 target: LOG_TARGET ,
529525 ?peer,
@@ -532,15 +528,27 @@ impl Kademlia {
532528 "handle `ADD_PROVIDER` message" ,
533529 ) ;
534530
535- match ( providers. len ( ) , providers. first ( ) ) {
531+ match ( providers. len ( ) , providers. pop ( ) ) {
536532 ( 1 , Some ( provider) ) =>
537533 if provider. peer == peer {
538- self . store . put_provider ( ProviderRecord {
539- key,
540- provider : peer,
541- addresses : provider. addresses . clone ( ) ,
542- expires : Instant :: now ( ) + self . provider_ttl ,
543- } ) ;
534+ self . store . put_provider (
535+ key. clone ( ) ,
536+ ContentProvider {
537+ peer,
538+ addresses : provider. addresses . clone ( ) ,
539+ } ,
540+ ) ;
541+
542+ let _ = self
543+ . event_tx
544+ . send ( KademliaEvent :: IncomingProvider {
545+ provided_key : key,
546+ provider : ContentProvider {
547+ peer : provider. peer ,
548+ addresses : provider. addresses ,
549+ } ,
550+ } )
551+ . await ;
544552 } else {
545553 tracing:: trace!(
546554 target: LOG_TARGET ,
@@ -590,10 +598,13 @@ impl Kademlia {
590598 "handle `GET_PROVIDERS` request" ,
591599 ) ;
592600
593- let providers = self . store . get_providers ( key) ;
594- // TODO: if local peer is among the providers, update its `ProviderRecord`
595- // to have up-to-date addresses.
596- // Requires https://github.com/paritytech/litep2p/issues/211.
601+ let mut providers = self . store . get_providers ( key) ;
602+
603+ // Make sure local provider addresses are up to date.
604+ let local_peer_id = self . local_key . clone ( ) . into_preimage ( ) ;
605+ providers. iter_mut ( ) . find ( |p| p. peer == local_peer_id) . as_mut ( ) . map ( |p| {
606+ p. addresses = self . service . public_addresses ( ) . get_addresses ( ) ;
607+ } ) ;
597608
598609 let closer_peers = self
599610 . routing_table
@@ -787,16 +798,19 @@ impl Kademlia {
787798
788799 Ok ( ( ) )
789800 }
790- QueryAction :: AddProviderToFoundNodes { provider, peers } => {
801+ QueryAction :: AddProviderToFoundNodes {
802+ provided_key,
803+ provider,
804+ peers,
805+ } => {
791806 tracing:: trace!(
792807 target: LOG_TARGET ,
793- provided_key = ?provider . key ,
808+ ?provided_key ,
794809 num_peers = ?peers. len( ) ,
795810 "add provider record to found peers" ,
796811 ) ;
797812
798- let provided_key = provider. key . clone ( ) ;
799- let message = KademliaMessage :: add_provider ( provider) ;
813+ let message = KademliaMessage :: add_provider ( provided_key. clone ( ) , provider) ;
800814
801815 for peer in peers {
802816 if let Err ( error) = self . open_substream_or_dial (
@@ -828,12 +842,14 @@ impl Kademlia {
828842 }
829843 QueryAction :: GetProvidersQueryDone {
830844 query_id,
845+ provided_key,
831846 providers,
832847 } => {
833848 let _ = self
834849 . event_tx
835850 . send ( KademliaEvent :: GetProvidersSuccess {
836851 query_id,
852+ provided_key,
837853 providers,
838854 } )
839855 . await ;
@@ -1036,28 +1052,26 @@ impl Kademlia {
10361052 }
10371053 Some ( KademliaCommand :: StartProviding {
10381054 key,
1039- public_addresses,
10401055 query_id
10411056 } ) => {
10421057 tracing:: debug!(
10431058 target: LOG_TARGET ,
10441059 query = ?query_id,
10451060 ?key,
1046- ?public_addresses,
10471061 "register as a content provider" ,
10481062 ) ;
10491063
1050- let provider = ProviderRecord {
1051- key: key. clone( ) ,
1052- provider: self . service. local_peer_id( ) ,
1053- addresses: public_addresses,
1054- expires: Instant :: now( ) + self . provider_ttl,
1064+ let addresses = self . service. public_addresses( ) . get_addresses( ) ;
1065+ let provider = ContentProvider {
1066+ peer: self . service. local_peer_id( ) ,
1067+ addresses,
10551068 } ;
10561069
1057- self . store. put_provider( provider. clone( ) ) ;
1070+ self . store. put_provider( key . clone ( ) , provider. clone( ) ) ;
10581071
10591072 self . engine. start_add_provider(
10601073 query_id,
1074+ key. clone( ) ,
10611075 provider,
10621076 self . routing_table
10631077 . closest( Key :: new( key) , self . replication_factor)
@@ -1105,12 +1119,15 @@ impl Kademlia {
11051119 Some ( KademliaCommand :: GetProviders { key, query_id } ) => {
11061120 tracing:: debug!( target: LOG_TARGET , ?key, "get providers from DHT" ) ;
11071121
1122+ let known_providers = self . store. get_providers( & key) ;
1123+
11081124 self . engine. start_get_providers(
11091125 query_id,
11101126 key. clone( ) ,
11111127 self . routing_table
11121128 . closest( Key :: new( key) , self . replication_factor)
11131129 . into( ) ,
1130+ known_providers,
11141131 ) ;
11151132 }
11161133 Some ( KademliaCommand :: AddKnownPeer { peer, addresses } ) => {
@@ -1151,25 +1168,24 @@ impl Kademlia {
11511168 }
11521169 } ,
11531170 action = self . store. next_action( ) => match action {
1154- Some ( MemoryStoreAction :: RefreshProvider { mut provider } ) => {
1171+ Some ( MemoryStoreAction :: RefreshProvider { provided_key , provider } ) => {
11551172 tracing:: trace!(
11561173 target: LOG_TARGET ,
1157- key = ?provider . key ,
1174+ ?provided_key ,
11581175 "republishing local provider" ,
11591176 ) ;
11601177
1161- // Make sure to roll expiration time.
1162- provider. expires = Instant :: now( ) + self . provider_ttl;
1163-
1164- self . store. put_provider( provider. clone( ) ) ;
1178+ self . store. put_provider( provided_key. clone( ) , provider. clone( ) ) ;
1179+ // We never update local provider addresses in the store when refresh
1180+ // it, as this is done anyway when replying to `GET_PROVIDERS` request.
11651181
1166- let key = provider. key. clone( ) ;
11671182 let query_id = self . next_query_id( ) ;
11681183 self . engine. start_add_provider(
11691184 query_id,
1185+ provided_key. clone( ) ,
11701186 provider,
11711187 self . routing_table
1172- . closest( Key :: new( key ) , self . replication_factor)
1188+ . closest( Key :: new( provided_key ) , self . replication_factor)
11731189 . into( ) ,
11741190 ) ;
11751191 }
0 commit comments