extern crate alloc;
use alloc::vec::Vec;
use core::num::NonZeroUsize;
use crate::kairos::Kairos;
use crate::metis::{Cut, Declaration, Dot, Epochs, SealedEpoch, Stability, VersionVector, Vouched};
#[track_caller]
fn d(station: u32, counter: u64) -> Dot {
Dot::from_parts(station, counter).expect("test literal names the non-dot counter zero")
}
mod examples;
mod properties;
fn rank(physical: u64) -> Kairos {
Kairos::new(physical, 0u16, 1, 0u16)
}
fn vector(entries: &[(u32, u64)]) -> VersionVector {
let mut vector = VersionVector::new();
for &(station, count) in entries {
vector.observe(station, count);
}
vector
}
fn cut(entries: &[(u32, u64)]) -> Cut {
Cut::from_witnessed(vector(entries))
}
fn declaration(roster: &[u32], dot: Dot, tick: u64, at: &[(u32, u64)]) -> Declaration {
let witnessed = cut(at);
let mut stability = Stability::new(roster.iter().copied());
for &station in roster {
stability.report_cut(station, &witnessed).unwrap();
}
let mut epochs = Epochs::new(roster.iter().copied(), NonZeroUsize::new(1).unwrap());
epochs
.declare(dot, rank(tick), &stability, &Cut::bottom())
.expect("the fixture dot is fresh above the fixture cut")
}
pub(in crate::metis::tests) fn displaced_window() -> (Epochs, SealedEpoch) {
let mut epochs = Epochs::new([1, 2], NonZeroUsize::new(2).unwrap());
let later = declaration(&[1, 2], d(1, 3), 9, &[(1, 2), (2, 3)]);
let mut stability = Stability::new([1, 2]);
for station in [1, 2] {
stability
.report_cut(station, &cut(&[(1, 2), (2, 3)]))
.unwrap();
}
epochs
.deliver(later, &stability, &Cut::bottom())
.expect("the later declaration opens the window");
let winner = declaration(&[1, 2], d(2, 3), 7, &[(1, 2), (2, 2)]);
let address = winner.address();
epochs
.deliver(winner, &stability, &Cut::bottom())
.expect("the predecessor displaces the later record");
assert_eq!(
epochs.candidates().count(),
1,
"the displaced record left the candidate antichain"
);
let delivered = cut(&[(1, 3), (2, 3)]);
let mut stability = Stability::new([1, 2]);
for station in [1, 2] {
stability.report_cut(station, &delivered).unwrap();
}
epochs
.confirm(address, &Vouched::trust(1, delivered.clone()))
.unwrap();
epochs
.confirm(address, &Vouched::trust(2, delivered.clone()))
.unwrap();
let _ = epochs.adopt(1, 3, &stability).unwrap();
epochs.adopt_report(address, &Vouched::trust(2, 3)).unwrap();
let sealed = epochs
.try_seal(&stability)
.expect("the adoption round is complete")
.clone();
assert_eq!(sealed.declaration(), address);
let dots: Vec<Dot> = sealed.declaration_dots().collect();
assert_eq!(
dots,
[d(1, 3), d(2, 3)],
"the ledger keeps the displaced dot the candidates lost"
);
(epochs, sealed)
}