praborrow_core/
lib.rs

1//! Core primitives for distributed ownership enforcement.
2//!
3//! This crate provides `Sovereign<T>`, a wrapper type that tracks ownership
4//! across network boundaries. When a resource is "annexed" (moved to another node),
5//! local access is prohibited.
6//!
7//! # The Garuda Proof System
8//!
9//! With `praborrow-prover`, this crate now supports **formally verified** state
10//! transitions. Use `annex_verified()` to require SMT proof before annexation.
11//!
12//! # Safety
13//! Uses `UnsafeCell` and `AtomicU8` for interior mutability with thread-safety.
14//! The `Send`/`Sync` implementations are safe when `T` is `Send`/`Sync`.
15
16use std::ops::{Deref, DerefMut};
17use std::sync::atomic::{AtomicU8, Ordering};
18use std::cell::UnsafeCell;
19use std::marker::PhantomData;
20
21/// The state of a Sovereign resource.
22/// 0: Domestic (Local jurisdiction)
23/// 1: Exiled (Foreign jurisdiction - moved to another node)
24#[derive(Debug, PartialEq, Eq, Clone, Copy)]
25#[repr(u8)]
26pub enum SovereignState {
27    Domestic = 0,
28    Exiled = 1,
29}
30
31/// A wrapper that enforces ownership semantics across network boundaries.
32///
33/// "Memory safety with sovereign integrity."
34pub struct Sovereign<T> {
35    inner: UnsafeCell<T>,
36    state: AtomicU8,
37}
38
39impl<T> Sovereign<T> {
40    /// Creates a new Sovereign resource under domestic jurisdiction.
41    pub fn new(value: T) -> Self {
42        Self {
43            inner: UnsafeCell::new(value),
44            state: AtomicU8::new(SovereignState::Domestic as u8),
45        }
46    }
47
48    /// Annexes the resource, moving it to foreign jurisdiction.
49    ///
50    /// Once annexed, the resource cannot be accessed locally.
51    /// Access attempts will result in a Sovereignty Violation (panic).
52    pub fn annex(&self) -> Result<(), String> {
53        let current = self.state.load(Ordering::SeqCst);
54        if current == SovereignState::Exiled as u8 {
55            return Err("Resource is already under foreign jurisdiction.".to_string());
56        }
57
58        // Diplomatically transition state
59        self.state.store(SovereignState::Exiled as u8, Ordering::SeqCst);
60        Ok(())
61    }
62
63    /// Returns a reference to the inner value without jurisdiction check.
64    ///
65    /// # Safety
66    /// This is safe because we're returning a shared reference and the caller
67    /// is responsible for ensuring the resource is domestic.
68    pub fn inner_ref(&self) -> &T {
69        // SAFETY: We're only reading, and this is safe when called from
70        // contexts that have already verified jurisdiction.
71        unsafe { &*self.inner.get() }
72    }
73
74    /// Returns the current state of the resource.
75    pub fn state(&self) -> SovereignState {
76        match self.state.load(Ordering::SeqCst) {
77            0 => SovereignState::Domestic,
78            _ => SovereignState::Exiled,
79        }
80    }
81
82    /// Checks if the resource is currently domestic.
83    fn verify_jurisdiction(&self) {
84        if self.state.load(Ordering::SeqCst) == SovereignState::Exiled as u8 {
85            panic!("SOVEREIGNTY VIOLATION: Resource is under foreign jurisdiction.");
86        }
87    }
88}
89
90impl<T> Deref for Sovereign<T> {
91    type Target = T;
92
93    fn deref(&self) -> &Self::Target {
94        self.verify_jurisdiction();
95        // SAFETY: We've verified the resource is domestic, so access is valid.
96        unsafe { &*self.inner.get() }
97    }
98}
99
100impl<T> DerefMut for Sovereign<T> {
101    fn deref_mut(&mut self) -> &mut Self::Target {
102        self.verify_jurisdiction();
103        // SAFETY: We've verified the resource is domestic and have &mut self.
104        unsafe { &mut *self.inner.get() }
105    }
106}
107
108// SAFETY: Sovereign<T> is Send/Sync if T is Send/Sync, as we use AtomicU8 for state
109// and check it before access. The UnsafeCell is protected by the atomic state check.
110unsafe impl<T: Send> Send for Sovereign<T> {}
111unsafe impl<T: Sync> Sync for Sovereign<T> {}
112
113/// Protocol for enforcing constitutional invariants (runtime checks).
114pub trait CheckProtocol {
115    /// Enforces all invariants, panicking if any are violated.
116    fn enforce_law(&self);
117}
118
119/// A value carrying cryptographic proof of verification.
120///
121/// This type can only be constructed by successful SMT verification.
122/// Its existence in a type signature proves that formal verification occurred.
123///
124/// # Type Safety Guarantee
125///
126/// `ProofCarrying<T>` cannot be forged - the private `_proof` field
127/// ensures only the prover crate can construct it.
128#[derive(Debug)]
129pub struct ProofCarrying<T> {
130    /// The carried value.
131    pub value: T,
132    /// Private marker ensuring construction only via verification.
133    _proof: PhantomData<()>,
134}
135
136impl<T> ProofCarrying<T> {
137    /// Creates a new proof-carrying value.
138    ///
139    /// This should only be called after successful verification.
140    #[doc(hidden)]
141    pub fn new_unchecked(value: T) -> Self {
142        Self {
143            value,
144            _proof: PhantomData,
145        }
146    }
147
148    /// Extracts the inner value, consuming the proof.
149    pub fn into_inner(self) -> T {
150        self.value
151    }
152}
153
154impl<T: Clone> Clone for ProofCarrying<T> {
155    fn clone(&self) -> Self {
156        Self {
157            value: self.value.clone(),
158            _proof: PhantomData,
159        }
160    }
161}
162
163/// Error type for verified annexation operations.
164#[derive(Debug, Clone, PartialEq, Eq)]
165pub enum AnnexError {
166    /// Resource is already under foreign jurisdiction.
167    AlreadyExiled,
168    /// SMT verification failed.
169    VerificationFailed(String),
170    /// Prover encountered an error.
171    ProverError(String),
172}
173
174impl std::fmt::Display for AnnexError {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176        match self {
177            AnnexError::AlreadyExiled => write!(f, "Resource is already under foreign jurisdiction"),
178            AnnexError::VerificationFailed(msg) => write!(f, "Verification failed: {}", msg),
179            AnnexError::ProverError(msg) => write!(f, "Prover error: {}", msg),
180        }
181    }
182}
183
184impl std::error::Error for AnnexError {}
185
186/// Error returned when a lease operation fails.
187#[derive(Debug, Clone, PartialEq, Eq)]
188pub enum LeaseError {
189    /// Resource is already leased to another holder.
190    AlreadyLeased,
191    /// Resource is under foreign jurisdiction.
192    ForeignJurisdiction,
193}
194
195/// Represents a lease on a Sovereign resource.
196pub struct Lease<T> {
197    /// The holder's unique identifier.
198    pub holder: u128,
199    /// Duration of the lease.
200    pub duration: std::time::Duration,
201    /// Phantom data for the resource type.
202    _phantom: PhantomData<T>,
203}
204
205impl<T> Lease<T> {
206    /// Creates a new lease.
207    pub fn new(holder: u128, duration: std::time::Duration) -> Self {
208        Self {
209            holder,
210            duration,
211            _phantom: PhantomData,
212        }
213    }
214}
215
216/// Trait for distributed borrow operations.
217pub trait DistributedBorrow<T> {
218    /// Attempt to acquire a lease on the resource.
219    fn try_hire(&self, candidate_id: u128, term: std::time::Duration) -> Result<Lease<T>, LeaseError>;
220}
221
222impl<T> DistributedBorrow<T> for Sovereign<T> {
223    fn try_hire(&self, candidate_id: u128, term: std::time::Duration) -> Result<Lease<T>, LeaseError> {
224        let current = self.state.load(Ordering::SeqCst);
225        if current == SovereignState::Exiled as u8 {
226            return Err(LeaseError::AlreadyLeased);
227        }
228        
229        // Transition to exiled state (leased)
230        self.state.store(SovereignState::Exiled as u8, Ordering::SeqCst);
231        Ok(Lease::new(candidate_id, term))
232    }
233}
234
235/// Extension trait for Sovereign types whose inner types implement formal verification.
236///
237/// This trait is automatically implemented for `Sovereign<T>` where `T` can be
238/// formally verified via the Garuda Proof System.
239pub trait VerifiedAnnex<T> {
240    /// Annexes the resource after successful formal verification.
241    ///
242    /// Unlike `annex()`, this method requires mathematical proof that all
243    /// invariants are satisfied before the state transition occurs.
244    ///
245    /// # Returns
246    ///
247    /// - `Ok(ProofCarrying<()>)` - Verification passed, resource is now Exiled
248    /// - `Err(AnnexError)` - Verification failed or resource already Exiled
249    ///
250    /// # Example
251    ///
252    /// ```ignore
253    /// use praborrow_core::{Sovereign, VerifiedAnnex};
254    ///
255    /// let resource = Sovereign::new(MyVerifiableStruct { balance: 100 });
256    /// 
257    /// // This will run SMT verification before annexing
258    /// match resource.annex_verified() {
259    ///     Ok(proof) => println!("Annexation proven safe!"),
260    ///     Err(e) => println!("Cannot annex: {}", e),
261    /// }
262    /// ```
263    fn annex_verified(&self) -> Result<ProofCarrying<()>, AnnexError>;
264}
265
266// Note: The actual implementation of VerifiedAnnex requires praborrow-prover,
267// which would create a circular dependency. Instead, the implementation is
268// provided via blanket impl in praborrow-prover or via the facade crate.
269//
270// Users should use the `praborrow` facade crate for full functionality.
271
272#[cfg(test)]
273mod tests {
274    use super::*;
275
276    #[test]
277    fn test_sovereign_new() {
278        let s = Sovereign::new(42i32);
279        assert_eq!(s.state(), SovereignState::Domestic);
280    }
281
282    #[test]
283    fn test_sovereign_deref() {
284        let s = Sovereign::new(42i32);
285        assert_eq!(*s, 42);
286    }
287
288    #[test]
289    fn test_sovereign_deref_mut() {
290        let mut s = Sovereign::new(42i32);
291        *s = 100;
292        assert_eq!(*s, 100);
293    }
294
295    #[test]
296    fn test_sovereign_annex() {
297        let s = Sovereign::new(42i32);
298        assert!(s.annex().is_ok());
299        assert_eq!(s.state(), SovereignState::Exiled);
300    }
301
302    #[test]
303    fn test_sovereign_double_annex() {
304        let s = Sovereign::new(42i32);
305        assert!(s.annex().is_ok());
306        assert!(s.annex().is_err());
307    }
308
309    #[test]
310    #[should_panic(expected = "SOVEREIGNTY VIOLATION")]
311    fn test_sovereignty_violation() {
312        let s = Sovereign::new(42i32);
313        s.annex().unwrap();
314        let _ = *s; // This should panic
315    }
316
317    #[test]
318    fn test_proof_carrying() {
319        let proof = ProofCarrying::new_unchecked(42i32);
320        assert_eq!(proof.value, 42);
321        assert_eq!(proof.into_inner(), 42);
322    }
323
324    #[test]
325    fn test_annex_error_display() {
326        let e = AnnexError::AlreadyExiled;
327        assert!(e.to_string().contains("foreign jurisdiction"));
328        
329        let e = AnnexError::VerificationFailed("test".to_string());
330        assert!(e.to_string().contains("test"));
331    }
332}