Fixed more compile time errors

This commit is contained in:
Timo Kösters 2022-09-07 13:25:51 +02:00 committed by Nyaaori
parent 785ddfc4aa
commit bd8b616ca0
No known key found for this signature in database
GPG key ID: E7819C3ED4D1F82E
103 changed files with 1617 additions and 2749 deletions

View file

@ -1,24 +1,29 @@
use ruma::{RoomId, RoomAliasId};
use crate::Result;
pub trait Data {
/// Creates or updates the alias to the given room id.
fn set_alias(
&self,
alias: &RoomAliasId,
room_id: &RoomId
) -> Result<()>;
/// Forgets about an alias. Returns an error if the alias did not exist.
fn remove_alias(
&self,
alias: &RoomAliasId,
) -> Result<()>;
/// Looks up the roomid for the given alias.
fn resolve_local_alias(
&self,
alias: &RoomAliasId,
) -> Result<()>;
) -> Result<Option<Box<RoomId>>>;
/// Returns all local aliases that point to the given room
fn local_aliases_for_room(
alias: &RoomAliasId,
) -> Result<()>;
&self,
room_id: &RoomId,
) -> Result<Box<dyn Iterator<Item=String>>>;
}

View file

@ -1,12 +1,14 @@
mod data;
pub use data::Data;
use ruma::{RoomAliasId, RoomId};
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self))]
pub fn set_alias(
&self,
@ -26,7 +28,7 @@ impl Service<_> {
#[tracing::instrument(skip(self))]
pub fn resolve_local_alias(&self, alias: &RoomAliasId) -> Result<Option<Box<RoomId>>> {
self.db.resolve_local_alias(alias: &RoomAliasId)
self.db.resolve_local_alias(alias)
}
#[tracing::instrument(skip(self))]

View file

@ -1,6 +1,7 @@
use std::collections::HashSet;
use crate::Result;
pub trait Data {
fn get_cached_eventid_authchain<'a>() -> Result<HashSet<u64>>;
fn cache_eventid_authchain<'a>(shorteventid: u64, auth_chain: &HashSet<u64>) -> Result<HashSet<u64>>;
fn get_cached_eventid_authchain(&self, shorteventid: u64) -> Result<HashSet<u64>>;
fn cache_eventid_authchain(&self, shorteventid: u64, auth_chain: &HashSet<u64>) -> Result<()>;
}

View file

@ -3,13 +3,13 @@ use std::{sync::Arc, collections::HashSet};
pub use data::Data;
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self))]
pub fn get_cached_eventid_authchain<'a>(
&'a self,

View file

@ -1,15 +1,16 @@
use ruma::RoomId;
use crate::Result;
pub trait Data {
/// Adds the room to the public room directory
fn set_public(room_id: &RoomId) -> Result<()>;
fn set_public(&self, room_id: &RoomId) -> Result<()>;
/// Removes the room from the public room directory.
fn set_not_public(room_id: &RoomId) -> Result<()>;
fn set_not_public(&self, room_id: &RoomId) -> Result<()>;
/// Returns true if the room is in the public room directory.
fn is_public_room(room_id: &RoomId) -> Result<bool>;
fn is_public_room(&self, room_id: &RoomId) -> Result<bool>;
/// Returns the unsorted public room directory
fn public_rooms() -> impl Iterator<Item = Result<Box<RoomId>>> + '_;
fn public_rooms(&self) -> Box<dyn Iterator<Item = Result<Box<RoomId>>>>;
}

View file

@ -2,13 +2,13 @@ mod data;
pub use data::Data;
use ruma::RoomId;
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self))]
pub fn set_public(&self, room_id: &RoomId) -> Result<()> {
self.db.set_public(room_id)

View file

@ -2,7 +2,9 @@ pub mod presence;
pub mod read_receipt;
pub mod typing;
pub struct Service<D> {
pub trait Data: presence::Data + read_receipt::Data + typing::Data {}
pub struct Service<D: Data> {
presence: presence::Service<D>,
read_receipt: read_receipt::Service<D>,
typing: typing::Service<D>,

View file

@ -1,6 +1,7 @@
use std::collections::HashMap;
use ruma::{UserId, RoomId, events::presence::PresenceEvent};
use crate::Result;
pub trait Data {
/// Adds a presence event which will be saved until a new event replaces it.

View file

@ -4,13 +4,13 @@ use std::collections::HashMap;
pub use data::Data;
use ruma::{RoomId, UserId, events::presence::PresenceEvent};
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Adds a presence event which will be saved until a new event replaces it.
///
/// Note: This method takes a RoomId because presence updates are always bound to rooms to

View file

@ -1,4 +1,5 @@
use ruma::{RoomId, events::receipt::ReceiptEvent, UserId, serde::Raw};
use crate::Result;
pub trait Data {
/// Replaces the previous read receipt.
@ -14,13 +15,13 @@ pub trait Data {
&self,
room_id: &RoomId,
since: u64,
) -> impl Iterator<
) -> Box<dyn Iterator<
Item = Result<(
Box<UserId>,
u64,
Raw<ruma::events::AnySyncEphemeralRoomEvent>,
)>,
>;
>>;
/// Sets a private read marker at `count`.
fn private_read_set(&self, room_id: &RoomId, user_id: &UserId, count: u64) -> Result<()>;

View file

@ -1,12 +1,14 @@
mod data;
pub use data::Data;
use ruma::{RoomId, UserId, events::receipt::ReceiptEvent, serde::Raw};
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Replaces the previous read receipt.
pub fn readreceipt_update(
&self,

View file

@ -1,5 +1,5 @@
use std::collections::HashSet;
use crate::Result;
use ruma::{UserId, RoomId};
pub trait Data {
@ -14,5 +14,5 @@ pub trait Data {
fn last_typing_update(&self, room_id: &RoomId) -> Result<u64>;
/// Returns all user ids currently typing.
fn typings_all(&self, room_id: &RoomId) -> Result<HashSet<UserId>>;
fn typings_all(&self, room_id: &RoomId) -> Result<HashSet<Box<UserId>>>;
}

View file

@ -1,14 +1,14 @@
mod data;
pub use data::Data;
use ruma::{UserId, RoomId};
use ruma::{UserId, RoomId, events::SyncEphemeralRoomEvent};
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is
/// called.
pub fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> {

View file

@ -250,7 +250,7 @@ impl Service {
// We go through all the signatures we see on the value and fetch the corresponding signing
// keys
self.fetch_required_signing_keys(&value, pub_key_map, db)
self.fetch_required_signing_keys(&value, pub_key_map)
.await?;
// 2. Check signatures, otherwise drop
@ -1153,6 +1153,11 @@ impl Service {
let mut eventid_info = HashMap::new();
let mut todo_outlier_stack: Vec<Arc<EventId>> = initial_set;
let first_pdu_in_room = services()
.rooms
.first_pdu_in_room(room_id)?
.ok_or_else(|| Error::bad_database("Failed to find first pdu in db."))?;
let mut amount = 0;
while let Some(prev_event_id) = todo_outlier_stack.pop() {

View file

@ -1,4 +1,5 @@
use ruma::{RoomId, DeviceId, UserId};
use crate::Result;
pub trait Data {
fn lazy_load_was_sent_before(

View file

@ -4,13 +4,13 @@ use std::collections::HashSet;
pub use data::Data;
use ruma::{DeviceId, UserId, RoomId};
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self))]
pub fn lazy_load_was_sent_before(
&self,

View file

@ -1,4 +1,5 @@
use ruma::RoomId;
use crate::Result;
pub trait Data {
fn exists(&self, room_id: &RoomId) -> Result<bool>;

View file

@ -2,13 +2,13 @@ mod data;
pub use data::Data;
use ruma::RoomId;
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Checks if a room exists.
#[tracing::instrument(skip(self))]
pub fn exists(&self, room_id: &RoomId) -> Result<bool> {

View file

@ -16,7 +16,9 @@ pub mod state_compressor;
pub mod timeline;
pub mod user;
pub struct Service<D> {
pub trait Data: alias::Data + auth_chain::Data + directory::Data + edus::Data + lazy_loading::Data + metadata::Data + outlier::Data + pdu_metadata::Data + search::Data + short::Data + state::Data + state_accessor::Data + state_cache::Data + state_compressor::Data + timeline::Data + user::Data {}
pub struct Service<D: Data> {
pub alias: alias::Service<D>,
pub auth_chain: auth_chain::Service<D>,
pub directory: directory::Service<D>,

View file

@ -1,6 +1,6 @@
use ruma::{EventId, signatures::CanonicalJsonObject};
use ruma::{signatures::CanonicalJsonObject, EventId};
use crate::PduEvent;
use crate::{PduEvent, Result};
pub trait Data {
fn get_outlier_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>>;

View file

@ -2,13 +2,13 @@ mod data;
pub use data::Data;
use ruma::{EventId, signatures::CanonicalJsonObject};
use crate::{service::*, PduEvent};
use crate::{Result, PduEvent};
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Returns the pdu from the outlier tree.
pub fn get_outlier_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
self.db.get_outlier_pdu_json(event_id)

View file

@ -1,6 +1,7 @@
use std::sync::Arc;
use ruma::{EventId, RoomId};
use crate::Result;
pub trait Data {
fn mark_as_referenced(&self, room_id: &RoomId, event_ids: &[Arc<EventId>]) -> Result<()>;

View file

@ -4,13 +4,13 @@ use std::sync::Arc;
pub use data::Data;
use ruma::{RoomId, EventId};
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self, room_id, event_ids))]
pub fn mark_as_referenced(&self, room_id: &RoomId, event_ids: &[Arc<EventId>]) -> Result<()> {
self.db.mark_as_referenced(room_id, event_ids)

View file

@ -1,11 +1,12 @@
use ruma::RoomId;
use crate::Result;
pub trait Data {
fn index_pdu<'a>(&self, room_id: &RoomId, pdu_id: u64, message_body: String) -> Result<()>;
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: u64, message_body: String) -> Result<()>;
fn search_pdus<'a>(
&'a self,
room_id: &RoomId,
search_string: &str,
) -> Result<Option<(impl Iterator<Item = Vec<u8>> + 'a, Vec<String>)>>;
) -> Result<Option<(Box<dyn Iterator<Item = Vec<u8>>>, Vec<String>)>>;
}

View file

@ -1,12 +1,14 @@
mod data;
pub use data::Data;
use crate::Result;
use ruma::RoomId;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
#[tracing::instrument(skip(self))]
pub fn search_pdus<'a>(
&'a self,

View file

@ -0,0 +1,2 @@
pub trait Data {
}

View file

@ -2,19 +2,18 @@ mod data;
use std::sync::Arc;
pub use data::Data;
use ruma::{EventId, events::StateEventType};
use ruma::{EventId, events::StateEventType, RoomId};
use crate::{service::*, Error, utils};
use crate::{Result, Error, utils, services};
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
pub fn get_or_create_shorteventid(
&self,
event_id: &EventId,
globals: &super::globals::Globals,
) -> Result<u64> {
if let Some(short) = self.eventidshort_cache.lock().unwrap().get_mut(event_id) {
return Ok(*short);
@ -24,7 +23,7 @@ impl Service<_> {
Some(shorteventid) => utils::u64_from_bytes(&shorteventid)
.map_err(|_| Error::bad_database("Invalid shorteventid in db."))?,
None => {
let shorteventid = globals.next_count()?;
let shorteventid = services().globals.next_count()?;
self.eventid_shorteventid
.insert(event_id.as_bytes(), &shorteventid.to_be_bytes())?;
self.shorteventid_eventid
@ -82,7 +81,6 @@ impl Service<_> {
&self,
event_type: &StateEventType,
state_key: &str,
globals: &super::globals::Globals,
) -> Result<u64> {
if let Some(short) = self
.statekeyshort_cache
@ -101,7 +99,7 @@ impl Service<_> {
Some(shortstatekey) => utils::u64_from_bytes(&shortstatekey)
.map_err(|_| Error::bad_database("Invalid shortstatekey in db."))?,
None => {
let shortstatekey = globals.next_count()?;
let shortstatekey = services().globals.next_count()?;
self.statekey_shortstatekey
.insert(&statekey, &shortstatekey.to_be_bytes())?;
self.shortstatekey_statekey
@ -190,7 +188,7 @@ impl Service<_> {
/// Returns (shortstatehash, already_existed)
fn get_or_create_shortstatehash(
&self,
state_hash: &StateHashId,
state_hash: &[u8],
) -> Result<(u64, bool)> {
Ok(match self.statehash_shortstatehash.get(state_hash)? {
Some(shortstatehash) => (
@ -199,7 +197,7 @@ impl Service<_> {
true,
),
None => {
let shortstatehash = globals.next_count()?;
let shortstatehash = services().globals.next_count()?;
self.statehash_shortstatehash
.insert(state_hash, &shortstatehash.to_be_bytes())?;
(shortstatehash, false)
@ -220,13 +218,12 @@ impl Service<_> {
pub fn get_or_create_shortroomid(
&self,
room_id: &RoomId,
globals: &super::globals::Globals,
) -> Result<u64> {
Ok(match self.roomid_shortroomid.get(room_id.as_bytes())? {
Some(short) => utils::u64_from_bytes(&short)
.map_err(|_| Error::bad_database("Invalid shortroomid in db."))?,
None => {
let short = globals.next_count()?;
let short = services().globals.next_count()?;
self.roomid_shortroomid
.insert(room_id.as_bytes(), &short.to_be_bytes())?;
short

View file

@ -1,30 +1,28 @@
use std::sync::Arc;
use std::{sync::MutexGuard, collections::HashSet};
use std::fmt::Debug;
use crate::Result;
use ruma::{EventId, RoomId};
pub trait Data {
/// Returns the last state hash key added to the db for the given room.
fn get_room_shortstatehash(room_id: &RoomId);
fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>>;
/// Update the current state of the room.
fn set_room_state(room_id: &RoomId, new_shortstatehash: u64,
_mutex_lock: &MutexGuard<'_, StateLock>, // Take mutex guard to make sure users get the room state mutex
);
fn set_room_state(&self, room_id: &RoomId, new_shortstatehash: u64,
_mutex_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
) -> Result<()>;
/// Associates a state with an event.
fn set_event_state(shorteventid: u64, shortstatehash: u64) -> Result<()>;
fn set_event_state(&self, shorteventid: u64, shortstatehash: u64) -> Result<()>;
/// Returns all events we would send as the prev_events of the next event.
fn get_forward_extremities(room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>;
fn get_forward_extremities(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>;
/// Replace the forward extremities of the room.
fn set_forward_extremities(
fn set_forward_extremities<'a>(&self,
room_id: &RoomId,
event_ids: impl IntoIterator<Item = &'_ EventId> + Debug,
_mutex_lock: &MutexGuard<'_, StateLock>, // Take mutex guard to make sure users get the room state mutex
event_ids: impl IntoIterator<Item = &'a EventId> + Debug,
_mutex_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
) -> Result<()>;
}
pub struct StateLock;

View file

@ -6,13 +6,15 @@ use ruma::{RoomId, events::{room::{member::MembershipState, create::RoomCreateEv
use serde::Deserialize;
use tracing::warn;
use crate::{service::*, SERVICE, PduEvent, Error, utils::calculate_hash};
use crate::{Result, services, PduEvent, Error, utils::calculate_hash};
use super::state_compressor::CompressedStateEvent;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Set the room to the given statehash and update caches.
pub fn force_state(
&self,
@ -23,11 +25,11 @@ impl Service<_> {
) -> Result<()> {
for event_id in statediffnew.into_iter().filter_map(|new| {
SERVICE.rooms.state_compressor.parse_compressed_state_event(new)
services().rooms.state_compressor.parse_compressed_state_event(new)
.ok()
.map(|(_, id)| id)
}) {
let pdu = match SERVICE.rooms.timeline.get_pdu_json(&event_id)? {
let pdu = match services().rooms.timeline.get_pdu_json(&event_id)? {
Some(pdu) => pdu,
None => continue,
};
@ -63,10 +65,10 @@ impl Service<_> {
Err(_) => continue,
};
SERVICE.room.state_cache.update_membership(room_id, &user_id, membership, &pdu.sender, None, false)?;
services().room.state_cache.update_membership(room_id, &user_id, membership, &pdu.sender, None, false)?;
}
SERVICE.room.state_cache.update_joined_count(room_id)?;
services().room.state_cache.update_joined_count(room_id)?;
self.db.set_room_state(room_id, shortstatehash);
@ -84,7 +86,7 @@ impl Service<_> {
room_id: &RoomId,
state_ids_compressed: HashSet<CompressedStateEvent>,
) -> Result<()> {
let shorteventid = SERVICE.short.get_or_create_shorteventid(event_id)?;
let shorteventid = services().short.get_or_create_shorteventid(event_id)?;
let previous_shortstatehash = self.db.get_room_shortstatehash(room_id)?;
@ -96,11 +98,11 @@ impl Service<_> {
);
let (shortstatehash, already_existed) =
SERVICE.short.get_or_create_shortstatehash(&state_hash)?;
services().short.get_or_create_shortstatehash(&state_hash)?;
if !already_existed {
let states_parents = previous_shortstatehash
.map_or_else(|| Ok(Vec::new()), |p| SERVICE.room.state_compressor.load_shortstatehash_info(p))?;
.map_or_else(|| Ok(Vec::new()), |p| services().room.state_compressor.load_shortstatehash_info(p))?;
let (statediffnew, statediffremoved) =
if let Some(parent_stateinfo) = states_parents.last() {
@ -119,7 +121,7 @@ impl Service<_> {
} else {
(state_ids_compressed, HashSet::new())
};
SERVICE.room.state_compressor.save_state_from_diff(
services().room.state_compressor.save_state_from_diff(
shortstatehash,
statediffnew,
statediffremoved,
@ -176,7 +178,7 @@ impl Service<_> {
}
// TODO: statehash with deterministic inputs
let shortstatehash = SERVICE.globals.next_count()?;
let shortstatehash = services().globals.next_count()?;
let mut statediffnew = HashSet::new();
statediffnew.insert(new);
@ -273,4 +275,8 @@ impl Service<_> {
.ok_or_else(|| Error::BadDatabase("Invalid room version"))?;
Ok(room_version)
}
pub fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>> {
self.db.get_room_shortstatehash(room_id)
}
}

View file

@ -1,9 +1,11 @@
use std::{sync::Arc, collections::HashMap};
use std::{sync::Arc, collections::{HashMap, BTreeMap}};
use async_trait::async_trait;
use ruma::{EventId, events::StateEventType, RoomId};
use crate::PduEvent;
use crate::{Result, PduEvent};
#[async_trait]
pub trait Data {
/// Builds a StateMap by iterating over all keys that start
/// with state_hash, this gives the full state for the given state_hash.

View file

@ -4,13 +4,13 @@ use std::{sync::Arc, collections::{HashMap, BTreeMap}};
pub use data::Data;
use ruma::{events::StateEventType, RoomId, EventId};
use crate::{service::*, PduEvent};
use crate::{Result, PduEvent};
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Builds a StateMap by iterating over all keys that start
/// with state_hash, this gives the full state for the given state_hash.
#[tracing::instrument(skip(self))]

View file

@ -1,5 +1,9 @@
use ruma::{UserId, RoomId};
use ruma::{UserId, RoomId, serde::Raw, events::AnyStrippedStateEvent};
use crate::Result;
pub trait Data {
fn mark_as_once_joined(user_id: &UserId, room_id: &RoomId) -> Result<()>;
fn mark_as_once_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<()>;
fn mark_as_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<()>;
fn mark_as_invited(&self, user_id: &UserId, room_id: &RoomId, last_state: Option<Vec<Raw<AnyStrippedStateEvent>>>) -> Result<()>;
fn mark_as_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<()>;
}

View file

@ -5,13 +5,13 @@ pub use data::Data;
use regex::Regex;
use ruma::{RoomId, UserId, events::{room::{member::MembershipState, create::RoomCreateEventContent}, AnyStrippedStateEvent, StateEventType, tag::TagEvent, RoomAccountDataEventType, GlobalAccountDataEventType, direct::DirectEvent, ignored_user_list::IgnoredUserListEvent, AnySyncStateEvent}, serde::Raw, ServerName};
use crate::{service::*, SERVICE, utils, Error};
use crate::{Result, services, utils, Error};
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/// Update current membership data.
#[tracing::instrument(skip(self, last_state))]
pub fn update_membership(
@ -24,8 +24,8 @@ impl Service<_> {
update_joined_count: bool,
) -> Result<()> {
// Keep track what remote users exist by adding them as "deactivated" users
if user_id.server_name() != SERVICE.globals.server_name() {
SERVICE.users.create(user_id, None)?;
if user_id.server_name() != services().globals.server_name() {
services().users.create(user_id, None)?;
// TODO: displayname, avatar url
}
@ -37,10 +37,6 @@ impl Service<_> {
serverroom_id.push(0xff);
serverroom_id.extend_from_slice(room_id.as_bytes());
let mut roomuser_id = room_id.as_bytes().to_vec();
roomuser_id.push(0xff);
roomuser_id.extend_from_slice(user_id.as_bytes());
match &membership {
MembershipState::Join => {
// Check if the user never joined this room
@ -80,24 +76,23 @@ impl Service<_> {
// .ok();
// Copy old tags to new room
if let Some(tag_event) = db.account_data.get::<TagEvent>(
if let Some(tag_event) = services().account_data.get::<TagEvent>(
Some(&predecessor.room_id),
user_id,
RoomAccountDataEventType::Tag,
)? {
SERVICE.account_data
services().account_data
.update(
Some(room_id),
user_id,
RoomAccountDataEventType::Tag,
&tag_event,
&db.globals,
)
.ok();
};
// Copy direct chat flag
if let Some(mut direct_event) = SERVICE.account_data.get::<DirectEvent>(
if let Some(mut direct_event) = services().account_data.get::<DirectEvent>(
None,
user_id,
GlobalAccountDataEventType::Direct.to_string().into(),
@ -112,7 +107,7 @@ impl Service<_> {
}
if room_ids_updated {
SERVICE.account_data.update(
services().account_data.update(
None,
user_id,
GlobalAccountDataEventType::Direct.to_string().into(),
@ -123,16 +118,11 @@ impl Service<_> {
}
}
self.userroomid_joined.insert(&userroom_id, &[])?;
self.roomuserid_joined.insert(&roomuser_id, &[])?;
self.userroomid_invitestate.remove(&userroom_id)?;
self.roomuserid_invitecount.remove(&roomuser_id)?;
self.userroomid_leftstate.remove(&userroom_id)?;
self.roomuserid_leftcount.remove(&roomuser_id)?;
self.db.mark_as_joined(user_id, room_id)?;
}
MembershipState::Invite => {
// We want to know if the sender is ignored by the receiver
let is_ignored = SERVICE
let is_ignored = services()
.account_data
.get::<IgnoredUserListEvent>(
None, // Ignored users are in global account data
@ -153,41 +143,22 @@ impl Service<_> {
return Ok(());
}
self.userroomid_invitestate.insert(
&userroom_id,
&serde_json::to_vec(&last_state.unwrap_or_default())
.expect("state to bytes always works"),
)?;
self.roomuserid_invitecount
.insert(&roomuser_id, &db.globals.next_count()?.to_be_bytes())?;
self.userroomid_joined.remove(&userroom_id)?;
self.roomuserid_joined.remove(&roomuser_id)?;
self.userroomid_leftstate.remove(&userroom_id)?;
self.roomuserid_leftcount.remove(&roomuser_id)?;
self.db.mark_as_invited(user_id, room_id, last_state)?;
}
MembershipState::Leave | MembershipState::Ban => {
self.userroomid_leftstate.insert(
&userroom_id,
&serde_json::to_vec(&Vec::<Raw<AnySyncStateEvent>>::new()).unwrap(),
)?; // TODO
self.roomuserid_leftcount
.insert(&roomuser_id, &db.globals.next_count()?.to_be_bytes())?;
self.userroomid_joined.remove(&userroom_id)?;
self.roomuserid_joined.remove(&roomuser_id)?;
self.userroomid_invitestate.remove(&userroom_id)?;
self.roomuserid_invitecount.remove(&roomuser_id)?;
self.db.mark_as_left(user_id, room_id)?;
}
_ => {}
}
if update_joined_count {
self.update_joined_count(room_id, db)?;
self.update_joined_count(room_id)?;
}
Ok(())
}
#[tracing::instrument(skip(self, room_id, db))]
#[tracing::instrument(skip(self, room_id))]
pub fn update_joined_count(&self, room_id: &RoomId) -> Result<()> {
let mut joinedcount = 0_u64;
let mut invitedcount = 0_u64;
@ -196,8 +167,8 @@ impl Service<_> {
for joined in self.room_members(room_id).filter_map(|r| r.ok()) {
joined_servers.insert(joined.server_name().to_owned());
if joined.server_name() == db.globals.server_name()
&& !db.users.is_deactivated(&joined).unwrap_or(true)
if joined.server_name() == services().globals.server_name()
&& !services().users.is_deactivated(&joined).unwrap_or(true)
{
real_users.insert(joined);
}
@ -285,7 +256,7 @@ impl Service<_> {
.get("sender_localpart")
.and_then(|string| string.as_str())
.and_then(|string| {
UserId::parse_with_server_name(string, SERVICE.globals.server_name()).ok()
UserId::parse_with_server_name(string, services().globals.server_name()).ok()
});
let in_room = bridge_user_id

View file

@ -1,4 +1,5 @@
use crate::service::rooms::CompressedStateEvent;
use super::CompressedStateEvent;
use crate::Result;
pub struct StateDiff {
parent: Option<u64>,
@ -7,6 +8,6 @@ pub struct StateDiff {
}
pub trait Data {
fn get_statediff(shortstatehash: u64) -> Result<StateDiff>;
fn save_statediff(shortstatehash: u64, diff: StateDiff) -> Result<()>;
fn get_statediff(&self, shortstatehash: u64) -> Result<StateDiff>;
fn save_statediff(&self, shortstatehash: u64, diff: StateDiff) -> Result<()>;
}

View file

@ -4,7 +4,7 @@ use std::{mem::size_of, sync::Arc, collections::HashSet};
pub use data::Data;
use ruma::{EventId, RoomId};
use crate::{service::*, utils};
use crate::{Result, utils, services};
use self::data::StateDiff;
@ -12,7 +12,9 @@ pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
pub type CompressedStateEvent = [u8; 2 * size_of::<u64>()];
impl<D: Data> Service<D> {
/// Returns a stack with info on shortstatehash, full state, added diff and removed diff for the selected shortstatehash and each parent layer.
#[tracing::instrument(skip(self))]
pub fn load_shortstatehash_info(
@ -62,12 +64,11 @@ impl Service<_> {
&self,
shortstatekey: u64,
event_id: &EventId,
globals: &super::globals::Globals,
) -> Result<CompressedStateEvent> {
let mut v = shortstatekey.to_be_bytes().to_vec();
v.extend_from_slice(
&self
.get_or_create_shorteventid(event_id, globals)?
.get_or_create_shorteventid(event_id)?
.to_be_bytes(),
);
Ok(v.try_into().expect("we checked the size above"))
@ -210,15 +211,16 @@ impl Service<_> {
/// Returns the new shortstatehash
pub fn save_state(
&self,
room_id: &RoomId,
new_state_ids_compressed: HashSet<CompressedStateEvent>,
) -> Result<(u64,
HashSet<CompressedStateEvent>, // added
HashSet<CompressedStateEvent>)> // removed
{
let previous_shortstatehash = self.d.current_shortstatehash(room_id)?;
let previous_shortstatehash = self.db.current_shortstatehash(room_id)?;
let state_hash = self.calculate_hash(
let state_hash = utils::calculate_hash(
&new_state_ids_compressed
.iter()
.map(|bytes| &bytes[..])
@ -226,7 +228,7 @@ impl Service<_> {
);
let (new_shortstatehash, already_existed) =
self.get_or_create_shortstatehash(&state_hash, &db.globals)?;
services().rooms.short.get_or_create_shortstatehash(&state_hash)?;
if Some(new_shortstatehash) == previous_shortstatehash {
return Ok(());

View file

@ -2,7 +2,7 @@ use std::sync::Arc;
use ruma::{signatures::CanonicalJsonObject, EventId, UserId, RoomId};
use crate::PduEvent;
use crate::{Result, PduEvent};
pub trait Data {
fn last_timeline_count(&self, sender_user: &UserId, room_id: &RoomId) -> Result<u64>;
@ -48,28 +48,26 @@ pub trait Data {
/// Returns an iterator over all events in a room that happened after the event with id `since`
/// in chronological order.
#[tracing::instrument(skip(self))]
fn pdus_since<'a>(
&'a self,
user_id: &UserId,
room_id: &RoomId,
since: u64,
) -> Result<impl Iterator<Item = Result<(Vec<u8>, PduEvent)>> + 'a>;
) -> Result<Box<dyn Iterator<Item = Result<(Vec<u8>, PduEvent)>>>>;
/// Returns an iterator over all events and their tokens in a room that happened before the
/// event with id `until` in reverse-chronological order.
#[tracing::instrument(skip(self))]
fn pdus_until<'a>(
&'a self,
user_id: &UserId,
room_id: &RoomId,
until: u64,
) -> Result<impl Iterator<Item = Result<(Vec<u8>, PduEvent)>> + 'a>;
) -> Result<Box<dyn Iterator<Item = Result<(Vec<u8>, PduEvent)>>>>;
fn pdus_after<'a>(
&'a self,
user_id: &UserId,
room_id: &RoomId,
from: u64,
) -> Result<impl Iterator<Item = Result<(Vec<u8>, PduEvent)>> + 'a>;
) -> Result<Box<dyn Iterator<Item = Result<(Vec<u8>, PduEvent)>>>>;
}

View file

@ -1,23 +1,29 @@
mod data;
use std::borrow::Cow;
use std::sync::Arc;
use std::{sync::MutexGuard, iter, collections::HashSet};
use std::fmt::Debug;
pub use data::Data;
use regex::Regex;
use ruma::events::room::power_levels::RoomPowerLevelsEventContent;
use ruma::push::Ruleset;
use ruma::signatures::CanonicalJsonValue;
use ruma::state_res::RoomVersion;
use ruma::{EventId, signatures::CanonicalJsonObject, push::{Action, Tweak}, events::{push_rules::PushRulesEvent, GlobalAccountDataEventType, RoomEventType, room::{member::MembershipState, create::RoomCreateEventContent}, StateEventType}, UserId, RoomAliasId, RoomId, uint, state_res, api::client::error::ErrorKind, serde::to_canonical_value, ServerName};
use serde::Deserialize;
use serde_json::value::to_raw_value;
use tracing::{warn, error};
use crate::SERVICE;
use crate::{service::{*, pdu::{PduBuilder, EventHash}}, Error, PduEvent, utils};
use crate::{services, Result, service::pdu::{PduBuilder, EventHash}, Error, PduEvent, utils};
use super::state_compressor::CompressedStateEvent;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
/*
/// Checks if a room exists.
#[tracing::instrument(skip(self))]
@ -44,7 +50,7 @@ impl Service<_> {
#[tracing::instrument(skip(self))]
pub fn last_timeline_count(&self, sender_user: &UserId, room_id: &RoomId) -> Result<u64> {
self.db.last_timeline_count(sender_user: &UserId, room_id: &RoomId)
self.db.last_timeline_count(sender_user, room_id)
}
// TODO Is this the same as the function above?
@ -127,7 +133,7 @@ impl Service<_> {
/// Removes a pdu and creates a new one with the same id.
#[tracing::instrument(skip(self))]
fn replace_pdu(&self, pdu_id: &[u8], pdu: &PduEvent) -> Result<()> {
self.db.pdu_count(pdu_id, pdu: &PduEvent)
self.db.replace_pdu(pdu_id, pdu)
}
/// Creates a new persisted data unit and adds it to a room.
@ -177,7 +183,7 @@ impl Service<_> {
self.replace_pdu_leaves(&pdu.room_id, leaves)?;
let mutex_insert = Arc::clone(
db.globals
services().globals
.roomid_mutex_insert
.write()
.unwrap()
@ -186,14 +192,14 @@ impl Service<_> {
);
let insert_lock = mutex_insert.lock().unwrap();
let count1 = db.globals.next_count()?;
let count1 = services().globals.next_count()?;
// Mark as read first so the sending client doesn't get a notification even if appending
// fails
self.edus
.private_read_set(&pdu.room_id, &pdu.sender, count1, &db.globals)?;
.private_read_set(&pdu.room_id, &pdu.sender, count1)?;
self.reset_notification_counts(&pdu.sender, &pdu.room_id)?;
let count2 = db.globals.next_count()?;
let count2 = services().globals.next_count()?;
let mut pdu_id = shortroomid.to_be_bytes().to_vec();
pdu_id.extend_from_slice(&count2.to_be_bytes());
@ -218,7 +224,7 @@ impl Service<_> {
drop(insert_lock);
// See if the event matches any known pushers
let power_levels: RoomPowerLevelsEventContent = db
let power_levels: RoomPowerLevelsEventContent = services()
.rooms
.room_state_get(&pdu.room_id, &StateEventType::RoomPowerLevels, "")?
.map(|ev| {
@ -233,13 +239,13 @@ impl Service<_> {
let mut notifies = Vec::new();
let mut highlights = Vec::new();
for user in self.get_our_real_users(&pdu.room_id, db)?.iter() {
for user in self.get_our_real_users(&pdu.room_id)?.iter() {
// Don't notify the user of their own events
if user == &pdu.sender {
continue;
}
let rules_for_user = db
let rules_for_user = services()
.account_data
.get(
None,
@ -252,7 +258,7 @@ impl Service<_> {
let mut highlight = false;
let mut notify = false;
for action in pusher::get_actions(
for action in services().pusher.get_actions(
user,
&rules_for_user,
&power_levels,
@ -282,8 +288,8 @@ impl Service<_> {
highlights.push(userroom_id);
}
for senderkey in db.pusher.get_pusher_senderkeys(user) {
db.sending.send_push_pdu(&*pdu_id, senderkey)?;
for senderkey in services().pusher.get_pusher_senderkeys(user) {
services().sending.send_push_pdu(&*pdu_id, senderkey)?;
}
}
@ -328,7 +334,6 @@ impl Service<_> {
content.membership,
&pdu.sender,
invite_state,
db,
true,
)?;
}
@ -344,34 +349,34 @@ impl Service<_> {
.map_err(|_| Error::bad_database("Invalid content in pdu."))?;
if let Some(body) = content.body {
DB.rooms.search.index_pdu(room_id, pdu_id, body)?;
services().rooms.search.index_pdu(shortroomid, pdu_id, body)?;
let admin_room = self.id_from_alias(
let admin_room = self.alias.resolve_local_alias(
<&RoomAliasId>::try_from(
format!("#admins:{}", db.globals.server_name()).as_str(),
format!("#admins:{}", services().globals.server_name()).as_str(),
)
.expect("#admins:server_name is a valid room alias"),
)?;
let server_user = format!("@conduit:{}", db.globals.server_name());
let server_user = format!("@conduit:{}", services().globals.server_name());
let to_conduit = body.starts_with(&format!("{}: ", server_user));
// This will evaluate to false if the emergency password is set up so that
// the administrator can execute commands as conduit
let from_conduit =
pdu.sender == server_user && db.globals.emergency_password().is_none();
pdu.sender == server_user && services().globals.emergency_password().is_none();
if to_conduit && !from_conduit && admin_room.as_ref() == Some(&pdu.room_id) {
db.admin.process_message(body.to_string());
services().admin.process_message(body.to_string());
}
}
}
_ => {}
}
for appservice in db.appservice.all()? {
if self.appservice_in_room(room_id, &appservice, db)? {
db.sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
for appservice in services().appservice.all()? {
if self.appservice_in_room(&pdu.room_id, &appservice)? {
services().sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
continue;
}
@ -388,11 +393,11 @@ impl Service<_> {
.get("sender_localpart")
.and_then(|string| string.as_str())
.and_then(|string| {
UserId::parse_with_server_name(string, db.globals.server_name()).ok()
UserId::parse_with_server_name(string, services().globals.server_name()).ok()
})
{
if state_key_uid == &appservice_uid {
db.sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
services().sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
continue;
}
}
@ -431,16 +436,16 @@ impl Service<_> {
.map_or(false, |state_key| users.is_match(state_key))
};
let matching_aliases = |aliases: &Regex| {
self.room_aliases(room_id)
self.room_aliases(&pdu.room_id)
.filter_map(|r| r.ok())
.any(|room_alias| aliases.is_match(room_alias.as_str()))
};
if aliases.iter().any(matching_aliases)
|| rooms.map_or(false, |rooms| rooms.contains(&room_id.as_str().into()))
|| rooms.map_or(false, |rooms| rooms.contains(&pdu.room_id.as_str().into()))
|| users.iter().any(matching_users)
{
db.sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
services().sending.send_pdu_appservice(&appservice.0, &pdu_id)?;
}
}
}
@ -464,14 +469,14 @@ impl Service<_> {
redacts,
} = pdu_builder;
let prev_events: Vec<_> = SERVICE
let prev_events: Vec<_> = services()
.rooms
.get_pdu_leaves(room_id)?
.into_iter()
.take(20)
.collect();
let create_event = SERVICE
let create_event = services()
.rooms
.room_state_get(room_id, &StateEventType::RoomCreate, "")?;
@ -488,7 +493,7 @@ impl Service<_> {
// If there was no create event yet, assume we are creating a room with the default
// version right now
let room_version_id = create_event_content
.map_or(SERVICE.globals.default_room_version(), |create_event| {
.map_or(services().globals.default_room_version(), |create_event| {
create_event.room_version
});
let room_version =
@ -500,7 +505,7 @@ impl Service<_> {
// Our depth is the maximum depth of prev_events + 1
let depth = prev_events
.iter()
.filter_map(|event_id| Some(db.rooms.get_pdu(event_id).ok()??.depth))
.filter_map(|event_id| Some(services().rooms.get_pdu(event_id).ok()??.depth))
.max()
.unwrap_or_else(|| uint!(0))
+ uint!(1);
@ -525,7 +530,7 @@ impl Service<_> {
let pdu = PduEvent {
event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
room_id: room_id.to_owned(),
sender: sender_user.to_owned(),
sender: sender.to_owned(),
origin_server_ts: utils::millis_since_unix_epoch()
.try_into()
.expect("time is valid"),
@ -577,13 +582,13 @@ impl Service<_> {
// Add origin because synapse likes that (and it's required in the spec)
pdu_json.insert(
"origin".to_owned(),
to_canonical_value(db.globals.server_name())
to_canonical_value(services().globals.server_name())
.expect("server name is a valid CanonicalJsonValue"),
);
match ruma::signatures::hash_and_sign_event(
SERVICE.globals.server_name().as_str(),
SERVICE.globals.keypair(),
services().globals.server_name().as_str(),
services().globals.keypair(),
&mut pdu_json,
&room_version_id,
) {
@ -616,22 +621,20 @@ impl Service<_> {
);
// Generate short event id
let _shorteventid = self.get_or_create_shorteventid(&pdu.event_id, &db.globals)?;
let _shorteventid = self.get_or_create_shorteventid(&pdu.event_id)?;
}
/// Creates a new persisted data unit and adds it to a room. This function takes a
/// roomid_mutex_state, meaning that only this function is able to mutate the room state.
#[tracing::instrument(skip(self, _mutex_lock))]
#[tracing::instrument(skip(self, state_lock))]
pub fn build_and_append_pdu(
&self,
pdu_builder: PduBuilder,
sender: &UserId,
room_id: &RoomId,
_mutex_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
state_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
) -> Result<Arc<EventId>> {
let (pdu, pdu_json) = self.create_hash_and_sign_event()?;
let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, &state_lock);
// We append to state before appending the pdu, so we don't have a moment in time with the
// pdu without it's state. This is okay because append_pdu can't fail.
@ -664,9 +667,9 @@ impl Service<_> {
}
// Remove our server from the server list since it will be added to it by room_servers() and/or the if statement above
servers.remove(SERVICE.globals.server_name());
servers.remove(services().globals.server_name());
SERVICE.sending.send_pdu(servers.into_iter(), &pdu_id)?;
services().sending.send_pdu(servers.into_iter(), &pdu_id)?;
Ok(pdu.event_id)
}
@ -684,20 +687,20 @@ impl Service<_> {
) -> Result<Option<Vec<u8>>> {
// We append to state before appending the pdu, so we don't have a moment in time with the
// pdu without it's state. This is okay because append_pdu can't fail.
SERVICE.rooms.set_event_state(
services().rooms.set_event_state(
&pdu.event_id,
&pdu.room_id,
state_ids_compressed,
)?;
if soft_fail {
SERVICE.rooms
services().rooms
.mark_as_referenced(&pdu.room_id, &pdu.prev_events)?;
SERVICE.rooms.replace_pdu_leaves(&pdu.room_id, new_room_leaves)?;
services().rooms.replace_pdu_leaves(&pdu.room_id, new_room_leaves)?;
return Ok(None);
}
let pdu_id = SERVICE.rooms.append_pdu(pdu, pdu_json, new_room_leaves)?;
let pdu_id = services().rooms.append_pdu(pdu, pdu_json, new_room_leaves)?;
Ok(Some(pdu_id))
}

View file

@ -1,3 +1,6 @@
use ruma::{UserId, RoomId};
use crate::Result;
pub trait Data {
fn reset_notification_counts(&self, user_id: &UserId, room_id: &RoomId) -> Result<()>;
@ -17,5 +20,5 @@ pub trait Data {
fn get_shared_rooms<'a>(
&'a self,
users: Vec<Box<UserId>>,
) -> Result<impl Iterator<Item = Result<Box<RoomId>>> + 'a>;
) -> Result<Box<dyn Iterator<Item = Result<Box<RoomId>>>>>;
}

View file

@ -2,13 +2,13 @@ mod data;
pub use data::Data;
use ruma::{RoomId, UserId};
use crate::service::*;
use crate::Result;
pub struct Service<D: Data> {
db: D,
}
impl Service<_> {
impl<D: Data> Service<D> {
pub fn reset_notification_counts(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> {
self.db.reset_notification_counts(user_id, room_id)
}
@ -27,7 +27,7 @@ impl Service<_> {
token: u64,
shortstatehash: u64,
) -> Result<()> {
self.db.associate_token_shortstatehash(user_id, room_id)
self.db.associate_token_shortstatehash(room_id, token, shortstatehash)
}
pub fn get_token_shortstatehash(&self, room_id: &RoomId, token: u64) -> Result<Option<u64>> {