Skip to main content

dkms_wasm/database/indexed_db/
escrow_database.rs

1use std::sync::Arc;
2
3use keri_sdk::database::SequencedEventDatabase;
4use said::SelfAddressingIdentifier;
5
6use keri_core::{
7    database::EscrowDatabase,
8    database::LogDatabase,
9    event::KeyEvent,
10    event_message::{msg::KeriEvent, signed_event_message::SignedEventMessage},
11    prefix::IdentifierPrefix,
12};
13
14use super::IndexedDbError;
15
16pub struct IndexedDbEscrowDatabase {
17    escrow: Arc<
18        dyn SequencedEventDatabase<
19            DatabaseType = (),
20            Error = IndexedDbError,
21            DigestIter = Box<dyn Iterator<Item = said::SelfAddressingIdentifier>>,
22        >,
23    >,
24    log: Arc<super::logging::IndexedDbLogDatabase>,
25}
26
27// SAFETY: In WebAssembly context, there's no true threading, so these are safe
28unsafe impl Send for IndexedDbEscrowDatabase {}
29unsafe impl Sync for IndexedDbEscrowDatabase {}
30
31impl EscrowDatabase for IndexedDbEscrowDatabase {
32    type EscrowDatabaseType = ();
33    type LogDatabaseType = super::logging::IndexedDbLogDatabase;
34    type Error = IndexedDbError;
35    type EventIter = Box<dyn Iterator<Item = SignedEventMessage>>;
36
37    fn new(
38        escrow: Arc<
39            dyn SequencedEventDatabase<
40                DatabaseType = Self::EscrowDatabaseType,
41                Error = Self::Error,
42                DigestIter = Box<dyn Iterator<Item = said::SelfAddressingIdentifier>>,
43            >,
44        >,
45        log: Arc<Self::LogDatabaseType>,
46    ) -> Self
47    where
48        Self: Sized,
49    {
50        Self { escrow, log }
51    }
52
53    fn save_digest(
54        &self,
55        id: &IdentifierPrefix,
56        sn: u64,
57        event_digest: &SelfAddressingIdentifier,
58    ) -> Result<(), Self::Error> {
59        self.escrow.insert(id, sn, event_digest)?;
60
61        Ok(())
62    }
63
64    fn insert(&self, event: &SignedEventMessage) -> Result<(), Self::Error> {
65        self.log
66            .log_event_with_new_transaction(event)?;
67        let said = event.event_message.digest().unwrap();
68        let id = event.event_message.data.get_prefix();
69        let sn = event.event_message.data.sn;
70        self.escrow.insert(&id, sn, &said)?;
71
72        Ok(())
73    }
74
75    fn insert_key_value(
76        &self,
77        id: &IdentifierPrefix,
78        sn: u64,
79        event: &SignedEventMessage,
80    ) -> Result<(), Self::Error> {
81        self.log
82            .log_event_with_new_transaction(event)?;
83        let said = event.event_message.digest().unwrap();
84
85        self.escrow.insert(id, sn, &said)?;
86
87        Ok(())
88    }
89
90    fn get(&self, identifier: &IdentifierPrefix, sn: u64) -> Result<Self::EventIter, Self::Error> {
91        let saids = self.escrow.get(identifier, sn)?;
92        let saids_vec: Vec<_> = saids.collect();
93
94        let log = Arc::clone(&self.log);
95
96        let events = saids_vec.into_iter().filter_map(move |said| {
97            log.get_signed_event(&said)
98                .ok()
99                .flatten()
100                .map(|el| el.signed_event_message)
101        });
102
103        Ok(Box::new(events))
104    }
105
106    fn get_from_sn(
107        &self,
108        identifier: &IdentifierPrefix,
109        sn: u64,
110    ) -> Result<Self::EventIter, Self::Error> {
111        let saids = self.escrow.get_greater_than(identifier, sn)?;
112        let saids_vec: Vec<_> = saids.collect();
113
114        let log = Arc::clone(&self.log);
115
116        let events = saids_vec.into_iter().filter_map(move |said| {
117            log.get_signed_event(&said)
118                .ok()
119                .flatten()
120                .map(|el| el.signed_event_message)
121        });
122
123        Ok(Box::new(events))
124    }
125
126    fn remove(&self, event: &KeriEvent<KeyEvent>) {
127        let said = event.digest().unwrap();
128        let id = event.data.get_prefix();
129        let sn = event.data.sn;
130        self.escrow.remove(&id, sn, &said).unwrap();
131    }
132
133    fn contains(
134        &self,
135        id: &IdentifierPrefix,
136        sn: u64,
137        digest: &SelfAddressingIdentifier,
138    ) -> Result<bool, Self::Error> {
139        Ok(self
140            .escrow
141            .get(id, sn)?
142            .any(|said| &said == digest))
143    }
144}