minerva 0.2.0

Causal ordering for distributed systems
//! Production epoch-shadow and seal-consignment assurance.

extern crate alloc;

mod consignment;
mod shadow;

use alloc::vec::Vec;
use core::num::NonZeroUsize;

use crate::kairos::Kairos;
use crate::metis::{
    Adopted, Anchor, Cut, Dot, DotSet, Dotted, EpochConsignmentError, EpochIdeal, EpochShadow,
    EpochStratum, Epochs, Event, Locus, Metatheses, Metathesis, Rhapsody, SealedEpoch, Stability,
    VersionVector, Vouched,
};

/// Builds an identity literal. Panics on the non-dot counter zero (R-91).
#[track_caller]
fn d(station: u32, counter: u64) -> Dot {
    Dot::from_parts(station, counter).expect("test literal names the non-dot counter zero")
}

type Text = Dotted<Rhapsody>;
type Moves = Dotted<Metatheses>;

fn rank(physical_ns: u64) -> Kairos {
    Kairos::new(physical_ns, 0, 1, 0u16)
}

fn locus(anchor: Anchor, rank: Kairos) -> Locus {
    Locus { anchor, rank }
}

fn weave(text: &mut Text, dot: Dot, locus: Locus) {
    let mut delta = Rhapsody::new();
    assert!(delta.weave(dot, locus));
    text.merge_from(&Dotted::from_store(delta));
}

fn remove(text: &mut Text, dot: Dot) {
    let mut context = DotSet::new();
    assert!(context.insert(dot));
    text.merge_from(&Dotted::from_context(context));
}

fn movement(testimony: Dot, target: (u32, u64), anchor: Anchor, rank: Kairos) -> Moves {
    Dotted::from_store(Metatheses::singleton(
        testimony,
        Metathesis {
            target: target.into(),
            to: locus(anchor, rank),
        },
    ))
}

fn adopted_over(dot: Dot, boundary: &Cut) -> Adopted {
    let mut stability = Stability::new([1, 2]);
    stability.report_cut(1, boundary).unwrap();
    stability.report_cut(2, boundary).unwrap();
    let mut epochs = Epochs::new([1, 2], NonZeroUsize::new(1).unwrap());
    let declaration = epochs
        .declare(dot, rank(dot.counter()), &stability, &Cut::bottom())
        .unwrap();
    let mut delivered = boundary.as_vector().clone();
    delivered.observe(dot.station(), dot.counter());
    let delivered = Cut::from_witnessed(delivered);
    stability.report_cut(1, &delivered).unwrap();
    stability.report_cut(2, &delivered).unwrap();
    epochs
        .confirm(declaration.address(), &Vouched::trust(1, delivered.clone()))
        .unwrap();
    epochs
        .confirm(declaration.address(), &Vouched::trust(2, delivered.clone()))
        .unwrap();
    epochs
        .adopt(1, delivered.as_vector().get(1), &stability)
        .unwrap_or_else(|error| panic!("declaration {declaration:?} should adopt: {error}"))
}

fn adopted(dot: Dot) -> Adopted {
    let mut vector = VersionVector::new();
    vector.observe(1, 9);
    vector.observe(2, 9);
    adopted_over(dot, &Cut::from_witnessed(vector))
}

fn open_shadow(text: Text, moves: Moves) -> EpochShadow {
    let coverage = text.context().merge(moves.context());
    let boundary = Cut::floor_of(&coverage);
    let adopted = adopted_over(
        d(1, boundary.as_vector().get(1).saturating_add(1)),
        &boundary,
    );
    EpochStratum::new(&adopted, text, moves)
        .unwrap()
        .into_transition()
        .shadow
}

fn text_delta(dot: Dot, locus: Locus) -> Text {
    let mut text = Rhapsody::new();
    assert!(text.weave(dot, locus));
    Dotted::from_store(text)
}