-
Notifications
You must be signed in to change notification settings - Fork 162
feat(l1): store validated ENR from handshake in peer table #6109
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
base: main
Are you sure you want to change the base?
feat(l1): store validated ENR from handshake in peer table #6109
Conversation
Greptile OverviewGreptile SummaryImplements ENR storage during handshake validation per discv5 spec by calling Key changes:
Issues found:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| crates/networking/p2p/discv5/server.rs | Adds validated ENR to peer table during handshake, but stores record before verifying node_id matches src_id |
| crates/networking/p2p/discv5/peer_table.rs | Updates existing contacts with higher seq ENRs, properly resolving the TODO |
Sequence Diagram
sequenceDiagram
participant Remote as Remote Peer
participant Server as DiscoveryServer
participant PeerTable as PeerTable
Remote->>Server: Handshake packet with ENR
Server->>Server: Verify ENR signature
alt ENR signature invalid
Server-->>Remote: Return (no response)
end
Server->>Server: Extract public key from ENR
Server->>PeerTable: new_contact_records(ENR)
Note over PeerTable: Add/Update peer in contacts
Server->>Server: Verify node_id matches src_id
alt node_id mismatch
Server-->>Remote: Return (no response)
Note right of PeerTable: Invalid peer remains in table
end
Server->>Server: Verify id-signature
alt id-signature invalid
Server-->>Remote: Return (no response)
end
Server->>Server: Derive session keys
Server->>PeerTable: set_session_info()
Server->>Server: Decrypt and handle message
Server-->>Remote: Handshake complete
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.
2 files reviewed, 1 comment
| // Add the peer to the peer table | ||
| self.peer_table | ||
| .new_contact_records(vec![record.clone()], self.local_node.node_id()) | ||
| .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.
Peer added to table before verifying node_id matches src_id (line 315). If verification fails at line 317, the invalid peer remains in the table.
Move this call after the node_id verification (after line 319).
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/networking/p2p/discv5/server.rs
Line: 306:309
Comment:
Peer added to table before verifying node_id matches src_id (line 315). If verification fails at line 317, the invalid peer remains in the table.
Move this call after the node_id verification (after line 319).
How can I resolve this? If you propose a fix, please make it concise.|
Thanks for your contribution, but a previous PR fixing this exists. |
|
Sorry, there is no previous PR for this issue, I got mixed up. I'm reopening this |
Greptile OverviewGreptile SummaryThis PR implements ENR storage during handshake verification per the discv5 spec. The implementation adds validated ENRs to the peer table and updates existing contacts when receiving higher sequence numbers. Key changes:
Issues identified:
Confidence Score: 2/5
|
| Filename | Overview |
|---|---|
| crates/networking/p2p/discv5/server.rs | Added peer to table during handshake, but placement before node_id verification creates security issue where invalid peers remain stored |
| crates/networking/p2p/discv5/peer_table.rs | Updated existing contacts with higher seq ENRs, but missing fork_id validation when updating records |
Sequence Diagram
sequenceDiagram
participant Remote as Remote Peer
participant Server as DiscoveryServer
participant PeerTable as PeerTableServer
Remote->>Server: Handshake with ENR
Server->>Server: Verify ENR signature
alt ENR signature valid
Server->>PeerTable: new_contact_records(ENR)
PeerTable->>PeerTable: Check if contact exists
alt Contact does not exist
PeerTable->>PeerTable: Validate fork_id
PeerTable->>PeerTable: Insert new contact
else Contact exists with ENR
alt New seq > existing seq
PeerTable->>PeerTable: Update record (no fork_id check)
end
else Contact exists without ENR
PeerTable->>PeerTable: Add record (no fork_id check)
end
Server->>Server: Verify node_id matches src_id
alt node_id mismatch
Server->>Server: Return early (peer remains in table)
else node_id valid
Server->>Server: Verify id-signature
Server->>PeerTable: set_session_info()
Server->>Server: Process message
end
else ENR signature invalid
Server->>Server: Return early
end
Last reviewed commit: 9c73c70
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.
2 files reviewed, 2 comments
| // Add the peer to the peer table | ||
| self.peer_table | ||
| .new_contact_records(vec![record.clone()], self.local_node.node_id()) | ||
| .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.
Peer added before full handshake authentication. This call runs before the derived_node_id != src_id check (line 316) and before the id-signature verification (line 337). A malicious node claiming src_id=X but sending a valid ENR for node Y would get Y inserted into the peer table — the ENR signature is valid (it's Y's real ENR), so new_contact_records accepts it. The function returns early at line 317, but the peer table entry persists.
Move this call after the id-signature verification at line 346 — there's no reason to store anything until the handshake is fully authenticated.
| METRICS.record_new_discovery().await; | ||
| } | ||
| // TODO Handle the case the contact is already present | ||
| // The contact is already present |
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.
This was already implemented more thoroughly on a previous PR
This PR will conflict once that merges. Consider rebasing on top of it and focusing only on the handle_handshake insertion.
Motivation
When a handshake is received from an unknown peer, we verify their ENR but do not add it to the peer table. According to the discv5 specification, once an ENR signature has been validated, the record should be stored.
Description
new_contact_records().Checklist
STORE_SCHEMA_VERSION(crates/storage/lib.rs) if the PR includes breaking changes to theStorerequiring a re-sync.Closes #6056.