xmtp_db/
xmtp_openmls_provider.rs

1use crate::ConnectionExt;
2use crate::MlsProviderExt;
3use crate::TransactionalKeyStore;
4use crate::sql_key_store::SqlKeyStoreError;
5use openmls_rust_crypto::RustCrypto;
6use openmls_traits::OpenMlsProvider;
7use openmls_traits::storage::CURRENT_VERSION;
8use openmls_traits::storage::{Entity, StorageProvider};
9use xmtp_common::{MaybeSend, MaybeSync};
10
11/// Convenience super trait to constrain the storage provider to a
12/// specific error type and version
13/// This storage provider is likewise implemented on both &T and T references,
14/// to allow creating a referenced or owned provider.
15// constraining the error type here will avoid leaking
16// the associated type parameter, so we don't need to define it on every function.
17pub trait XmtpMlsStorageProvider:
18    MaybeSend + MaybeSync + StorageProvider<CURRENT_VERSION, Error = SqlKeyStoreError>
19{
20    /// An Opaque Database connection type. Can be anything.
21    type Connection: ConnectionExt;
22
23    type TxQuery: TransactionalKeyStore;
24
25    type DbQuery<'a>: crate::DbQuery
26    where
27        Self::Connection: 'a;
28
29    fn db<'a>(&'a self) -> Self::DbQuery<'a>;
30
31    /// Start a new transaction
32    fn transaction<T, E, F>(&self, f: F) -> Result<T, E>
33    where
34        F: FnOnce(&mut Self::TxQuery) -> Result<T, E>,
35        E: From<diesel::result::Error> + From<crate::ConnectionError> + std::error::Error;
36
37    /// Start a savepoint within a transaction
38    /// Must only be used when already in a transaction
39    // TODO: enforce that this is only used within transactions
40    // otherwise we run into sqlite race conditions b/c this does not
41    // use BEGIN IMMEDIATE.
42    // we can ensure this by checking sqlite transaction depth.
43    fn savepoint<T, E, F>(&self, f: F) -> Result<T, E>
44    where
45        F: FnOnce(&mut Self::TxQuery) -> Result<T, E>,
46        E: From<diesel::result::Error> + From<crate::ConnectionError> + std::error::Error;
47
48    fn _disable_lint_for_self<'a>(_: Self::DbQuery<'a>) {}
49
50    fn read<V: Entity<CURRENT_VERSION>>(
51        &self,
52        label: &[u8],
53        key: &[u8],
54    ) -> Result<Option<V>, SqlKeyStoreError>;
55
56    fn read_list<V: Entity<CURRENT_VERSION>>(
57        &self,
58        label: &[u8],
59        key: &[u8],
60    ) -> Result<Vec<V>, <Self as StorageProvider<CURRENT_VERSION>>::Error>;
61
62    fn delete(
63        &self,
64        label: &[u8],
65        key: &[u8],
66    ) -> Result<(), <Self as StorageProvider<CURRENT_VERSION>>::Error>;
67
68    fn write(
69        &self,
70        label: &[u8],
71        key: &[u8],
72        value: &[u8],
73    ) -> Result<(), <Self as StorageProvider<CURRENT_VERSION>>::Error>;
74
75    #[cfg(feature = "test-utils")]
76    fn hash_all(&self) -> Result<Vec<u8>, SqlKeyStoreError>;
77}
78
79pub struct XmtpOpenMlsProvider<S> {
80    crypto: RustCrypto,
81    mls_storage: S,
82}
83
84impl<S> XmtpOpenMlsProvider<S> {
85    pub fn new(mls_storage: S) -> Self {
86        Self {
87            crypto: RustCrypto::default(),
88            mls_storage,
89        }
90    }
91}
92
93impl<S> XmtpOpenMlsProvider<S> {
94    pub fn new_crypto() -> RustCrypto {
95        RustCrypto::default()
96    }
97}
98
99impl<S> MlsProviderExt for XmtpOpenMlsProvider<S>
100where
101    S: XmtpMlsStorageProvider,
102{
103    type XmtpStorage = S;
104
105    fn key_store(&self) -> &Self::XmtpStorage {
106        &self.mls_storage
107    }
108}
109
110impl<S> OpenMlsProvider for XmtpOpenMlsProvider<S>
111where
112    S: XmtpMlsStorageProvider,
113{
114    type CryptoProvider = RustCrypto;
115    type RandProvider = RustCrypto;
116    type StorageProvider = S;
117    fn crypto(&self) -> &Self::CryptoProvider {
118        &self.crypto
119    }
120
121    fn rand(&self) -> &Self::RandProvider {
122        &self.crypto
123    }
124
125    fn storage(&self) -> &Self::StorageProvider {
126        &self.mls_storage
127    }
128}
129
130pub struct XmtpOpenMlsProviderRef<'a, S> {
131    crypto: RustCrypto,
132    mls_storage: &'a S,
133}
134
135impl<'a, S> MlsProviderExt for XmtpOpenMlsProviderRef<'a, S>
136where
137    S: XmtpMlsStorageProvider,
138{
139    type XmtpStorage = S;
140
141    fn key_store(&self) -> &Self::XmtpStorage {
142        self.mls_storage
143    }
144}
145
146impl<'a, S> OpenMlsProvider for XmtpOpenMlsProviderRef<'a, S>
147where
148    S: XmtpMlsStorageProvider,
149{
150    type CryptoProvider = RustCrypto;
151    type RandProvider = RustCrypto;
152    type StorageProvider = S;
153    fn crypto(&self) -> &Self::CryptoProvider {
154        &self.crypto
155    }
156
157    fn rand(&self) -> &Self::RandProvider {
158        &self.crypto
159    }
160
161    fn storage(&self) -> &Self::StorageProvider {
162        self.mls_storage
163    }
164}
165
166impl<'a, S> XmtpOpenMlsProviderRef<'a, S> {
167    pub fn new(mls_storage: &'a S) -> Self {
168        Self {
169            crypto: RustCrypto::default(),
170            mls_storage,
171        }
172    }
173}
174
175pub struct XmtpOpenMlsProviderRefMut<'a, S> {
176    crypto: RustCrypto,
177    mls_storage: &'a mut S,
178}
179
180impl<'a, S> XmtpOpenMlsProviderRefMut<'a, S> {
181    pub fn new(mls_storage: &'a mut S) -> Self {
182        Self {
183            crypto: RustCrypto::default(),
184            mls_storage,
185        }
186    }
187}
188
189impl<'a, S> MlsProviderExt for XmtpOpenMlsProviderRefMut<'a, S>
190where
191    S: XmtpMlsStorageProvider,
192{
193    type XmtpStorage = S;
194
195    fn key_store(&self) -> &Self::XmtpStorage {
196        self.mls_storage
197    }
198}
199
200impl<'a, S> OpenMlsProvider for XmtpOpenMlsProviderRefMut<'a, S>
201where
202    S: XmtpMlsStorageProvider,
203{
204    type CryptoProvider = RustCrypto;
205    type RandProvider = RustCrypto;
206    type StorageProvider = S;
207    fn crypto(&self) -> &Self::CryptoProvider {
208        &self.crypto
209    }
210
211    fn rand(&self) -> &Self::RandProvider {
212        &self.crypto
213    }
214
215    fn storage(&self) -> &Self::StorageProvider {
216        self.mls_storage
217    }
218}