-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Improve P2P discovery #9526
Improve P2P discovery #9526
Changes from 1 commit
48cb9d4
e563f98
5e67cb5
0abffce
8d1cdbc
e0f61b1
973fd2c
d586beb
95d0b4a
2af281f
fe230b2
e4d5212
c38ff7c
bbf99bd
6ebdc56
e98c191
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 |
---|---|---|
|
@@ -128,6 +128,7 @@ pub struct Discovery<'a> { | |
id_hash: H256, | ||
secret: Secret, | ||
public_endpoint: NodeEndpoint, | ||
started_discovering: bool, | ||
discovering: bool, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two bools look like their doing the same thing? Could we ever be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, much clearer now. Can't really think of a better name, maybe s/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds better, thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two booleans look like they're doing the same thing, i.e. could we ever be in a state where |
||
discovery_round: u16, | ||
discovery_id: NodeId, | ||
|
@@ -154,6 +155,7 @@ impl<'a> Discovery<'a> { | |
id_hash: keccak(key.public()), | ||
secret: key.secret().clone(), | ||
public_endpoint: public, | ||
started_discovering: false, | ||
discovering: false, | ||
discovery_round: 0, | ||
discovery_id: NodeId::new(), | ||
|
@@ -500,7 +502,7 @@ impl<'a> Discovery<'a> { | |
let timestamp: u64 = rlp.val_at(2)?; | ||
self.check_timestamp(timestamp)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should check error here and remove from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will just go expired after a few 100ms, so I think it's fine as-is. |
||
|
||
let expected_node = match self.in_flight_pings.entry(*node_id) { | ||
let mut expected_node = match self.in_flight_pings.entry(*node_id) { | ||
Entry::Occupied(entry) => { | ||
let expected_node = { | ||
let request = entry.get(); | ||
|
@@ -509,7 +511,7 @@ impl<'a> Discovery<'a> { | |
None | ||
} else { | ||
if request.deprecated_echo_hash == echo_hash { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not know how such deprecated functionalities are managed, ideally this should disappear in a few parity version I think. It is an open question, maybe we can use things like rust deprecated tag or other to keep trace of it (and not forget it in the base code ad vita eternam) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But maybe we want to keep it for better compatibility (not really my point of view) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure either... @5chdn maybe? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, add a I really need this for the release:) |
||
info!(target: "discovery", "Got a Pong from old Parity version."); | ||
trace!(target: "discovery", "Got Pong from an old parity-ethereum version."); | ||
} | ||
// Get the UDP port from the saved request, and | ||
// the address from the incoming connection | ||
|
@@ -529,38 +531,40 @@ impl<'a> Discovery<'a> { | |
expected_node | ||
}, | ||
Entry::Vacant(_) => { | ||
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from); | ||
None | ||
}, | ||
}; | ||
|
||
// If the Node couldn't be found from its ID, | ||
// Try to find it in from the hash that was sent back | ||
// if expected_node.is_none() { | ||
// self.in_flight_pings.retain(|_, ping_request| { | ||
// if ping_request.echo_hash == echo_hash || ping_request.deprecated_echo_hash == echo_hash { | ||
// debug!(target: "discovery", | ||
// "Found corresponding request expected={:x}@{} ; found={:x}@{}", | ||
// node_id, from, | ||
// ping_request.node.id, ping_request.node.endpoint.address | ||
// ); | ||
// expected_node = Some(NodeEntry { | ||
// id: *node_id, | ||
// endpoint: NodeEndpoint { | ||
// udp_port: ping_request.node.endpoint.udp_port, | ||
// address: from.clone(), | ||
// } | ||
// }); | ||
// false | ||
// } else { | ||
// true | ||
// } | ||
// }); | ||
// } | ||
if expected_node.is_none() { | ||
let mut found = false; | ||
self.in_flight_pings.retain(|_, ping_request| { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When would this be the case? Iterating through the whole If there's a good reason for this, the map might as well be keyed on the ping hash (except that it would be harder to maintain compatibility with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is to cater for the fact that the node answering your Ping might not have the NodeID you've been told. Another mechanism would be to Ping back any unknown received Pong ; I can try that if it sounds better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the NodeID is wrong, then the address (NodeID + Network Endpoint) is wrong, so I think it's fine to just drop the PONG. Consider also that the sender of the PONG will likely PING back to us after receiving the PING, from which we can get the correct NodeID, so this unlikely case should resolve itself anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay I'll remove it from now. Note that Geth doesn't Ping back on received Ping, it just adds it to their NodeTable . |
||
if !found && ping_request.echo_hash == echo_hash || ping_request.deprecated_echo_hash == echo_hash { | ||
debug!(target: "discovery", | ||
"Found corresponding request expected={:x}@{} ; found={:x}@{}", | ||
node_id, from, | ||
ping_request.node.id, ping_request.node.endpoint.address | ||
); | ||
found = true; | ||
expected_node = Some(NodeEntry { | ||
id: *node_id, | ||
endpoint: NodeEndpoint { | ||
udp_port: ping_request.node.endpoint.udp_port, | ||
address: from.clone(), | ||
} | ||
}); | ||
false | ||
} else { | ||
true | ||
} | ||
}); | ||
} | ||
|
||
if let Some(node) = expected_node { | ||
Ok(self.update_node(node)) | ||
} else { | ||
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from); | ||
Ok(None) | ||
} | ||
} | ||
|
@@ -711,6 +715,10 @@ impl<'a> Discovery<'a> { | |
|
||
if self.discovering { | ||
self.discover(); | ||
// Start discovering if the first pings have been sent (or timed out) | ||
} else if self.in_flight_pings.len() == 0 && !self.started_discovering { | ||
self.started_discovering = true; | ||
self.start(); | ||
} | ||
} | ||
|
||
|
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.
Instead of a separate bool, I think making
discovery_round
anOption<u16>
is cleaner.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.
Definitly, thanks!