[net-fixes] peering: only count node IDs and not addresses in hash

This commit is contained in:
Alex Auvolat 2024-03-21 09:47:04 +01:00
parent ce69dc302c
commit 5225a81dee
No known key found for this signature in database
GPG key ID: 0E496D15096376BE

View file

@ -164,29 +164,40 @@ struct KnownHosts {
impl KnownHosts { impl KnownHosts {
fn new() -> Self { fn new() -> Self {
let list = HashMap::new(); let list = HashMap::new();
let hash = Self::calculate_hash(vec![]); let mut ret = Self {
Self { list, hash } list,
hash: hash::Digest::from_slice(&[0u8; 64][..]).unwrap(),
};
ret.update_hash();
ret
} }
fn update_hash(&mut self) { fn update_hash(&mut self) {
self.hash = Self::calculate_hash(self.connected_peers_vec()); // The hash is a value that is exchanged between nodes when they ping one
} // another. Nodes compare their known hosts hash to know if they are connected
fn connected_peers_vec(&self) -> Vec<(NodeID, SocketAddr)> { // to the same set of nodes. If the hashes differ, they are connected to
let mut list = Vec::with_capacity(self.list.len()); // different nodes and they trigger an exchange of the full list of active
for (id, peer) in self.list.iter() { // connections. The hash value only represents the set of node IDs and not
if peer.state.is_up() { // their actual socket addresses, because nodes can be connected via different
list.push((*id, peer.addr)); // addresses and that shouldn't necessarily trigger a full peer exchange.
} let mut list = self
} .list
list .iter()
} .filter(|(_, peer)| peer.state.is_up())
fn calculate_hash(mut list: Vec<(NodeID, SocketAddr)>) -> hash::Digest { .map(|(id, _)| *id)
.collect::<Vec<_>>();
list.sort(); list.sort();
let mut hash_state = hash::State::new(); let mut hash_state = hash::State::new();
for (id, addr) in list { for id in list {
hash_state.update(&id[..]); hash_state.update(&id[..]);
hash_state.update(&format!("{}\n", addr).into_bytes()[..]);
} }
hash_state.finalize() self.hash = hash_state.finalize();
}
fn connected_peers_vec(&self) -> Vec<(NodeID, SocketAddr)> {
self.list
.iter()
.filter(|(_, peer)| peer.state.is_up())
.map(|(id, peer)| (*id, peer.addr))
.collect::<Vec<_>>()
} }
} }