From ff25c4dae1e3d9738a9fd6bdbfe1e75836378596 Mon Sep 17 00:00:00 2001 From: Age Manning Date: Tue, 2 Apr 2024 16:07:46 +1100 Subject: [PATCH 1/2] Prevent storing non-contactable ENRs --- src/service.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/service.rs b/src/service.rs index af968fdb..cc0524a1 100644 --- a/src/service.rs +++ b/src/service.rs @@ -886,7 +886,10 @@ impl Service { }; self.send_rpc_request(active_request); } - self.connection_updated(node_id, ConnectionStatus::PongReceived(enr)); + // Only update the routing table if the new ENR is contactable + if self.ip_mode.get_contactable_addr(&enr).is_some() { + self.connection_updated(node_id, ConnectionStatus::PongReceived(enr)); + } } } } @@ -1188,15 +1191,19 @@ impl Service { return false; } - // If any of the discovered nodes are in the routing table, and there contains an older ENR, update it. // If there is an event stream send the Discovered event if self.config.report_discovered_peers { self.send_event(Event::Discovered(enr.clone())); } - // ignore peers that don't pass the table filter - if (self.config.table_filter)(enr) { - let key = kbucket::Key::from(enr.node_id()); + // Check that peers are compatible to be included into the routing table. They must: + // - Pass the table filter + // - Be contactable + // + // Failing this, they are not added, and if there is an older version of them in our + // table, we remove them. + let key = kbucket::Key::from(enr.node_id()); + if (self.config.table_filter)(enr) && self.ip_mode.get_contactable_addr(enr).is_some() { // If the ENR exists in the routing table and the discovered ENR has a greater // sequence number, perform some filter checks before updating the enr. @@ -1208,6 +1215,7 @@ impl Service { }; if must_update_enr { + if let UpdateResult::Failed(reason) = self.kbuckets.write().update_node(&key, enr.clone(), None) { @@ -1221,7 +1229,16 @@ impl Service { } } } else { - return false; // Didn't pass the table filter remove the peer + // Is either non-contactable or didn't pass the table filter. If it exists in the + // routing table, remove it. + match self.kbuckets.write().entry(&key) { + kbucket::Entry::Present(entry, _) if entry.value().seq() < enr.seq() => entry.remove(), + kbucket::Entry::Pending(mut entry, _) => if entry.value().seq() < enr.seq() {entry.remove()}, + _ => {} + } + + // Didn't pass the requirements remove the ENR + return false; } // The remaining ENRs are used if this request was part of a query. If we are From 5a863be0a64e05e116170a8b489b1de2870c235d Mon Sep 17 00:00:00 2001 From: Age Manning Date: Tue, 2 Apr 2024 16:11:01 +1100 Subject: [PATCH 2/2] fmt --- src/service.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/service.rs b/src/service.rs index cc0524a1..ba0f80f4 100644 --- a/src/service.rs +++ b/src/service.rs @@ -888,7 +888,10 @@ impl Service { } // Only update the routing table if the new ENR is contactable if self.ip_mode.get_contactable_addr(&enr).is_some() { - self.connection_updated(node_id, ConnectionStatus::PongReceived(enr)); + self.connection_updated( + node_id, + ConnectionStatus::PongReceived(enr), + ); } } } @@ -1204,7 +1207,6 @@ impl Service { // table, we remove them. let key = kbucket::Key::from(enr.node_id()); if (self.config.table_filter)(enr) && self.ip_mode.get_contactable_addr(enr).is_some() { - // If the ENR exists in the routing table and the discovered ENR has a greater // sequence number, perform some filter checks before updating the enr. @@ -1215,7 +1217,6 @@ impl Service { }; if must_update_enr { - if let UpdateResult::Failed(reason) = self.kbuckets.write().update_node(&key, enr.clone(), None) { @@ -1232,8 +1233,14 @@ impl Service { // Is either non-contactable or didn't pass the table filter. If it exists in the // routing table, remove it. match self.kbuckets.write().entry(&key) { - kbucket::Entry::Present(entry, _) if entry.value().seq() < enr.seq() => entry.remove(), - kbucket::Entry::Pending(mut entry, _) => if entry.value().seq() < enr.seq() {entry.remove()}, + kbucket::Entry::Present(entry, _) if entry.value().seq() < enr.seq() => { + entry.remove() + } + kbucket::Entry::Pending(mut entry, _) => { + if entry.value().seq() < enr.seq() { + entry.remove() + } + } _ => {} }