Skip to content

Commit 0b4bf1d

Browse files
authored
kad: Avoid cloning the KademliaMessage and use reference for RoutingTable::closest (#233)
This PR brings a few optimizations wrt cloning objects and improves the ergonomics of the routing table API: - `KademliaMessage` is moved by value to avoid further cloning of references - kademlia keys are constructed from borrowed references - `RoutingTable::closest` takes the provided key by reference for better ergonomics. One use-case for references is when the key is later on used for other purposes (like computing distances) cc @paritytech/networking --------- Signed-off-by: Alexandru Vasile <[email protected]>
1 parent f112b59 commit 0b4bf1d

File tree

2 files changed

+51
-43
lines changed

2 files changed

+51
-43
lines changed

src/protocol/libp2p/kademlia/mod.rs

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,7 @@ impl Kademlia {
422422
tracing::trace!(target: LOG_TARGET, ?peer, query = ?query_id, "handle message from peer");
423423

424424
match KademliaMessage::from_bytes(message).ok_or(Error::InvalidData)? {
425-
ref message @ KademliaMessage::FindNode {
426-
ref target,
427-
ref peers,
428-
} => {
425+
KademliaMessage::FindNode { target, peers } => {
429426
match query_id {
430427
Some(query_id) => {
431428
tracing::trace!(
@@ -437,8 +434,12 @@ impl Kademlia {
437434
);
438435

439436
// update routing table and inform user about the update
440-
self.update_routing_table(peers).await;
441-
self.engine.register_response(query_id, peer, message.clone());
437+
self.update_routing_table(&peers).await;
438+
self.engine.register_response(
439+
query_id,
440+
peer,
441+
KademliaMessage::FindNode { target, peers },
442+
);
442443
}
443444
None => {
444445
tracing::trace!(
@@ -449,9 +450,9 @@ impl Kademlia {
449450
);
450451

451452
let message = KademliaMessage::find_node_response(
452-
target,
453+
&target,
453454
self.routing_table
454-
.closest(Key::from(target.clone()), self.replication_factor),
455+
.closest(&Key::new(target.as_ref()), self.replication_factor),
455456
);
456457
self.executor.send_message(peer, message.into(), substream);
457458
}
@@ -471,13 +472,9 @@ impl Kademlia {
471472

472473
let _ = self.event_tx.send(KademliaEvent::IncomingRecord { record }).await;
473474
}
474-
ref message @ KademliaMessage::GetRecord {
475-
ref key,
476-
ref record,
477-
ref peers,
478-
} => {
475+
KademliaMessage::GetRecord { key, record, peers } => {
479476
match (query_id, key) {
480-
(Some(query_id), _) => {
477+
(Some(query_id), key) => {
481478
tracing::trace!(
482479
target: LOG_TARGET,
483480
?peer,
@@ -488,8 +485,12 @@ impl Kademlia {
488485
);
489486

490487
// update routing table and inform user about the update
491-
self.update_routing_table(peers).await;
492-
self.engine.register_response(query_id, peer, message.clone());
488+
self.update_routing_table(&peers).await;
489+
self.engine.register_response(
490+
query_id,
491+
peer,
492+
KademliaMessage::GetRecord { key, record, peers },
493+
);
493494
}
494495
(None, Some(key)) => {
495496
tracing::trace!(
@@ -499,22 +500,20 @@ impl Kademlia {
499500
"handle `GET_VALUE` request",
500501
);
501502

502-
let value = self.store.get(key).cloned();
503+
let value = self.store.get(&key).cloned();
503504
let closest_peers = self
504505
.routing_table
505-
.closest(Key::from(key.to_vec()), self.replication_factor);
506+
.closest(&Key::new(key.as_ref()), self.replication_factor);
506507

507-
let message = KademliaMessage::get_value_response(
508-
(*key).clone(),
509-
closest_peers,
510-
value,
511-
);
508+
let message =
509+
KademliaMessage::get_value_response(key, closest_peers, value);
512510
self.executor.send_message(peer, message.into(), substream);
513511
}
514512
(None, None) => tracing::debug!(
515513
target: LOG_TARGET,
516514
?peer,
517-
?message,
515+
?record,
516+
?peers,
518517
"unable to handle `GET_RECORD` request with empty key",
519518
),
520519
}
@@ -567,10 +566,10 @@ impl Kademlia {
567566
}
568567
}
569568
}
570-
ref message @ KademliaMessage::GetProviders {
571-
ref key,
572-
ref peers,
573-
ref providers,
569+
KademliaMessage::GetProviders {
570+
key,
571+
peers,
572+
providers,
574573
} => {
575574
match (query_id, key) {
576575
(Some(query_id), key) => {
@@ -586,9 +585,17 @@ impl Kademlia {
586585
);
587586

588587
// update routing table and inform user about the update
589-
self.update_routing_table(peers).await;
588+
self.update_routing_table(&peers).await;
590589

591-
self.engine.register_response(query_id, peer, message.clone());
590+
self.engine.register_response(
591+
query_id,
592+
peer,
593+
KademliaMessage::GetProviders {
594+
key,
595+
peers,
596+
providers,
597+
},
598+
);
592599
}
593600
(None, Some(key)) => {
594601
tracing::trace!(
@@ -598,7 +605,7 @@ impl Kademlia {
598605
"handle `GET_PROVIDERS` request",
599606
);
600607

601-
let mut providers = self.store.get_providers(key);
608+
let mut providers = self.store.get_providers(&key);
602609

603610
// Make sure local provider addresses are up to date.
604611
let local_peer_id = self.local_key.clone().into_preimage();
@@ -608,7 +615,7 @@ impl Kademlia {
608615

609616
let closer_peers = self
610617
.routing_table
611-
.closest(Key::from(key.to_vec()), self.replication_factor);
618+
.closest(&Key::new(key.as_ref()), self.replication_factor);
612619

613620
let message =
614621
KademliaMessage::get_providers_response(providers, &closer_peers);
@@ -617,7 +624,8 @@ impl Kademlia {
617624
(None, None) => tracing::debug!(
618625
target: LOG_TARGET,
619626
?peer,
620-
?message,
627+
?peers,
628+
?providers,
621629
"unable to handle `GET_PROVIDERS` request with empty key",
622630
),
623631
}
@@ -977,7 +985,7 @@ impl Kademlia {
977985
query_id,
978986
peer,
979987
self.routing_table
980-
.closest(Key::from(peer), self.replication_factor)
988+
.closest(&Key::from(peer), self.replication_factor)
981989
.into()
982990
);
983991
}
@@ -1005,7 +1013,7 @@ impl Kademlia {
10051013
self.engine.start_put_record(
10061014
query_id,
10071015
record,
1008-
self.routing_table.closest(key, self.replication_factor).into(),
1016+
self.routing_table.closest(&key, self.replication_factor).into(),
10091017
);
10101018
}
10111019
Some(KademliaCommand::PutRecordToPeers {
@@ -1074,7 +1082,7 @@ impl Kademlia {
10741082
key.clone(),
10751083
provider,
10761084
self.routing_table
1077-
.closest(Key::new(key), self.replication_factor)
1085+
.closest(&Key::new(key), self.replication_factor)
10781086
.into(),
10791087
);
10801088
}
@@ -1107,7 +1115,7 @@ impl Kademlia {
11071115
query_id,
11081116
key.clone(),
11091117
self.routing_table
1110-
.closest(Key::new(key), self.replication_factor)
1118+
.closest(&Key::new(key), self.replication_factor)
11111119
.into(),
11121120
quorum,
11131121
if record.is_some() { 1 } else { 0 },
@@ -1125,7 +1133,7 @@ impl Kademlia {
11251133
query_id,
11261134
key.clone(),
11271135
self.routing_table
1128-
.closest(Key::new(key), self.replication_factor)
1136+
.closest(&Key::new(key), self.replication_factor)
11291137
.into(),
11301138
known_providers,
11311139
);
@@ -1185,7 +1193,7 @@ impl Kademlia {
11851193
provided_key.clone(),
11861194
provider,
11871195
self.routing_table
1188-
.closest(Key::new(provided_key), self.replication_factor)
1196+
.closest(&Key::new(provided_key), self.replication_factor)
11891197
.into(),
11901198
);
11911199
}

src/protocol/libp2p/kademlia/routing_table.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ impl RoutingTable {
186186
}
187187

188188
/// Get `limit` closest peers to `target` from the k-buckets.
189-
pub fn closest<K: Clone>(&mut self, target: Key<K>, limit: usize) -> Vec<KademliaPeer> {
190-
ClosestBucketsIter::new(self.local_key.distance(&target))
191-
.flat_map(|index| self.buckets[index.get()].closest_iter(&target))
189+
pub fn closest<K: Clone>(&mut self, target: &Key<K>, limit: usize) -> Vec<KademliaPeer> {
190+
ClosestBucketsIter::new(self.local_key.distance(target))
191+
.flat_map(|index| self.buckets[index.get()].closest_iter(target))
192192
.take(limit)
193193
.collect()
194194
}
@@ -299,7 +299,7 @@ mod tests {
299299
}
300300

301301
let target = Key::from(PeerId::random());
302-
let closest = table.closest(target.clone(), 60usize);
302+
let closest = table.closest(&target, 60usize);
303303
let mut prev = None;
304304

305305
for peer in &closest {

0 commit comments

Comments
 (0)