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