Skip to content

Commit

Permalink
draft: formula to get num peers per cpl
Browse files Browse the repository at this point in the history
  • Loading branch information
bochaco committed Apr 8, 2024
1 parent 3f6b45c commit 0522e65
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
16 changes: 9 additions & 7 deletions sn_networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,17 +817,19 @@ impl Network {

/// Using a random address, check if there is a sybil attack around it
pub async fn perform_sybil_attack_check(&self) {
let random_addr = {
let (random_addr, cid) = {
let mut rng = rand::thread_rng();
let chunk_addr = ChunkAddress::new(XorName::random(&mut rng));
NetworkAddress::from_chunk_address(chunk_addr)
let cid = XorName::random(&mut rng);
let chunk_addr = ChunkAddress::new(cid);
(NetworkAddress::from_chunk_address(chunk_addr), cid)
};

match self.get_closest_peers(&random_addr, true).await {
Ok(closest_peers) => match check_for_sybil_attack(&closest_peers).await {
Ok(is_attack) => info!(">>> Sybil attack detection result: {is_attack}"),
Err(err) => error!(">>> Failed to check for sybil attack: {err:?}"),
},
Ok(closest_peers) => {
if check_for_sybil_attack(&closest_peers, &cid).await {
info!(">>> Sybil attack detected around xorname: {cid}");
}
}
Err(err) => error!(">>> Failed to get closes peer to check for sybil attack: {err:?}"),
}
}
Expand Down
39 changes: 27 additions & 12 deletions sn_networking/src/sybil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
// 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::Result;

use libp2p::PeerId;
use num::{integer::binomial, pow::Pow};
use xor_name::{XorName, XOR_NAME_LEN};

// Threshold to determine if there is an attack using Kullback-Liebler (KL) divergence
// between model peer ids distribution vs. actual distribution around any point in the address space.
Expand All @@ -18,31 +17,47 @@ 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

pub(super) async fn check_for_sybil_attack(peers: &[PeerId]) -> Result<bool> {
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!(
">>> CHECKING SYBIL ATTACK WITH {} PEERS: {peers:?}",
peers.len()
);
let q = num_peers_per_cpl(peers)? / K;
let n = get_net_size_estimate()?;
let q = num_peers_per_cpl(peers, cid);
let n = get_net_size_estimate();
let p = compute_model_distribution(n);
info!(">>> MODEL DIST WITH {} PEERS: {p}", peers.len());
let kl_divergence = compute_kl_divergence(p, q);

let is_attack = kl_divergence > KL_DIVERGENCE_THRESHOLD;
Ok(is_attack)
kl_divergence > KL_DIVERGENCE_THRESHOLD
}

// Formula 6 in page 7
fn num_peers_per_cpl(peers: &[PeerId]) -> Result<usize> {
// TODO!
Ok(0usize)
fn num_peers_per_cpl(peers: &[PeerId], cid: &XorName) -> usize {
let peers_per_cpl = peers.iter().fold(0, |acc, peer| {
let peer_kad_id = XorName::from_content(&peer.to_bytes());
acc + common_prefix(&peer_kad_id, cid)
});

peers_per_cpl / K
}

// TODO: this is a copy of the private XorName::common_prefix method which could be made public.

Check notice

Code scanning / devskim

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

Suspicious comment
/// Returns the length of the common prefix with the `other` name; e. g.
/// the when `other = 11110000` and `self = 11111111` this is 4.
fn common_prefix(lhs: &XorName, rhs: &XorName) -> usize {
for byte_index in 0..XOR_NAME_LEN {
if lhs[byte_index] != rhs[byte_index] {
return (byte_index * 8) + (lhs[byte_index] ^ rhs[byte_index]).leading_zeros() as usize;
}
}
8 * XOR_NAME_LEN
}

// Formula 1 and 2 in page ??
fn get_net_size_estimate() -> Result<usize> {
fn get_net_size_estimate() -> usize {
// TODO!

Check notice

Code scanning / devskim

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

Suspicious comment
Ok(N)
N
}

// Formula 3 in page 7
Expand Down

0 comments on commit 0522e65

Please sign in to comment.