mod acl_check; mod fetch_and_handle_outliers; mod fetch_prev; mod fetch_state; mod handle_incoming_pdu; mod handle_outlier_pdu; mod handle_prev_pdu; mod parse_incoming_pdu; mod resolve_state; mod state_at_incoming; mod upgrade_outlier_pdu; use std::{ collections::HashMap, fmt::Write, sync::{Arc, RwLock as StdRwLock}, time::Instant, }; use conduwuit::{ utils::{MutexMap, TryFutureExtExt}, Err, PduEvent, Result, Server, }; use futures::TryFutureExt; use ruma::{ events::room::create::RoomCreateEventContent, state_res::RoomVersion, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, }; use crate::{globals, rooms, sending, server_keys, Dep}; pub struct Service { pub mutex_federation: RoomMutexMap, pub federation_handletime: StdRwLock, services: Services, } struct Services { globals: Dep, sending: Dep, auth_chain: Dep, metadata: Dep, outlier: Dep, pdu_metadata: Dep, server_keys: Dep, short: Dep, state: Dep, state_accessor: Dep, state_compressor: Dep, timeline: Dep, server: Arc, } type RoomMutexMap = MutexMap; type HandleTimeMap = HashMap; impl crate::Service for Service { fn build(args: crate::Args<'_>) -> Result> { Ok(Arc::new(Self { mutex_federation: RoomMutexMap::new(), federation_handletime: HandleTimeMap::new().into(), services: Services { globals: args.depend::("globals"), sending: args.depend::("sending"), auth_chain: args.depend::("rooms::auth_chain"), metadata: args.depend::("rooms::metadata"), outlier: args.depend::("rooms::outlier"), server_keys: args.depend::("server_keys"), pdu_metadata: args.depend::("rooms::pdu_metadata"), short: args.depend::("rooms::short"), state: args.depend::("rooms::state"), state_accessor: args .depend::("rooms::state_accessor"), state_compressor: args .depend::("rooms::state_compressor"), timeline: args.depend::("rooms::timeline"), server: args.server.clone(), }, })) } fn memory_usage(&self, out: &mut dyn Write) -> Result<()> { let mutex_federation = self.mutex_federation.len(); writeln!(out, "federation_mutex: {mutex_federation}")?; let federation_handletime = self .federation_handletime .read() .expect("locked for reading") .len(); writeln!(out, "federation_handletime: {federation_handletime}")?; Ok(()) } fn name(&self) -> &str { crate::service::make_name(std::module_path!()) } } impl Service { async fn event_exists(&self, event_id: OwnedEventId) -> bool { self.services.timeline.pdu_exists(&event_id).await } async fn event_fetch(&self, event_id: OwnedEventId) -> Option> { self.services .timeline .get_pdu(&event_id) .map_ok(Arc::new) .ok() .await } } fn check_room_id(room_id: &RoomId, pdu: &PduEvent) -> Result { if pdu.room_id != room_id { return Err!(Request(InvalidParam(error!( pdu_event_id = ?pdu.event_id, pdu_room_id = ?pdu.room_id, ?room_id, "Found event from room in room", )))); } Ok(()) } fn get_room_version_id(create_event: &PduEvent) -> Result { let content: RoomCreateEventContent = create_event.get_content()?; let room_version = content.room_version; Ok(room_version) } #[inline] fn to_room_version(room_version_id: &RoomVersionId) -> RoomVersion { RoomVersion::new(room_version_id).expect("room version is supported") }