diff options
Diffstat (limited to 'p2p/src/routing_table')
-rw-r--r-- | p2p/src/routing_table/bucket.rs | 21 | ||||
-rw-r--r-- | p2p/src/routing_table/mod.rs | 12 |
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 } |