-
Notifications
You must be signed in to change notification settings - Fork 133
feat(l1): detect and update stale enr on ping pong #5507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
20a9ad1
ee151a0
cd8296b
fabee25
d3cab37
3df7ae3
bed7abc
aa4130b
14a776c
756e6f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -163,7 +163,7 @@ impl DiscoveryServer { | |||||||||||||||||||||||||||||||||||||||||||||||||
| sender_public_key, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let _ = self.handle_ping(hash, node).await.inspect_err(|e| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let _ = self.handle_ping(ping_message, hash, sender_public_key, node).await.inspect_err(|e| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| error!(sent = "Ping", to = %format!("{sender_public_key:#x}"), err = ?e, "Error handling message"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -280,29 +280,7 @@ impl DiscoveryServer { | |||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| async fn enr_lookup(&mut self) -> Result<(), DiscoveryServerError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some(contact) = self.peer_table.get_contact_for_enr_lookup().await? { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let expiration: u64 = get_msg_expiration_from_seconds(EXPIRATION_SECONDS); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let enr_request = Message::ENRRequest(ENRRequestMessage { expiration }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut buf = Vec::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| enr_request.encode_with_header(&mut buf, &self.signer); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let enr_request_hash: [u8; 32] = buf[..32] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .try_into() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .expect("first 32 bytes are the message hash"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.udp_socket.send_to(&buf, contact.node.udp_addr()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .inspect_err( |e| error!(sending = "ENRRequest", addr = ?&contact.node.udp_addr(), to = %format!("{:#x}", contact.node.public_key), err=?e, "Error sending message"),) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .is_err() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.peer_table | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .set_disposable(&contact.node.node_id()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| METRICS.record_new_discarded_node().await; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| self.peer_table | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .record_enr_request_sent(&contact.node.node_id(), H256::from(enr_request_hash)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.send_enr_request(&contact.node).await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -388,6 +366,33 @@ impl DiscoveryServer { | |||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| async fn send_enr_request(&mut self, node: &Node) -> Result<(), DiscoveryServerError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let expiration: u64 = get_msg_expiration_from_seconds(EXPIRATION_SECONDS); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let enr_request = Message::ENRRequest(ENRRequestMessage { expiration }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut buf = Vec::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| enr_request.encode_with_header(&mut buf, &self.signer); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let enr_request_hash: [u8; 32] = buf[..32] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .try_into() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .expect("first 32 bytes are the message hash"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
Oppen marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.udp_socket.send_to(&buf, node.udp_addr()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .inspect_err( |e| error!(sending = "ENRRequest", addr = ?node.udp_addr(), to = %format!("{:#x}", node.public_key), err=?e, "Error sending message"),) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .is_err() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.peer_table | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .set_disposable(&node.node_id()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| METRICS.record_new_discarded_node().await; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| self.peer_table | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .record_enr_request_sent(&node.node_id(), H256::from(enr_request_hash)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| async fn send_enr_response( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &self, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| request_hash: H256, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -402,11 +407,34 @@ impl DiscoveryServer { | |||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| async fn handle_ping(&mut self, hash: H256, node: Node) -> Result<(), DiscoveryServerError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| async fn handle_ping( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| &mut self, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ping_message: PingMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hash: H256, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| sender_public_key: H512, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| node: Node, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), DiscoveryServerError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.send_pong(hash, &node).await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.peer_table.insert_if_new(&node).await.unwrap_or(false) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.send_ping(&node).await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // If the contact has stale ENR then request the updated one. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let node_id = node_id(&sender_public_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| let node_id = node_id(&sender_public_key); | |
| let node_id = node.node_id(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if let (Some(received), Some(stored)) = (received_enr_seq, stored_enr_seq) | |
| && received > stored | |
| { | |
| self.send_enr_request(&node).await?; | |
| } | |
| if received_enr_seq.is_some_and(|r| stored_enr_seq.is_some_and(|s| r > s)) { | |
| self.send_enr_request(&node).await?; | |
| } |
Not sure which one I prefer 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe transpose:
| if let (Some(received), Some(stored)) = (received_enr_seq, stored_enr_seq) | |
| && received > stored | |
| { | |
| self.send_enr_request(&node).await?; | |
| } | |
| if [received_enr_seq, stored_enr_seq].transpose().is_some_and(|[received, stored]| received > stored) { | |
| self.send_enr_request(&node).await?; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or:
| if let (Some(received), Some(stored)) = (received_enr_seq, stored_enr_seq) | |
| && received > stored | |
| { | |
| self.send_enr_request(&node).await?; | |
| } | |
| if let Some([received, stored]) = [received_enr_seq, stored_enr_seq].transpose() && received > stored { | |
| self.send_enr_request(&node).await?; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transpose is an unstable feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😭
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new ENR staleness detection logic in handle_ping lacks test coverage. Consider adding tests to verify that ENR requests are sent when a ping is received with a higher sequence number than the stored ENR.
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new ENR staleness detection logic in handle_pong lacks test coverage. Consider adding tests to verify that ENR requests are sent when a pong is received with a higher sequence number than the stored ENR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's factorize common code (message encoding, hash extraction,
udp_socket.send, maybeset_disposable) withsend_ping/send_ping_internalto an utility function to minimize code repetiton.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added send_else_dispose to remove code duplication.