chio_kernel/
revocation_runtime.rs1use std::collections::HashSet;
2use std::sync::{Mutex, MutexGuard};
3
4use crate::{budget_store::RevocationCommitMetadata, RevocationStoreError};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct RevocationObservation {
8 pub revoked: bool,
9 pub commit: Option<RevocationCommitMetadata>,
10}
11
12pub trait RevocationStore: Send + Sync {
17 fn is_revoked(&self, capability_id: &str) -> Result<bool, RevocationStoreError>;
19
20 fn revoke(&self, capability_id: &str) -> Result<bool, RevocationStoreError>;
22
23 fn observe_revocation(
24 &self,
25 capability_id: &str,
26 ) -> Result<RevocationObservation, RevocationStoreError> {
27 Ok(RevocationObservation {
28 revoked: self.is_revoked(capability_id)?,
29 commit: None,
30 })
31 }
32
33 fn is_ephemeral(&self) -> bool {
37 true
38 }
39}
40
41#[derive(Debug, Default)]
43pub struct InMemoryRevocationStore {
44 revoked: Mutex<HashSet<String>>,
45}
46
47impl InMemoryRevocationStore {
48 pub fn new() -> Self {
50 Self::default()
51 }
52
53 fn revoked(&self) -> Result<MutexGuard<'_, HashSet<String>>, RevocationStoreError> {
54 self.revoked.lock().map_err(|_| {
55 RevocationStoreError::Sync("in-memory revocation store lock poisoned".to_string())
56 })
57 }
58}
59
60impl RevocationStore for InMemoryRevocationStore {
61 fn is_revoked(&self, capability_id: &str) -> Result<bool, RevocationStoreError> {
62 Ok(self.revoked()?.contains(capability_id))
63 }
64
65 fn revoke(&self, capability_id: &str) -> Result<bool, RevocationStoreError> {
66 Ok(self.revoked()?.insert(capability_id.to_owned()))
67 }
68}