From 3d3df2628d4dd1286419156e4ee69b6213fdca23 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 3 Sep 2024 14:21:11 +0300 Subject: [PATCH 1/4] kad: Avoid cloning for `KademliaMessage::FindNode` Signed-off-by: Alexandru Vasile --- src/protocol/libp2p/kademlia/mod.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index ea157ea1..fde0ba4b 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -394,10 +394,7 @@ impl Kademlia { tracing::trace!(target: LOG_TARGET, ?peer, query = ?query_id, "handle message from peer"); match KademliaMessage::from_bytes(message).ok_or(Error::InvalidData)? { - ref message @ KademliaMessage::FindNode { - ref target, - ref peers, - } => { + KademliaMessage::FindNode { target, peers } => { match query_id { Some(query_id) => { tracing::trace!( @@ -409,8 +406,12 @@ impl Kademlia { ); // update routing table and inform user about the update - self.update_routing_table(peers).await; - self.engine.register_response(query_id, peer, message.clone()); + self.update_routing_table(&peers).await; + self.engine.register_response( + query_id, + peer, + KademliaMessage::FindNode { target, peers }, + ); } None => { tracing::trace!( @@ -421,9 +422,9 @@ impl Kademlia { ); let message = KademliaMessage::find_node_response( - target, + &target, self.routing_table - .closest(Key::from(target.clone()), self.replication_factor), + .closest(Key::new(target.as_ref()), self.replication_factor), ); self.executor.send_message(peer, message.into(), substream); } From 4d1d5e3593e3dab413137e3429f803e6a1d57c3b Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 3 Sep 2024 14:26:40 +0300 Subject: [PATCH 2/4] kad: Avoid cloning for `KademliaMessage::GetRecord` Signed-off-by: Alexandru Vasile --- src/protocol/libp2p/kademlia/mod.rs | 30 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index fde0ba4b..cf93ff5a 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -444,13 +444,9 @@ impl Kademlia { let _ = self.event_tx.send(KademliaEvent::IncomingRecord { record }).await; } - ref message @ KademliaMessage::GetRecord { - ref key, - ref record, - ref peers, - } => { + KademliaMessage::GetRecord { key, record, peers } => { match (query_id, key) { - (Some(query_id), _) => { + (Some(query_id), key) => { tracing::trace!( target: LOG_TARGET, ?peer, @@ -461,8 +457,12 @@ impl Kademlia { ); // update routing table and inform user about the update - self.update_routing_table(peers).await; - self.engine.register_response(query_id, peer, message.clone()); + self.update_routing_table(&peers).await; + self.engine.register_response( + query_id, + peer, + KademliaMessage::GetRecord { key, record, peers }, + ); } (None, Some(key)) => { tracing::trace!( @@ -472,22 +472,20 @@ impl Kademlia { "handle `GET_VALUE` request", ); - let value = self.store.get(key).cloned(); + let value = self.store.get(&key).cloned(); let closest_peers = self .routing_table - .closest(Key::from(key.to_vec()), self.replication_factor); + .closest(Key::new(key.as_ref()), self.replication_factor); - let message = KademliaMessage::get_value_response( - (*key).clone(), - closest_peers, - value, - ); + let message = + KademliaMessage::get_value_response(key, closest_peers, value); self.executor.send_message(peer, message.into(), substream); } (None, None) => tracing::debug!( target: LOG_TARGET, ?peer, - ?message, + ?record, + ?peers, "unable to handle `GET_RECORD` request with empty key", ), } From fd2b7f809658bebf97658860d3351471341e11e7 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 3 Sep 2024 14:31:03 +0300 Subject: [PATCH 3/4] kad: Avoid cloning for `KademliaMessage::GetProviders` Signed-off-by: Alexandru Vasile --- src/protocol/libp2p/kademlia/mod.rs | 34 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index cf93ff5a..c7ce478b 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -526,10 +526,10 @@ impl Kademlia { } } } - ref message @ KademliaMessage::GetProviders { - ref key, - ref peers, - ref providers, + KademliaMessage::GetProviders { + key, + peers, + providers, } => { match (query_id, key) { (Some(query_id), key) => { @@ -545,9 +545,17 @@ impl Kademlia { ); // update routing table and inform user about the update - self.update_routing_table(peers).await; + self.update_routing_table(&peers).await; - self.engine.register_response(query_id, peer, message.clone()); + self.engine.register_response( + query_id, + peer, + KademliaMessage::GetProviders { + key, + peers, + providers, + }, + ); } (None, Some(key)) => { tracing::trace!( @@ -557,26 +565,24 @@ impl Kademlia { "handle `GET_PROVIDERS` request", ); - let providers = self.store.get_providers(key); + let providers = self.store.get_providers(&key); // TODO: if local peer is among the providers, update its `ProviderRecord` // to have up-to-date addresses. // Requires https://github.com/paritytech/litep2p/issues/211. let closer_peers = self .routing_table - .closest(Key::from(key.to_vec()), self.replication_factor); + .closest(Key::new(key.as_ref()), self.replication_factor); - let message = KademliaMessage::get_providers_response( - key.clone(), - providers, - &closer_peers, - ); + let message = + KademliaMessage::get_providers_response(key, providers, &closer_peers); self.executor.send_message(peer, message.into(), substream); } (None, None) => tracing::debug!( target: LOG_TARGET, ?peer, - ?message, + ?peers, + ?providers, "unable to handle `GET_PROVIDERS` request with empty key", ), } From 82a9bbed4a6cac94b5f605211194ea018d5810b1 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 3 Sep 2024 14:35:40 +0300 Subject: [PATCH 4/4] kad: Pass reference to key as parameter to closest fn Signed-off-by: Alexandru Vasile --- src/protocol/libp2p/kademlia/mod.rs | 12 ++++++------ src/protocol/libp2p/kademlia/routing_table.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index c7ce478b..d3c4b3ef 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -424,7 +424,7 @@ impl Kademlia { let message = KademliaMessage::find_node_response( &target, self.routing_table - .closest(Key::new(target.as_ref()), self.replication_factor), + .closest(&Key::new(target.as_ref()), self.replication_factor), ); self.executor.send_message(peer, message.into(), substream); } @@ -475,7 +475,7 @@ impl Kademlia { let value = self.store.get(&key).cloned(); let closest_peers = self .routing_table - .closest(Key::new(key.as_ref()), self.replication_factor); + .closest(&Key::new(key.as_ref()), self.replication_factor); let message = KademliaMessage::get_value_response(key, closest_peers, value); @@ -572,7 +572,7 @@ impl Kademlia { let closer_peers = self .routing_table - .closest(Key::new(key.as_ref()), self.replication_factor); + .closest(&Key::new(key.as_ref()), self.replication_factor); let message = KademliaMessage::get_providers_response(key, providers, &closer_peers); @@ -863,7 +863,7 @@ impl Kademlia { self.engine.start_find_node( query_id, peer, - self.routing_table.closest(Key::from(peer), self.replication_factor).into() + self.routing_table.closest(&Key::from(peer), self.replication_factor).into() ); } Some(KademliaCommand::PutRecord { mut record, query_id }) => { @@ -882,7 +882,7 @@ impl Kademlia { self.engine.start_put_record( query_id, record, - self.routing_table.closest(key, self.replication_factor).into(), + self.routing_table.closest(&key, self.replication_factor).into(), ); } Some(KademliaCommand::PutRecordToPeers { mut record, query_id, peers, update_local_store }) => { @@ -928,7 +928,7 @@ impl Kademlia { self.engine.start_get_record( query_id, key.clone(), - self.routing_table.closest(Key::new(key.clone()), self.replication_factor).into(), + self.routing_table.closest(&Key::new(key.clone()), self.replication_factor).into(), quorum, if record.is_some() { 1 } else { 0 }, ); diff --git a/src/protocol/libp2p/kademlia/routing_table.rs b/src/protocol/libp2p/kademlia/routing_table.rs index 2fcbc172..7040babf 100644 --- a/src/protocol/libp2p/kademlia/routing_table.rs +++ b/src/protocol/libp2p/kademlia/routing_table.rs @@ -186,9 +186,9 @@ impl RoutingTable { } /// Get `limit` closest peers to `target` from the k-buckets. - pub fn closest(&mut self, target: Key, limit: usize) -> Vec { - ClosestBucketsIter::new(self.local_key.distance(&target)) - .flat_map(|index| self.buckets[index.get()].closest_iter(&target)) + pub fn closest(&mut self, target: &Key, limit: usize) -> Vec { + ClosestBucketsIter::new(self.local_key.distance(target)) + .flat_map(|index| self.buckets[index.get()].closest_iter(target)) .take(limit) .collect() } @@ -299,7 +299,7 @@ mod tests { } let target = Key::from(PeerId::random()); - let closest = table.closest(target.clone(), 60usize); + let closest = table.closest(&target, 60usize); let mut prev = None; for peer in &closest {