Implement filler v1 (#698)
This commit is contained in:
parent
5f5b394017
commit
fcb903c14a
@ -4,3 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[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::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