minerva 0.2.0

Causal ordering for distributed systems
extern crate alloc;

use alloc::vec::Vec;

use crate::metis::{DotSet, Rhapsody, RhapsodyDecodeError};

use super::super::d;
use super::rank;

#[test]
fn test_rhapsody_rejects_malformed_visible_suffix() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u64.to_be_bytes());
    bytes.push(0x00);
    bytes.extend_from_slice(&rank(1).to_bytes());
    bytes.push(0x02u8);
    bytes.extend_from_slice(&0u32.to_be_bytes());
    assert!(matches!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::Visible(_))
    ));
}

/// The suffix budget is the skeleton's cardinality (S197 gate review): a
/// suffix claiming more dots than the frame's loci vouch for refuses, even
/// where the standalone have-set frame's byte-length budget would also
/// refuse it for its own reason. Here one locus backs a 38-dot suffix, so
/// the budget of one refuses; the legal dense-above-a-hole case (a skeleton
/// as large as its visible set) round-trips, pinned in the snapshot suite
/// (`test_a_deleted_low_dot_survives_the_suffix_budget`, both codecs).
#[test]
fn test_rhapsody_suffix_budget_is_the_skeleton() {
    let mut dense = DotSet::new();
    for index in 2..=39u64 {
        let _ = dense.insert(d(1, index));
    }
    let dense_frame = dense.to_bytes();
    assert!(
        DotSet::from_bytes(&dense_frame).is_err(),
        "the standalone have-set keeps its own byte-length budget (PRD 0016)",
    );

    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&2u64.to_be_bytes());
    bytes.push(0x00);
    bytes.extend_from_slice(&rank(1).to_bytes());
    bytes.extend_from_slice(&dense_frame);
    assert!(matches!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::Visible(_))
    ));
}

#[test]
fn test_rhapsody_rejects_malformed_rank() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u64.to_be_bytes());
    bytes.push(0x00);
    bytes.push(0x02u8);
    bytes.extend_from_slice(&[0u8; 16]);
    bytes.push(0x01u8);
    bytes.extend_from_slice(&0u32.to_be_bytes());
    assert!(matches!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::Rank(_))
    ));
}