Skip to main content

dkms_wasm/database/in_memory/
logging.rs

1use keri_core::database::LogDatabase;
2use super::InMemoryDbError;
3use std::sync::{Arc, RwLock};
4use std::collections::HashMap;
5use keri_core::event_message::signature::{Nontransferable, Transferable};
6use keri_core::event::KeyEvent;
7use keri_core::event_message::msg::KeriEvent;
8use keri_core::event_message::signed_event_message::{ SignedEventMessage, SignedNontransferableReceipt };
9use keri_core::database::timestamped::TimestampedSignedEventMessage;
10use keri_core::prefix::IndexedSignature;
11use said::SelfAddressingIdentifier;
12
13pub struct InMemoryLogDatabase {
14    events: RwLock<HashMap<String, TimestampedSignedEventMessage>>,
15    signatures: RwLock<HashMap<String, Vec<IndexedSignature>>>,
16    nontrans_receipts: RwLock<HashMap<String, Vec<Nontransferable>>>,
17    trans_receipts: RwLock<HashMap<String, Vec<Transferable>>>,
18}
19
20impl LogDatabase<'_> for InMemoryLogDatabase {
21    type DatabaseType = ();
22    type Error = InMemoryDbError;
23    type TransactionType = ();
24
25    fn new(_db: Arc<Self::DatabaseType>) -> Result<Self, Self::Error>
26    where
27        Self: Sized,
28    {
29        Ok(Self {
30            events: RwLock::new(HashMap::new()),
31            signatures: RwLock::new(HashMap::new()),
32            nontrans_receipts: RwLock::new(HashMap::new()),
33            trans_receipts: RwLock::new(HashMap::new()),
34        })
35    }
36
37    fn log_event(
38        &self,
39        _txn: &Self::TransactionType,
40        signed_event: &SignedEventMessage,
41    ) -> Result<(), Self::Error> {
42        self.log_event_with_new_transaction(signed_event)
43    }
44
45    fn log_event_with_new_transaction(
46        &self,
47        signed_event: &SignedEventMessage,
48    ) -> Result<(), Self::Error> {
49        let digest = signed_event
50            .event_message
51            .digest()
52            .map_err(|_| InMemoryDbError::MissingDigest)?;
53        
54        let said_str = digest.to_string();
55        
56        // Store the event
57        self.events
58            .write()
59            .map_err(|_| InMemoryDbError::LockError)?
60            .insert(said_str.clone(), TimestampedSignedEventMessage::new(signed_event.clone()));
61        
62        // Store the signatures
63        self.signatures
64            .write()
65            .map_err(|_| InMemoryDbError::LockError)?
66            .insert(said_str.clone(), signed_event.signatures.clone());
67
68        // Store the witness receipts if present
69        if let Some(receipts) = &signed_event.witness_receipts {
70            self.nontrans_receipts
71                .write()
72                .map_err(|_| InMemoryDbError::LockError)?
73                .insert(said_str.clone(), receipts.clone());
74        }
75
76        log::debug!("Logged event with SAID: {}", said_str);
77        Ok(())
78    }
79
80    fn log_receipt(
81        &self,
82        _txn: &Self::TransactionType,
83        signed_receipt: &SignedNontransferableReceipt,
84    ) -> Result<(), Self::Error> {
85        self.log_receipt_with_new_transaction(signed_receipt)
86    }
87
88    fn log_receipt_with_new_transaction(
89        &self,
90        signed_receipt: &SignedNontransferableReceipt,
91    ) -> Result<(), Self::Error> {
92        let digest = &signed_receipt.body.receipted_event_digest;
93        let said_str = digest.to_string();
94        
95        let mut receipts_map = self.nontrans_receipts
96            .write()
97            .map_err(|_| InMemoryDbError::LockError)?;
98        
99        // Get existing receipts or create new vector
100        let receipts = receipts_map.entry(said_str.clone()).or_insert_with(Vec::new);
101        
102        // Add new receipts
103        for receipt in &signed_receipt.signatures {
104            if !receipts.contains(receipt) {
105                receipts.push(receipt.clone());
106            }
107        }
108        
109        log::debug!("Logged receipt for SAID: {}", said_str);
110        Ok(())
111    }
112
113    fn get_signed_event(
114        &self,
115        said: &SelfAddressingIdentifier,
116    ) -> Result<Option<TimestampedSignedEventMessage>, Self::Error> {
117        let events = self.events
118            .read()
119            .map_err(|_| InMemoryDbError::LockError)?;
120        
121        let r = events.get(&said.to_string()).cloned();
122        Ok(r)
123    }
124
125    fn get_event(
126        &self,
127        said: &SelfAddressingIdentifier,
128    ) -> Result<Option<KeriEvent<KeyEvent>>, Self::Error> {
129        let events = self.events
130            .read()
131            .map_err(|_| InMemoryDbError::LockError)?;
132            
133        match events.get(&said.to_string()) {
134            Some(signed_event) => Ok(Some(signed_event.signed_event_message.event_message.clone())),
135            None => Ok(None),
136        }
137    }
138
139    fn get_signatures(
140        &self,
141        said: &SelfAddressingIdentifier,
142    ) -> Result<Option<impl Iterator<Item = IndexedSignature>>, Self::Error> {
143        let signatures = self.signatures
144            .read()
145            .map_err(|_| InMemoryDbError::LockError)?;
146            
147        match signatures.get(&said.to_string()) {
148            Some(sigs) => Ok(Some(sigs.clone().into_iter())),
149            None => Ok(None),
150        }
151    }
152
153    fn get_nontrans_couplets(
154        &self,
155        said: &SelfAddressingIdentifier,
156    ) -> Result<Option<impl Iterator<Item = Nontransferable>>, Self::Error> {
157        let receipts = self.nontrans_receipts
158            .read()
159            .map_err(|_| InMemoryDbError::LockError)?;
160            
161        match receipts.get(&said.to_string()) {
162            Some(receipts) => Ok(Some(receipts.clone().into_iter())),
163            None => Ok(None),
164        }
165    }
166
167    fn get_trans_receipts(
168        &self,
169        said: &SelfAddressingIdentifier,
170    ) -> Result<impl DoubleEndedIterator<Item = Transferable>, Self::Error> {
171        let receipts = self.trans_receipts
172            .read()
173            .map_err(|_| InMemoryDbError::LockError)?;
174            
175        match receipts.get(&said.to_string()) {
176            Some(receipts) => Ok(receipts.clone().into_iter()),
177            None => Ok(Vec::new().into_iter()),
178        }
179    }
180
181    fn remove_nontrans_receipt(
182        &self,
183        _txn_mode: &Self::TransactionType,
184        said: &SelfAddressingIdentifier,
185        nontrans: impl IntoIterator<Item = Nontransferable>,
186    ) -> Result<(), Self::Error> {
187        let said_str = said.to_string();
188        let mut receipts_map = self.nontrans_receipts
189            .write()
190            .map_err(|_| InMemoryDbError::LockError)?;
191        
192        if let Some(receipts) = receipts_map.get_mut(&said_str) {
193            let receipts_to_remove: Vec<Nontransferable> = nontrans.into_iter().collect();
194            receipts.retain(|r| !receipts_to_remove.contains(r));
195        }
196        
197        Ok(())
198    }
199
200    fn remove_nontrans_receipt_with_new_transaction(
201        &self,
202        said: &SelfAddressingIdentifier,
203        nontrans: impl IntoIterator<Item = Nontransferable>,
204    ) -> Result<(), Self::Error> {
205        self.remove_nontrans_receipt(&(), said, nontrans)
206    }
207}