use super::*;
use std::cmp;
mod graph_based;
mod ideal;
mod random;
mod super_safe;
pub use graph_based::*;
pub use ideal::*;
pub use random::*;
pub use super_safe::*;
#[derive(Default)]
pub struct DummyQsc;
impl QuorumSetConfigurator for DummyQsc {
fn configure(&self, _: NodeId, _: &mut Fbas) -> ChangeEffect {
NoChange
}
}
fn calculate_threshold(n: usize, relative_threshold: Option<f64>) -> usize {
if let Some(x) = relative_threshold {
calculate_x_threshold(n, x)
} else {
calculate_67p_threshold(n)
}
}
pub fn calculate_67p_threshold(n: usize) -> usize {
n - ((n as f64 - 1.) / 3.).floor() as usize
}
pub fn calculate_x_threshold(n: usize, x: f64) -> usize {
cmp::max(1, (x * n as f64).ceil() as usize)
}
#[cfg(test)]
mod tests {
use super::*;
#[macro_export]
macro_rules! assert_is_67p_threshold {
($t:expr, $n:expr) => {
assert!(3 * $t >= 2 * $n + 1, "Not a 67% threshold!")
};
}
#[macro_export]
macro_rules! assert_has_67p_threshold {
($qset:expr) => {
assert_is_67p_threshold!(
$qset.threshold,
$qset.validators.len() + $qset.inner_quorum_sets.len()
);
};
}
#[macro_export]
macro_rules! simulate {
($qsc:expr, $n:expr) => {{
let mut simulator =
Simulator::new(Fbas::new(), Rc::new($qsc), Rc::new(monitors::DummyMonitor));
simulator.simulate_growth($n);
simulator.finalize()
}};
}
#[test]
fn calculate_67p_threshold_up_to_20() {
for n in 1..20 {
assert_is_67p_threshold!(calculate_67p_threshold(n), n);
}
}
#[test]
fn calculate_relative_threshold_is_at_least_1() {
assert_eq!(calculate_x_threshold(0, 0.51), 1);
assert_eq!(calculate_x_threshold(100, 0.), 1);
}
}