minerva 0.2.0

Causal ordering for distributed systems
use crate::metis::{DotSet, DotStore, Rhapsody};

/// Encode, decode, and require canonical byte identity where the embedded
/// visible have-set is itself decodable under its anti-DoS dot budget.
pub(super) fn round_trip_rhapsody(rhapsody: &Rhapsody) {
    if !have_set_decodes(rhapsody) {
        return;
    }
    let bytes = rhapsody.to_bytes();
    let decoded =
        Rhapsody::from_bytes(&bytes).expect("a have-set-decodable rhapsody frame decodes");
    assert_eq!(
        decoded.to_bytes(),
        bytes,
        "an accepted rhapsody frame must re-encode identically",
    );
    assert_eq!(
        &decoded, rhapsody,
        "the round trip must preserve the rhapsody"
    );
}

/// Whether the visible have-set re-decodes standalone under its own dot budget.
fn have_set_decodes(rhapsody: &Rhapsody) -> bool {
    let mut visible = DotSet::new();
    for dot in rhapsody.dots() {
        let _ = visible.insert(dot);
    }
    DotSet::from_bytes(&visible.to_bytes()).is_ok()
}