saddle-db 0.3.0-alpha.3

Saddle managed asynchronous database access and transactions
Documentation
//! Linear Database authority for the fixed termination work domain.
//!
//! The copyable component facts remain implementation inputs to the DB
//! verifier.  Cross-crate composition receives only this opaque owner.

use crate::c1_normal_return::{DbNormalReturnWorkProof, db_normal_return_work_proof};

const OWNER_DOMAIN: &[u8] = b"saddle.db.termination-work-owner.v1";

/// Database-issued authority for its fixed normal-return termination work.
///
/// Fields are private and the type deliberately implements neither `Clone`,
/// `Copy`, `Debug`, serialization nor an open adapter trait.
///
/// ```compile_fail
/// use saddle_db::internal::VerifiedDbTerminationWorkOwner;
/// fn duplicate(owner: VerifiedDbTerminationWorkOwner) {
///     let _ = owner.clone();
/// }
/// ```
///
/// ```compile_fail
/// use saddle_db::internal::VerifiedDbTerminationWorkOwner;
/// let _ = VerifiedDbTerminationWorkOwner { };
/// ```
#[doc(hidden)]
pub struct VerifiedDbTerminationWorkOwner {
    work: DbNormalReturnWorkProof,
    seal: [u8; 32],
}

/// The sole Database-owned issuer. It accepts no caller-supplied identity,
/// topology, generation, work value or trait implementation.
#[doc(hidden)]
pub fn issue_verified_db_termination_work_owner() -> VerifiedDbTerminationWorkOwner {
    let work = db_normal_return_work_proof();
    VerifiedDbTerminationWorkOwner {
        seal: seal(work),
        work,
    }
}

/// Revalidates the Database-owned work fact without exposing it. A failure
/// returns the exact same linear owner so a later atomic composer can restore
/// all inputs before reporting rejection.
#[doc(hidden)]
pub fn validate_verified_db_termination_work_owner(
    owner: VerifiedDbTerminationWorkOwner,
) -> Result<VerifiedDbTerminationWorkOwner, VerifiedDbTerminationWorkOwner> {
    if owner.seal == seal(owner.work) {
        Ok(owner)
    } else {
        Err(owner)
    }
}

fn seal(work: DbNormalReturnWorkProof) -> [u8; 32] {
    let mut output = work.identity();
    for (index, byte) in OWNER_DOMAIN.iter().enumerate() {
        let slot = index % output.len();
        output[slot] = output[slot]
            .wrapping_add(*byte)
            .rotate_left((index % 7) as u32);
    }
    output
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn database_issues_and_consumes_the_only_concrete_work_shape() {
        let owner = issue_verified_db_termination_work_owner();
        let _owner = validate_verified_db_termination_work_owner(owner)
            .unwrap_or_else(|_| panic!("Database-issued termination work owner must validate"));
    }

    #[test]
    fn validation_failure_restores_the_same_owner() {
        let mut owner = issue_verified_db_termination_work_owner();
        let original_work = owner.work.identity();
        owner.seal[0] ^= 1;
        let restored = validate_verified_db_termination_work_owner(owner)
            .err()
            .expect("foreign seal must be recoverable");
        assert_eq!(restored.work.identity(), original_work);
        assert_ne!(restored.seal, seal(restored.work));
    }
}