Implement filler v1 (#698)
This commit is contained in:
parent
5f5b394017
commit
fcb903c14a
@ -4,3 +4,8 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libp2p-identity = { version = "0.2", features = ["peerid"] }
|
||||||
|
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
libp2p-identity = { version = "0.2", features = ["rand"] }
|
@ -1,3 +1,5 @@
|
|||||||
|
pub mod versions;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
pub mod v1;
|
88
nomos-da/network/subnetworks-assignations/src/versions/v1.rs
Normal file
88
nomos-da/network/subnetworks-assignations/src/versions/v1.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use crate::MembershipHandler;
|
||||||
|
use libp2p_identity::PeerId;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
/// Fill a `N` sized set of "subnetworks" from a list of peer ids members
|
||||||
|
pub struct FillFromNodeList {
|
||||||
|
pub assignations: Vec<HashSet<PeerId>>,
|
||||||
|
pub subnetwork_size: usize,
|
||||||
|
pub dispersal_factor: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FillFromNodeList {
|
||||||
|
pub fn new(peers: &[PeerId], subnetwork_size: usize, dispersal_factor: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
assignations: Self::fill(peers, subnetwork_size, dispersal_factor),
|
||||||
|
subnetwork_size,
|
||||||
|
dispersal_factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(
|
||||||
|
peers: &[PeerId],
|
||||||
|
subnetwork_size: usize,
|
||||||
|
replication_factor: usize,
|
||||||
|
) -> Vec<HashSet<PeerId>> {
|
||||||
|
assert!(!peers.is_empty());
|
||||||
|
// sort list to make it deterministic
|
||||||
|
let mut peers = peers.to_vec();
|
||||||
|
peers.sort_unstable();
|
||||||
|
// take n peers and fill a subnetwork until all subnetworks are filled
|
||||||
|
let mut cycle = peers.into_iter().cycle();
|
||||||
|
(0..subnetwork_size)
|
||||||
|
.map(|_| {
|
||||||
|
(0..replication_factor)
|
||||||
|
.map(|_| cycle.next().unwrap())
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MembershipHandler for FillFromNodeList {
|
||||||
|
type NetworkId = u16;
|
||||||
|
type Id = PeerId;
|
||||||
|
|
||||||
|
fn membership(&self, id: &Self::Id) -> HashSet<Self::NetworkId> {
|
||||||
|
self.assignations
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(netowrk_id, subnetwork)| {
|
||||||
|
subnetwork
|
||||||
|
.contains(id)
|
||||||
|
.then_some(netowrk_id as Self::NetworkId)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_allowed(&self, id: &Self::Id) -> bool {
|
||||||
|
for subnetwork in &self.assignations {
|
||||||
|
if subnetwork.contains(id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn members_of(&self, network_id: &Self::NetworkId) -> HashSet<Self::Id> {
|
||||||
|
self.assignations[*network_id as usize].clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::versions::v1::FillFromNodeList;
|
||||||
|
use libp2p_identity::PeerId;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_distribution_fill_from_node_list() {
|
||||||
|
let nodes: Vec<_> = std::iter::repeat_with(PeerId::random).take(100).collect();
|
||||||
|
let replication_factor = 2;
|
||||||
|
let subnetwork_size = 1024;
|
||||||
|
let distribution = FillFromNodeList::new(&nodes, subnetwork_size, replication_factor);
|
||||||
|
assert_eq!(distribution.assignations.len(), subnetwork_size);
|
||||||
|
for subnetwork in &distribution.assignations {
|
||||||
|
assert_eq!(subnetwork.len(), replication_factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user