Merge remote-tracking branch 'origin/main' into ben-name-alignment

This commit is contained in:
Benjamin Kampmann
2022-05-09 17:04:17 +02:00
8 changed files with 110 additions and 108 deletions

View File

@@ -71,9 +71,9 @@ pub use self::memory_store::MemoryStore;
/// State store specific error type.
#[derive(Debug, thiserror::Error)]
pub enum StoreError {
#[error(transparent)]
/// An error happened in the underlying database backend.
Backend(#[from] Box<dyn std::error::Error + Send + Sync>),
#[error(transparent)]
Backend(Box<dyn std::error::Error + Send + Sync>),
/// An error happened while serializing or deserializing some data.
#[error(transparent)]
Json(#[from] serde_json::Error),
@@ -107,6 +107,20 @@ pub enum StoreError {
#[error("Redaction failed: {0}")]
Redaction(#[source] ruma::signatures::Error),
}
impl StoreError {
/// Create a new [`Backend`][Self::Backend] error.
///
/// Shorthand for `StoreError::Backend(Box::new(error))`.
#[inline]
pub fn backend<E>(error: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Backend(Box::new(error))
}
}
/// A `StateStore` specific result type.
pub type Result<T, E = StoreError> = std::result::Result<T, E>;

View File

@@ -102,7 +102,7 @@ impl OlmMachine {
// this.
matrix_sdk_sled::OpenStoreError::Crypto(r) => r.into(),
matrix_sdk_sled::OpenStoreError::Sled(s) => CryptoStoreError::CryptoStore(
matrix_sdk_crypto::store::CryptoStoreError::Backend(Box::new(s)),
matrix_sdk_crypto::store::CryptoStoreError::backend(s),
),
_ => unreachable!(),
}

View File

@@ -625,7 +625,20 @@ pub enum CryptoStoreError {
/// A problem with the underlying database backend
#[error(transparent)]
Backend(#[from] Box<dyn std::error::Error + Send + Sync>),
Backend(Box<dyn std::error::Error + Send + Sync>),
}
impl CryptoStoreError {
/// Create a new [`Backend`][Self::Backend] error.
///
/// Shorthand for `StoreError::Backend(Box::new(error))`.
#[inline]
pub fn backend<E>(error: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Backend(Box::new(error))
}
}
/// Trait abstracting a store that the `OlmMachine` uses to store cryptographic

View File

@@ -120,7 +120,7 @@ impl From<IndexeddbStoreError> for CryptoStoreError {
match frm {
IndexeddbStoreError::Json(e) => CryptoStoreError::Serialization(e),
IndexeddbStoreError::CryptoStoreError(e) => e,
_ => CryptoStoreError::Backend(Box::new(frm)),
_ => CryptoStoreError::backend(frm),
}
}
}
@@ -217,9 +217,8 @@ impl IndexeddbStore {
Some(key) => StoreCipher::import(passphrase, &key)
.map_err(|_| CryptoStoreError::UnpicklingError)?,
None => {
let key = StoreCipher::new().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let encrypted =
key.export(passphrase).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let key = StoreCipher::new().map_err(CryptoStoreError::backend)?;
let encrypted = key.export(passphrase).map_err(CryptoStoreError::backend)?;
let tx: IdbTransaction<'_> = db.transaction_on_one_with_mode(
"matrix-sdk-crypto",
@@ -246,8 +245,7 @@ impl IndexeddbStore {
fn serialize_value(&self, value: &impl Serialize) -> Result<JsValue, CryptoStoreError> {
if let Some(key) = &self.store_cipher {
let value =
key.encrypt_value(value).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let value = key.encrypt_value(value).map_err(CryptoStoreError::backend)?;
Ok(JsValue::from_serde(&value)?)
} else {
@@ -261,7 +259,7 @@ impl IndexeddbStore {
) -> Result<T, CryptoStoreError> {
if let Some(key) = &self.store_cipher {
let value: Vec<u8> = value.into_serde()?;
key.decrypt_value(&value).map_err(|e| CryptoStoreError::Backend(Box::new(e)))
key.decrypt_value(&value).map_err(CryptoStoreError::backend)
} else {
Ok(value.into_serde()?)
}

View File

@@ -95,7 +95,7 @@ impl From<SerializationError> for StoreError {
expected, found
)),
},
_ => StoreError::Backend(Box::new(e)),
_ => StoreError::backend(e),
}
}
}

View File

@@ -212,11 +212,8 @@ impl SledStore {
passphrase: Option<&str>,
) -> Result<Self, OpenStoreError> {
let path = path.as_ref().join("matrix-sdk-crypto");
let db = Config::new()
.temporary(false)
.path(&path)
.open()
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let db =
Config::new().temporary(false).path(&path).open().map_err(CryptoStoreError::backend)?;
let store_cipher = if let Some(passphrase) = passphrase {
Some(Self::get_or_create_store_cipher(passphrase, &db)?.into())
@@ -242,7 +239,7 @@ impl SledStore {
fn serialize_value(&self, event: &impl Serialize) -> Result<Vec<u8>, CryptoStoreError> {
if let Some(key) = &self.store_cipher {
key.encrypt_value(event).map_err(|e| CryptoStoreError::Backend(Box::new(e)))
key.encrypt_value(event).map_err(CryptoStoreError::backend)
} else {
Ok(serde_json::to_vec(event)?)
}
@@ -253,7 +250,7 @@ impl SledStore {
event: &[u8],
) -> Result<T, CryptoStoreError> {
if let Some(key) = &self.store_cipher {
key.decrypt_value(event).map_err(|e| CryptoStoreError::Backend(Box::new(e)))
key.decrypt_value(event).map_err(CryptoStoreError::backend)
} else {
Ok(serde_json::from_slice(event)?)
}
@@ -272,7 +269,7 @@ impl SledStore {
.inbound_group_sessions
.iter()
.map(|p| {
let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let item = p.map_err(CryptoStoreError::backend)?;
Ok((item.0, self.deserialize_value(&item.1)?))
})
.collect::<Result<_>>()?;
@@ -294,9 +291,9 @@ impl SledStore {
Ok(())
});
ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
ret.map_err(CryptoStoreError::backend)?;
self.inner.flush_async().await.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
self.inner.flush_async().await.map_err(CryptoStoreError::backend)?;
Ok(())
}
@@ -305,7 +302,7 @@ impl SledStore {
let version = self
.inner
.get("store_version")
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|v| {
let (version_bytes, _) = v.split_at(std::mem::size_of::<u8>());
u8::from_be_bytes(version_bytes.try_into().unwrap_or_default())
@@ -325,25 +322,23 @@ impl SledStore {
self.inner
.insert("store_version", DATABASE_VERSION.to_be_bytes().as_ref())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
self.inner.flush().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
.map_err(CryptoStoreError::backend)?;
self.inner.flush().map_err(CryptoStoreError::backend)?;
Ok(())
}
fn get_or_create_store_cipher(passphrase: &str, database: &Db) -> Result<StoreCipher> {
let key = if let Some(key) = database
.get("store_cipher".encode())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
let key = if let Some(key) =
database.get("store_cipher".encode()).map_err(CryptoStoreError::backend)?
{
StoreCipher::import(passphrase, &key).map_err(|_| CryptoStoreError::UnpicklingError)?
} else {
let key = StoreCipher::new().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let encrypted =
key.export(passphrase).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let key = StoreCipher::new().map_err(CryptoStoreError::backend)?;
let encrypted = key.export(passphrase).map_err(CryptoStoreError::backend)?;
database
.insert("store_cipher".encode(), encrypted)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
.map_err(CryptoStoreError::backend)?;
key
};
@@ -404,7 +399,7 @@ impl SledStore {
async fn load_tracked_users(&self) -> Result<()> {
for value in &self.tracked_users {
let (_, user) = value.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let (_, user) = value.map_err(CryptoStoreError::backend)?;
let user: TrackedUser = self.deserialize_value(&user)?;
self.tracked_users_cache.insert(user.user_id.to_owned());
@@ -425,7 +420,7 @@ impl SledStore {
self.outbound_group_sessions
.get(self.encode_key(OUTBOUND_GROUP_TABLE_NAME, room_id))
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|p| self.deserialize_value(&p))
.transpose()?
.map(|p| {
@@ -630,8 +625,8 @@ impl SledStore {
},
);
ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
self.inner.flush().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
ret.map_err(CryptoStoreError::backend)?;
self.inner.flush().map_err(CryptoStoreError::backend)?;
Ok(())
}
@@ -640,14 +635,14 @@ impl SledStore {
let request = self
.outgoing_secret_requests
.get(id)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|r| self.deserialize_value(&r))
.transpose()?;
let request = if request.is_none() {
self.unsent_secret_requests
.get(id)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|r| self.deserialize_value(&r))
.transpose()?
} else {
@@ -682,17 +677,15 @@ impl SledStore {
);
}
self.tracked_users.apply_batch(batch).map_err(|e| CryptoStoreError::Backend(Box::new(e)))
self.tracked_users.apply_batch(batch).map_err(CryptoStoreError::backend)
}
}
#[async_trait]
impl CryptoStore for SledStore {
async fn load_account(&self) -> Result<Option<ReadOnlyAccount>> {
if let Some(pickle) = self
.account
.get("account".encode())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
if let Some(pickle) =
self.account.get("account".encode()).map_err(CryptoStoreError::backend)?
{
let pickle = self.deserialize_value(&pickle)?;
@@ -718,10 +711,8 @@ impl CryptoStore for SledStore {
}
async fn load_identity(&self) -> Result<Option<PrivateCrossSigningIdentity>> {
if let Some(i) = self
.private_identity
.get("identity".encode())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
if let Some(i) =
self.private_identity.get("identity".encode()).map_err(CryptoStoreError::backend)?
{
let pickle = self.deserialize_value(&i)?;
Ok(Some(
@@ -745,11 +736,7 @@ impl CryptoStore for SledStore {
let sessions: Result<Vec<Session>> = self
.sessions
.scan_prefix(self.encode_key(SESSIONS_TABLE_NAME, sender_key))
.map(|s| {
self.deserialize_value(
&s.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1,
)
})
.map(|s| self.deserialize_value(&s.map_err(CryptoStoreError::backend)?.1))
.map(|p| {
Ok(Session::from_pickle(
account_info.user_id.clone(),
@@ -776,7 +763,7 @@ impl CryptoStore for SledStore {
let pickle = self
.inbound_group_sessions
.get(&key)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|p| self.deserialize_value(&p));
if let Some(pickle) = pickle {
@@ -790,9 +777,7 @@ impl CryptoStore for SledStore {
let pickles: Result<Vec<PickledInboundGroupSession>> = self
.inbound_group_sessions
.iter()
.map(|p| {
self.deserialize_value(&p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1)
})
.map(|p| self.deserialize_value(&p.map_err(CryptoStoreError::backend)?.1))
.collect();
Ok(pickles?.into_iter().filter_map(|p| InboundGroupSession::from_pickle(p).ok()).collect())
@@ -803,7 +788,7 @@ impl CryptoStore for SledStore {
.inbound_group_sessions
.iter()
.map(|p| {
let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let item = p.map_err(CryptoStoreError::backend)?;
self.deserialize_value(&item.1)
})
.collect::<Result<_>>()?;
@@ -822,7 +807,7 @@ impl CryptoStore for SledStore {
.inbound_group_sessions
.iter()
.map(|p| {
let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
let item = p.map_err(CryptoStoreError::backend)?;
self.deserialize_value(&item.1)
})
.filter_map(|p: Result<PickledInboundGroupSession, CryptoStoreError>| match p {
@@ -893,7 +878,7 @@ impl CryptoStore for SledStore {
Ok(self
.devices
.get(key)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|d| self.deserialize_value(&d))
.transpose()?)
}
@@ -905,9 +890,7 @@ impl CryptoStore for SledStore {
let key = self.encode_key(DEVICE_TABLE_NAME, user_id);
self.devices
.scan_prefix(key)
.map(|d| {
self.deserialize_value(&d.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1)
})
.map(|d| self.deserialize_value(&d.map_err(CryptoStoreError::backend)?.1))
.map(|d| {
let d: ReadOnlyDevice = d?;
Ok((d.device_id().to_owned(), d))
@@ -921,7 +904,7 @@ impl CryptoStore for SledStore {
Ok(self
.identities
.get(key)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|i| self.deserialize_value(&i))
.transpose()?)
}
@@ -933,7 +916,7 @@ impl CryptoStore for SledStore {
Ok(self
.olm_hashes
.contains_key(serde_json::to_vec(message_hash)?)
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?)
.map_err(CryptoStoreError::backend)?)
}
async fn get_outgoing_secret_requests(
@@ -952,7 +935,7 @@ impl CryptoStore for SledStore {
let id = self
.secret_requests_by_info
.get(self.encode_key(SECRET_REQUEST_BY_INFO_TABLE, key_info))
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
.map_err(CryptoStoreError::backend)?;
if let Some(id) = id {
self.get_outgoing_key_request_helper(&id).await
@@ -965,9 +948,7 @@ impl CryptoStore for SledStore {
let requests: Result<Vec<GossipRequest>> = self
.unsent_secret_requests
.iter()
.map(|i| {
self.deserialize_value(&i.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1)
})
.map(|i| self.deserialize_value(&i.map_err(CryptoStoreError::backend)?.1))
.collect();
requests
@@ -1007,8 +988,8 @@ impl CryptoStore for SledStore {
},
);
ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
self.inner.flush_async().await.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?;
ret.map_err(CryptoStoreError::backend)?;
self.inner.flush_async().await.map_err(CryptoStoreError::backend)?;
Ok(())
}
@@ -1018,14 +999,14 @@ impl CryptoStore for SledStore {
let backup_version = self
.account
.get("backup_version_v1".encode())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|v| self.deserialize_value(&v))
.transpose()?;
let recovery_key = {
self.account
.get("recovery_key_v1".encode())
.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?
.map_err(CryptoStoreError::backend)?
.map(|p| self.deserialize_value(&p))
.transpose()?
};

View File

@@ -111,7 +111,7 @@ impl Into<StoreError> for SledStoreError {
)),
},
SledStoreError::StoreError(e) => e,
_ => StoreError::Backend(Box::new(self)),
_ => StoreError::backend(self),
}
}
}
@@ -269,8 +269,7 @@ impl SledStore {
}
pub fn open() -> StoreResult<Self> {
let db =
Config::new().temporary(true).open().map_err(|e| StoreError::Backend(Box::new(e)))?;
let db = Config::new().temporary(true).open().map_err(StoreError::backend)?;
SledStore::open_helper(db, None, None).map_err(|e| e.into())
}
@@ -278,8 +277,7 @@ impl SledStore {
// testing only
#[cfg(test)]
fn open_encrypted() -> StoreResult<Self> {
let db =
Config::new().temporary(true).open().map_err(|e| StoreError::Backend(Box::new(e)))?;
let db = Config::new().temporary(true).open().map_err(StoreError::backend)?;
SledStore::open_helper(
db,
@@ -321,19 +319,18 @@ impl SledStore {
}
fn upgrade(&self) -> StoreResult<()> {
let db_version =
self.inner.get(VERSION_KEY).map_err(|e| StoreError::Backend(Box::new(e)))?.map(|v| {
let (version_bytes, _) = v.split_at(std::mem::size_of::<u8>());
u8::from_be_bytes(version_bytes.try_into().unwrap_or_default())
});
let db_version = self.inner.get(VERSION_KEY).map_err(StoreError::backend)?.map(|v| {
let (version_bytes, _) = v.split_at(std::mem::size_of::<u8>());
u8::from_be_bytes(version_bytes.try_into().unwrap_or_default())
});
let old_version = match db_version {
None => {
// we are fresh, let's write the current version
self.inner
.insert(VERSION_KEY, DATABASE_VERSION.to_be_bytes().as_ref())
.map_err(|e| StoreError::Backend(Box::new(e)))?;
self.inner.flush().map_err(|e| StoreError::Backend(Box::new(e)))?;
.map_err(StoreError::backend)?;
self.inner.flush().map_err(StoreError::backend)?;
return Ok(());
}
Some(version) if version == DATABASE_VERSION => {
@@ -789,14 +786,12 @@ impl SledStore {
let key = self.encode_key(INVITED_USER_ID, room_id);
spawn_blocking(move || {
stream::iter(db.invited_user_ids.scan_prefix(key).map(|u| {
UserId::parse(String::from_utf8_lossy(
&u.map_err(|e| StoreError::Backend(Box::new(e)))?.1,
))
.map_err(StoreError::Identifier)
UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1))
.map_err(StoreError::Identifier)
}))
})
.await
.map_err(|e| StoreError::Backend(Box::new(e)))
.map_err(StoreError::backend)
}
pub async fn get_joined_user_ids(
@@ -807,14 +802,12 @@ impl SledStore {
let key = self.encode_key(JOINED_USER_ID, room_id);
spawn_blocking(move || {
stream::iter(db.joined_user_ids.scan_prefix(key).map(|u| {
UserId::parse(String::from_utf8_lossy(
&u.map_err(|e| StoreError::Backend(Box::new(e)))?.1,
))
.map_err(StoreError::Identifier)
UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1))
.map_err(StoreError::Identifier)
}))
})
.await
.map_err(|e| StoreError::Backend(Box::new(e)))
.map_err(StoreError::backend)
}
pub async fn get_stripped_invited_user_ids(
@@ -825,14 +818,12 @@ impl SledStore {
let key = self.encode_key(STRIPPED_INVITED_USER_ID, room_id);
spawn_blocking(move || {
stream::iter(db.stripped_invited_user_ids.scan_prefix(key).map(|u| {
UserId::parse(String::from_utf8_lossy(
&u.map_err(|e| StoreError::Backend(Box::new(e)))?.1,
))
.map_err(StoreError::Identifier)
UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1))
.map_err(StoreError::Identifier)
}))
})
.await
.map_err(|e| StoreError::Backend(Box::new(e)))
.map_err(StoreError::backend)
}
pub async fn get_stripped_joined_user_ids(
@@ -843,14 +834,12 @@ impl SledStore {
let key = self.encode_key(STRIPPED_JOINED_USER_ID, room_id);
spawn_blocking(move || {
stream::iter(db.stripped_joined_user_ids.scan_prefix(key).map(|u| {
UserId::parse(String::from_utf8_lossy(
&u.map_err(|e| StoreError::Backend(Box::new(e)))?.1,
))
.map_err(StoreError::Identifier)
UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1))
.map_err(StoreError::Identifier)
}))
})
.await
.map_err(|e| StoreError::Backend(Box::new(e)))
.map_err(StoreError::backend)
}
pub async fn get_room_infos(&self) -> Result<impl Stream<Item = Result<RoomInfo>>> {
@@ -941,13 +930,13 @@ impl SledStore {
.scan_prefix(key)
.values()
.map(|u| {
let v = u.map_err(|e| StoreError::Backend(Box::new(e)))?;
db.deserialize_event(&v).map_err(|e| StoreError::Backend(Box::new(e)))
let v = u.map_err(StoreError::backend)?;
db.deserialize_event(&v).map_err(StoreError::backend)
})
.collect()
})
.await
.map_err(|e| StoreError::Backend(Box::new(e)))?
.map_err(StoreError::backend)?
}
async fn add_media_content(&self, request: &MediaRequest, data: Vec<u8>) -> Result<()> {

View File

@@ -494,13 +494,20 @@ mod static_events {
(EventKind::MessageLike, events::room::redaction::RoomRedactionEventContent::TYPE);
}
impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent {
impl SyncEvent for events::room::redaction::OriginalSyncRoomRedactionEvent {
const ID: (EventKind, &'static str) = (
EventKind::OriginalMessageLike,
events::room::redaction::RoomRedactionEventContent::TYPE,
);
}
impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent {
const ID: (EventKind, &'static str) = (
EventKind::RedactedMessageLike,
events::room::redaction::RoomRedactionEventContent::TYPE,
);
}
impl<C> SyncEvent for events::SyncStateEvent<C>
where
C: StaticEventContent + StateEventContent + RedactContent,