clawft_kernel/licence/
store_sync.rs1use std::ops::Bound;
6
7use super::{
8 ApprovalStore, CheckoutGrantStore, SignedApproval, SignedBinding, SignedEnvelope, SignedGrant,
9};
10
11impl CheckoutGrantStore {
12 pub fn held_signed_binding(&self) -> Option<(u64, SignedBinding)> {
16 let local = self.local_mesh_id().get()?.to_hex();
17 let g = self.lock();
18 if g.poisoned.is_some() {
19 return None;
20 }
21 let h = g.binding.as_ref().filter(|h| h.body.mesh_id == local)?;
22 Some((h.body.seq, h.signed.clone()))
23 }
24
25 pub fn bound_grant_key(&self) -> Option<String> {
27 self.run(|g, ev| self.binding_in_effect(g, ev).ok().map(|b| b.grant_pubkey))
28 }
29
30 pub fn held_grant(&self, cog_id: &str, version: &str) -> Option<(u64, SignedGrant)> {
32 let g = self.lock();
33 let h = g
34 .slots
35 .get(&(cog_id.to_owned(), version.to_owned()))?
36 .current
37 .as_ref()?;
38 Some((h.body.seq, h.signed.clone()))
39 }
40
41 pub fn sync_grants_page(
48 &self,
49 after: Option<(u64, &str, &str)>,
50 max_entries: usize,
51 max_bytes: usize,
52 ) -> (Vec<(u64, String, String, SignedGrant)>, bool) {
53 self.run(|g, ev| {
54 if self.binding_in_effect(g, ev).is_err() {
55 return (Vec::new(), false);
56 }
57 let mut keys: Vec<(u64, &String, &String)> = g
58 .slots
59 .iter()
60 .filter_map(|((cog, ver), s)| Some((s.current.as_ref()?.body.seq, cog, ver)))
61 .filter(|(seq, cog, ver)| {
62 after.is_none_or(|(s, c, v)| (*seq, cog.as_str(), ver.as_str()) > (s, c, v))
63 })
64 .collect();
65 keys.sort();
66 let (mut out, mut bytes) = (Vec::new(), 0usize);
67 for (seq, cog, ver) in &keys {
68 let h = g.slots[&((*cog).clone(), (*ver).clone())].current.as_ref();
69 let Some(h) = h else { continue };
70 let n = env_size(&h.signed);
71 if out.len() >= max_entries || bytes + n > max_bytes {
72 return (out, true);
73 }
74 bytes += n;
75 out.push((*seq, (*cog).clone(), (*ver).clone(), h.signed.clone()));
76 }
77 (out, false)
78 })
79 }
80}
81
82pub(super) fn env_size(e: &SignedEnvelope) -> usize {
84 e.payload.len() + e.public_key.len() + e.signature.len()
85}
86
87impl ApprovalStore {
88 pub fn holds(&self, content_key: &str) -> bool {
90 self.lock().0.contains_key(content_key)
91 }
92
93 pub fn sync_approvals_page(
98 &self,
99 after: Option<&str>,
100 max_entries: usize,
101 max_bytes: usize,
102 ) -> (Vec<(String, SignedApproval)>, bool) {
103 let Some(local) = self.local.get().map(|m| m.to_hex()) else {
104 return (Vec::new(), false);
105 };
106 let g = self.lock();
107 if g.1.is_some() {
108 return (Vec::new(), false);
109 }
110 let from = after.map_or(Bound::Unbounded, |a| Bound::Excluded(a.to_owned()));
111 let (mut out, mut bytes) = (Vec::new(), 0usize);
112 for (k, (s, a)) in g.0.range((from, Bound::Unbounded)) {
113 if a.mesh_id != local {
114 continue;
115 }
116 let n = env_size(s);
117 if out.len() >= max_entries || bytes + n > max_bytes {
118 return (out, true);
119 }
120 bytes += n;
121 out.push((k.clone(), s.clone()));
122 }
123 (out, false)
124 }
125}