Skip to content

Commit

Permalink
draft: implement network size estimator formula
Browse files Browse the repository at this point in the history
  • Loading branch information
bochaco committed Apr 9, 2024
1 parent 38e406b commit a2578fe
Showing 1 changed file with 63 additions and 6 deletions.
69 changes: 63 additions & 6 deletions sn_networking/src/sybil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use crate::NetworkAddress;

use libp2p::PeerId;
use num::{integer::binomial, pow::Pow};
use xor_name::{XorName, XOR_NAME_LEN};
Expand All @@ -16,9 +18,11 @@ const KL_DIVERGENCE_THRESHOLD: f64 = 10f64; // TODO: find a good value

const K: usize = 20;
const N: usize = 25; // TODO: replace with network size estimation;

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
const MAX_ITER_FOR_NET_SIZE: usize = 50;

// Given the set of closest K peers ids to the passed content address, return 'true'
// if there is probabilistically a sybil attack around that CID address.
// This implements the algorithm proposed in https://ssg.lancs.ac.uk/wp-content/uploads/ndss_preprint.pdf
pub(super) async fn check_for_sybil_attack(peers: &[PeerId], cid: &XorName) -> bool {
// TODO: do we go ahead even if we don't have at least K peer ids...?

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
info!(
Expand All @@ -44,7 +48,7 @@ fn num_peers_per_cpl(peers: &[PeerId], cid: &XorName) -> usize {
peers_per_cpl / K
}

// TODO: use released https://github.com/maidsafe/xor_name/pull/96 instead
// TODO: remove this fn and instead use released https://github.com/maidsafe/xor_name/pull/96

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
fn common_prefix(lhs: &XorName, rhs: &XorName) -> usize {
for byte_index in 0..XOR_NAME_LEN {
if lhs[byte_index] != rhs[byte_index] {
Expand All @@ -54,18 +58,71 @@ fn common_prefix(lhs: &XorName, rhs: &XorName) -> usize {
8 * XOR_NAME_LEN
}

// Formula 1 and 2 in page ??
// Formula 1 and 2 in page 3
fn get_net_size_estimate() -> usize {
// TODO!
N
// FIXME: generate random keys, one for each of the 256 buckets

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
const M: usize = 256;
let m_random_keys = (0..M).map(|_| PeerId::random()).collect::<Vec<_>>();

// FIXME: get-closest-peers to each of the 256 random key

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
let closest_peers = (0..K)
.map(|_| (0..M).map(|_| PeerId::random()).collect::<Vec<_>>())
.collect::<Vec<_>>();

let mut best_n_found = 0;
let mut minimum_value_found = f64::MAX;
for n in 0..MAX_ITER_FOR_NET_SIZE {
let mut acc = 0f64;
for (i, closest_i_th_peers) in closest_peers.iter().enumerate() {
// compute average distance between each of the 256 random keys,
// and their i-th closest peer
let d_i =
average_between_keys_and_i_th_closest_peer(&m_random_keys, closest_i_th_peers);

let dist: f64 = d_i as f64 - ((2f64.pow(256) * i as f64) / (N + 1) as f64);
acc += dist.pow(2);
}
if acc < minimum_value_found {
minimum_value_found = acc;
best_n_found = n;
}
}

best_n_found
}

// Formula 1 in page 3
// Compute the average distance between each of the passed random keys,
// and their i-th closest peer
fn average_between_keys_and_i_th_closest_peer(
keys: &[PeerId],
closest_i_th_peers: &[PeerId],
) -> usize {
let m = keys.len();
if m != closest_i_th_peers.len() {
// FIXME: remove panic

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
panic!("Invalid arguments to calculate network size estimation");
}
let distances = keys.iter().enumerate().fold(0usize, |j, (acc, key)| {
let key_j_addr = NetworkAddress::from_peer(*key);
let closest_i_th_peer_addr = NetworkAddress::from_peer(closest_i_th_peers[j]);

// FIXME: review if we can use this method and/or the ilog2 value

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
acc + key_j_addr
.distance(&closest_i_th_peer_addr)
.ilog2()
.unwrap_or_default() as usize
});

distances / m
}

// Formula 3 in page 7
fn distrib_j_th_largest_prefix_length(j: usize, x: usize) -> f64 {
(0..j).fold(0f64, |acc, i| {
acc + binomial(N, i) as f64
acc + (binomial(N, i) as f64
* (1f64 - 0.5.pow((x + 1) as f64)).pow((N - i) as f64)
* 0.5.pow(((x + 1) * i) as f64)
* 0.5.pow(((x + 1) * i) as f64))
})
}

Expand Down

0 comments on commit a2578fe

Please sign in to comment.