aboutsummaryrefslogtreecommitdiff
path: root/p2p/src/routing_table
diff options
context:
space:
mode:
Diffstat (limited to 'p2p/src/routing_table')
-rw-r--r--p2p/src/routing_table/bucket.rs21
-rw-r--r--p2p/src/routing_table/mod.rs12
2 files changed, 25 insertions, 8 deletions
diff --git a/p2p/src/routing_table/bucket.rs b/p2p/src/routing_table/bucket.rs
index 13edd24..0f43b13 100644
--- a/p2p/src/routing_table/bucket.rs
+++ b/p2p/src/routing_table/bucket.rs
@@ -6,23 +6,28 @@ use rand::{rngs::OsRng, seq::SliceRandom};
pub type EntryStatusFlag = u16;
/// The entry is connected.
-pub const CONNECTED_ENTRY: EntryStatusFlag = 0b00001;
+pub const CONNECTED_ENTRY: EntryStatusFlag = 0b000001;
/// The entry is disconnected. This will increase the failure counter.
-pub const DISCONNECTED_ENTRY: EntryStatusFlag = 0b00010;
+pub const DISCONNECTED_ENTRY: EntryStatusFlag = 0b000010;
/// The entry is ready to reconnect, meaning it has either been added and
/// has no connection attempts, or it has been refreshed.
-pub const PENDING_ENTRY: EntryStatusFlag = 0b00100;
+pub const PENDING_ENTRY: EntryStatusFlag = 0b000100;
/// The entry is unreachable. This will increase the failure counter.
-pub const UNREACHABLE_ENTRY: EntryStatusFlag = 0b01000;
+pub const UNREACHABLE_ENTRY: EntryStatusFlag = 0b001000;
/// The entry is unstable. This will increase the failure counter.
-pub const UNSTABLE_ENTRY: EntryStatusFlag = 0b10000;
+pub const UNSTABLE_ENTRY: EntryStatusFlag = 0b010000;
+
+/// The entry is incompatible. This entry will not contribute to an increase in
+/// failure attempts, instead, it will persist in the routing table for the
+/// lookup process and will only be removed in the presence of a new entry.
+pub const INCOMPATIBLE_ENTRY: EntryStatusFlag = 0b100000;
#[allow(dead_code)]
-pub const ALL_ENTRY: EntryStatusFlag = 0b11111;
+pub const ALL_ENTRY: EntryStatusFlag = 0b111111;
/// A BucketEntry represents a peer in the routing table.
#[derive(Clone, Debug)]
@@ -38,6 +43,10 @@ impl BucketEntry {
self.status ^ CONNECTED_ENTRY == 0
}
+ pub fn is_incompatible(&self) -> bool {
+ self.status ^ INCOMPATIBLE_ENTRY == 0
+ }
+
pub fn is_unreachable(&self) -> bool {
self.status ^ UNREACHABLE_ENTRY == 0
}
diff --git a/p2p/src/routing_table/mod.rs b/p2p/src/routing_table/mod.rs
index abf9a08..35729da 100644
--- a/p2p/src/routing_table/mod.rs
+++ b/p2p/src/routing_table/mod.rs
@@ -1,8 +1,8 @@
mod bucket;
mod entry;
pub use bucket::{
- Bucket, BucketEntry, EntryStatusFlag, CONNECTED_ENTRY, DISCONNECTED_ENTRY, PENDING_ENTRY,
- UNREACHABLE_ENTRY, UNSTABLE_ENTRY,
+ Bucket, BucketEntry, EntryStatusFlag, CONNECTED_ENTRY, DISCONNECTED_ENTRY, INCOMPATIBLE_ENTRY,
+ PENDING_ENTRY, UNREACHABLE_ENTRY, UNSTABLE_ENTRY,
};
pub use entry::{xor_distance, Entry, Key};
@@ -82,6 +82,14 @@ impl RoutingTable {
return AddEntryResult::Added;
}
+ // Replace it with an incompatible entry if one exists.
+ let incompatible_entry = bucket.iter().find(|e| e.is_incompatible()).cloned();
+ if let Some(e) = incompatible_entry {
+ bucket.remove(&e.entry.key);
+ bucket.add(&entry);
+ return AddEntryResult::Added;
+ }
+
// If the bucket is full, the entry is ignored.
AddEntryResult::Ignored
}