diff --git a/src/service/rooms/event_handler.rs b/src/service/rooms/event_handler.rs index d5e7a6a4..1543e423 100644 --- a/src/service/rooms/event_handler.rs +++ b/src/service/rooms/event_handler.rs @@ -20,7 +20,6 @@ use ruma::{ }, events::{ room::{ - create::RoomCreateEventContent, redaction::RoomRedactionEventContent, server_acl::RoomServerAclEventContent, }, @@ -42,7 +41,7 @@ use super::{ timeline::PduId, }; use crate::{ - service::{globals::SigningKeys, pdu}, + service::{globals::SigningKeys, pdu, rooms::state::ExtractVersion}, services, utils::{debug_slice_truncated, room_version::RoomVersion}, Error, PduEvent, Result, @@ -115,34 +114,22 @@ impl Service { return Ok(Some(pdu_id.clone())); } - let create_event = services() - .rooms - .state_accessor - .room_state_get(room_id, &StateEventType::RoomCreate, "")? - .ok_or_else(|| { - Error::bad_database("Failed to find create event in db.") - })?; - - let create_event_content: RoomCreateEventContent = - serde_json::from_str(create_event.content.get()).map_err( - |error| { - error!(%error, "Invalid create event"); - Error::BadDatabase("Invalid create event.") - }, - )?; - let room_version_id = &create_event_content.room_version; - let first_pdu_in_room = services().rooms.timeline.first_pdu_in_room(room_id)?.ok_or_else( || Error::bad_database("Failed to find first pdu in db."), )?; + let room_version_id = services() + .rooms + .state + .get_create_content::(room_id)?; + let (incoming_pdu, val) = self .handle_outlier_pdu( origin, - &create_event, event_id, room_id, + &room_version_id, value, false, pub_key_map, @@ -165,9 +152,8 @@ impl Service { let (sorted_prev_events, mut eventid_info) = self .fetch_unknown_prev_events( origin, - &create_event, room_id, - room_version_id, + &room_version_id, pub_key_map, incoming_pdu.prev_events.clone(), ) @@ -245,9 +231,9 @@ impl Service { .upgrade_outlier_to_timeline_pdu( pdu, json, - &create_event, origin, room_id, + &room_version_id, pub_key_map, ) .await @@ -296,9 +282,9 @@ impl Service { .upgrade_outlier_to_timeline_pdu( incoming_pdu, val, - &create_event, origin, room_id, + &room_version_id, pub_key_map, ) .await; @@ -317,9 +303,9 @@ impl Service { fn handle_outlier_pdu<'a>( &'a self, origin: &'a ServerName, - create_event: &'a PduEvent, event_id: &'a EventId, room_id: &'a RoomId, + room_version_id: &'a RoomVersionId, mut value: CanonicalJsonObject, auth_events_known: bool, pub_key_map: &'a RwLock>, @@ -330,15 +316,7 @@ impl Service { // 2. Check signatures, otherwise drop // 3. check content hash, redact if doesn't match - let create_event_content: RoomCreateEventContent = - serde_json::from_str(create_event.content.get()).map_err( - |error| { - error!(%error, "Invalid create event"); - Error::BadDatabase("Invalid create event in db") - }, - )?; - let room_version_id = &create_event_content.room_version; let ruma_room_version = state_res::RoomVersion::new(room_version_id).map_err(|_| { Error::UnsupportedRoomVersion(room_version_id.clone()) @@ -470,7 +448,6 @@ impl Service { .iter() .map(|x| Arc::from(&**x)) .collect::>(), - create_event, room_id, room_version_id, pub_key_map, @@ -560,15 +537,14 @@ impl Service { #[tracing::instrument(skip_all, fields( incoming_pdu = %incoming_pdu.event_id, - create_event = %create_event.event_id, ))] pub(crate) async fn upgrade_outlier_to_timeline_pdu( &self, incoming_pdu: Arc, val: CanonicalJsonObject, - create_event: &PduEvent, origin: &ServerName, room_id: &RoomId, + room_version_id: &RoomVersionId, pub_key_map: &RwLock>, ) -> Result> { // Skip the PDU if we already have it as a timeline event @@ -594,15 +570,6 @@ impl Service { "Upgrading event to timeline pdu", ); - let create_event_content: RoomCreateEventContent = - serde_json::from_str(create_event.content.get()).map_err( - |error| { - warn!(%error, "Invalid create event"); - Error::BadDatabase("Invalid create event in db") - }, - )?; - - let room_version_id = &create_event_content.room_version; let room_version = RoomVersion::try_from(room_version_id)?; let ruma_room_version = state_res::RoomVersion::new(room_version_id) .map_err(|_| { @@ -822,7 +789,6 @@ impl Service { .fetch_and_handle_outliers( origin, &collect, - create_event, room_id, room_version_id, pub_key_map, @@ -859,16 +825,36 @@ impl Service { } } - // The original create event must still be in the state - let create_shortstatekey = services() - .rooms - .short - .get_shortstatekey(&StateEventType::RoomCreate, "")? - .expect("Room exists"); + let new_create_event = state + .get( + &services() + .rooms + .short + .get_shortstatekey( + &StateEventType::RoomCreate, + "", + )? + .expect("Room exists"), + ) + .map(|x| &**x) + .ok_or(Error::BadServerResponse( + "state_ids response did not contain an \ + m.room.create event", + ))?; - if state.get(&create_shortstatekey) - != Some(&create_event.event_id) - { + let original_create_event = &*services() + .rooms + .state_accessor + .room_state_get( + room_id, + &StateEventType::RoomCreate, + "", + )? + .expect("Room exists") + .event_id; + + // The original create event must still be in the state + if new_create_event != original_create_event { return Err(Error::bad_database( "Incoming event refers to wrong create event.", )); @@ -1228,7 +1214,6 @@ impl Service { &'a self, origin: &'a ServerName, events: &'a [Arc], - create_event: &'a PduEvent, room_id: &'a RoomId, room_version_id: &'a RoomVersionId, pub_key_map: &'a RwLock>, @@ -1403,9 +1388,9 @@ impl Service { match self .handle_outlier_pdu( origin, - create_event, next_id, room_id, + room_version_id, value.clone(), true, pub_key_map, @@ -1437,7 +1422,6 @@ impl Service { async fn fetch_unknown_prev_events( &self, origin: &ServerName, - create_event: &PduEvent, room_id: &RoomId, room_version_id: &RoomVersionId, pub_key_map: &RwLock>, @@ -1462,7 +1446,6 @@ impl Service { .fetch_and_handle_outliers( origin, &[prev_event_id.clone()], - create_event, room_id, room_version_id, pub_key_map,