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