Skip to content

Commit 8b0e2b8

Browse files
ElFantasmaedg-l
andauthored
perf(l1): reusing FindNode message per lookup loop (#5047)
**Motivation** Noticed that random key creation for FindNode messages was consuming a lot of CPU: <img width="1860" height="563" alt="image" src="https://github.com/user-attachments/assets/9d823161-6013-41fe-94b1-008803edb353" /> **Description** So, instead of creating a new key on each message, we create a FindNode message on every lookup cycle, and encode it a single time to send to all peers. It removes some randomness but gains in performance. In any case, next lookup cycle will create a new key. New flamegraph: <img width="1854" height="539" alt="image" src="https://github.com/user-attachments/assets/d2b42609-e178-4ec7-a1a7-31230926c06e" /> Tested on mainnet to see if it reduced peer finding performance, and it took 3' 24'' to find 50 peers ``` 2025-10-24T18:48:42.213697Z INFO ethrex_p2p::network: P2P Snap Sync: elapsed: 00h 03m 23s 00ms 50 peers. Current step: Downloading Headers ``` and 13' 43'' to reach the 100 peers limit: ``` 2025-10-24T18:59:02.280007Z INFO ethrex_p2p::network: P2P Snap Sync: elapsed: 00h 13m 43s 00ms 100 peers. Current step: Downloading Headers ```  --------- Co-authored-by: Edgar <[email protected]>
1 parent 5346ed2 commit 8b0e2b8

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Perf
44

5+
### 2025-10-27
6+
7+
- Reusing FindNode message per lookup loop instead of randomizing the key for each message. [#5047](https://github.com/lambdaclass/ethrex/pull/5047)
8+
59
### 2025-10-21
610

711
- Instead of lazy computation of blocklist, do greedy computation of allowlist and store the result, fetch it with the DB. [#4961](https://github.com/lambdaclass/ethrex/pull/4961)

crates/networking/p2p/discv4/server.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,18 @@ impl DiscoveryServer {
216216
}
217217

218218
async fn lookup(&mut self) -> Result<(), DiscoveryServerError> {
219+
// Sending the same FindNode message to all contacts to optimize message creation and encoding
220+
let expiration: u64 = get_msg_expiration_from_seconds(EXPIRATION_SECONDS);
221+
let random_priv_key = SecretKey::new(&mut OsRng);
222+
let random_pub_key = public_key_from_signing_key(&random_priv_key);
223+
let msg = Message::FindNode(FindNodeMessage::new(random_pub_key, expiration));
224+
let mut buf = BytesMut::new();
225+
msg.encode_with_header(&mut buf, &self.signer);
226+
219227
for contact in self.peer_table.get_contacts_for_lookup().await? {
220-
if self.send_find_node(&contact.node).await.is_err() {
228+
if self.udp_socket.send_to(&buf, &contact.node.udp_addr()).await.inspect_err(
229+
|e| error!(sending = ?msg, addr = ?&contact.node.udp_addr(), err=?e, "Error sending message"),
230+
).is_err() {
221231
self.peer_table
222232
.set_disposable(&contact.node.node_id())
223233
.await?;
@@ -309,20 +319,6 @@ impl DiscoveryServer {
309319
Ok(())
310320
}
311321

312-
async fn send_find_node(&self, node: &Node) -> Result<(), DiscoveryServerError> {
313-
let expiration: u64 = get_msg_expiration_from_seconds(EXPIRATION_SECONDS);
314-
315-
let random_priv_key = SecretKey::new(&mut OsRng);
316-
let random_pub_key = public_key_from_signing_key(&random_priv_key);
317-
318-
let msg = Message::FindNode(FindNodeMessage::new(random_pub_key, expiration));
319-
self.send(msg, node.udp_addr()).await?;
320-
321-
debug!(sent = "FindNode", to = %format!("{:#x}", node.public_key));
322-
323-
Ok(())
324-
}
325-
326322
async fn send_neighbors(
327323
&self,
328324
neighbors: Vec<Node>,

0 commit comments

Comments
 (0)