Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

DevP2p: Get node IP address and udp port from Socket, if not included in PING packet #10705

Merged
merged 10 commits into from
Jun 12, 2019
29 changes: 25 additions & 4 deletions util/network-devp2p/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ pub struct Discovery<'a> {
discovery_nodes: HashSet<NodeId>,
node_buckets: Vec<NodeBucket>,

// these nodes can't be used for syncing.
bootnodes: HashSet<NodeId>,
seunlanlege marked this conversation as resolved.
Show resolved Hide resolved

// Sometimes we don't want to add nodes to the NodeTable, but still want to
// keep track of them to avoid excessive pinging (happens when an unknown node sends
// a discovery request to us -- the node might be on a different net).
Expand Down Expand Up @@ -200,6 +203,7 @@ impl<'a> Discovery<'a> {
discovery_id: NodeId::new(),
discovery_nodes: HashSet::new(),
node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(),
bootnodes: HashSet::new(),
other_observed_nodes: LruCache::new(OBSERVED_NODES_MAX_SIZE),
in_flight_pings: HashMap::new(),
in_flight_find_nodes: HashMap::new(),
Expand Down Expand Up @@ -257,7 +261,7 @@ impl<'a> Discovery<'a> {
Ok(()) => None,
Err(BucketError::Ourselves) => None,
Err(BucketError::NotInTheBucket{node_entry, bucket_distance}) => Some((node_entry, bucket_distance))
}.map(|(node_entry, bucket_distance)| {
}.and_then(|(node_entry, bucket_distance)| {
trace!(target: "discovery", "Adding a new node {:?} into our bucket {}", &node_entry, bucket_distance);

let mut added = HashMap::with_capacity(1);
Expand All @@ -275,7 +279,12 @@ impl<'a> Discovery<'a> {
if let Some(node) = node_to_ping {
self.try_ping(node, PingReason::Default);
};
TableUpdates{added, removed: HashSet::new()}

if !self.bootnodes.contains(&node_entry.id) {
seunlanlege marked this conversation as resolved.
Show resolved Hide resolved
Some(TableUpdates { added, removed: HashSet::new() })
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
} else {
None
}
})
}

Expand Down Expand Up @@ -518,7 +527,19 @@ impl<'a> Discovery<'a> {

fn on_ping(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr, echo_hash: &[u8]) -> Result<Option<TableUpdates>, Error> {
trace!(target: "discovery", "Got Ping from {:?}", &from);
let ping_from = NodeEndpoint::from_rlp(&rlp.at(1)?)?;
let ping_from = if let Ok(node_endpoint) = NodeEndpoint::from_rlp(&rlp.at(1)?) {
node_endpoint
} else {
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
let mut address = from.clone();
// address here is the node's tcp port. If we are unable to get the `NodeEndpoint` from the `ping_from`
// field then this is most likely a BootNode, set the tcp port to 0 because it can not be used for syncing.
seunlanlege marked this conversation as resolved.
Show resolved Hide resolved
self.bootnodes.insert(node_id.clone());
address.set_port(0);
NodeEndpoint {
address,
udp_port: from.port()
ngotchac marked this conversation as resolved.
Show resolved Hide resolved
}
};
let ping_to = NodeEndpoint::from_rlp(&rlp.at(2)?)?;
let timestamp: u64 = rlp.val_at(3)?;
self.check_timestamp(timestamp)?;
Expand All @@ -540,7 +561,7 @@ impl<'a> Discovery<'a> {
self.send_packet(PACKET_PONG, from, &response.drain())?;

let entry = NodeEntry { id: *node_id, endpoint: pong_to.clone() };
if !entry.endpoint.is_valid() {
if !entry.endpoint.is_valid() && !self.bootnodes.contains(node_id) {
debug!(target: "discovery", "Got bad address: {:?}", entry);
} else if !self.is_allowed(&entry) {
debug!(target: "discovery", "Address not allowed: {:?}", entry);
Expand Down