Skip to main content

karyon_p2p/discovery/kademlia/routing_table/
entry.rs

1use bincode::{Decode, Encode};
2
3use crate::{bloom::Bloom, discovery::kademlia::messages::PeerMsg, message::PeerAddr, PeerID};
4
5/// Specifies the size of the key, in bytes.
6pub const KEY_SIZE: usize = 32;
7
8/// The unique key identifying the peer.
9pub type Key = [u8; KEY_SIZE];
10
11/// An Entry represents a peer in the routing table.
12#[derive(Encode, Decode, Clone, Debug)]
13pub struct Entry {
14    /// The unique key identifying the peer.
15    pub key: Key,
16    /// Connection addresses for peer-to-peer data, ordered by priority.
17    pub addrs: Vec<PeerAddr>,
18    /// Discovery addresses for lookup and refresh, ordered by priority.
19    pub discovery_addrs: Vec<PeerAddr>,
20    /// Bloom filter of protocols the peer claims to support.
21    /// Treated as a hint; handshake is the source of truth.
22    pub protocols: Bloom,
23}
24
25impl Entry {
26    /// Returns the primary address (first addr) for subnet checks, if available.
27    pub fn primary_addr(&self) -> Option<&karyon_net::Addr> {
28        self.addrs.first().map(|a| &a.addr)
29    }
30}
31
32impl PartialEq for Entry {
33    fn eq(&self, other: &Self) -> bool {
34        self.key == other.key
35    }
36}
37
38impl From<Entry> for PeerMsg {
39    fn from(entry: Entry) -> PeerMsg {
40        PeerMsg {
41            peer_id: PeerID(entry.key),
42            addrs: entry.addrs,
43            discovery_addrs: entry.discovery_addrs,
44            protocols: entry.protocols,
45        }
46    }
47}
48
49impl From<PeerMsg> for Entry {
50    fn from(peer: PeerMsg) -> Entry {
51        Entry {
52            key: peer.peer_id.0,
53            addrs: peer.addrs,
54            discovery_addrs: peer.discovery_addrs,
55            protocols: peer.protocols,
56        }
57    }
58}
59
60/// Calculates the XOR distance between two provided keys.
61///
62/// The XOR distance is a metric used in Kademlia to measure the closeness
63/// of keys.
64pub fn xor_distance(key: &Key, other: &Key) -> Key {
65    let mut res = [0; 32];
66    for (i, (k, o)) in key.iter().zip(other.iter()).enumerate() {
67        res[i] = k ^ o;
68    }
69    res
70}