From df16b2ba9817bf56d7b125db33c9539cfacf56d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Thu, 31 Dec 2020 14:52:08 +0100 Subject: [PATCH] fix: rare state races --- src/database/rooms.rs | 29 ++++++++++++++++++----------- src/server_server.rs | 2 +- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/database/rooms.rs b/src/database/rooms.rs index a6d8fea5..ab3dd3f3 100644 --- a/src/database/rooms.rs +++ b/src/database/rooms.rs @@ -678,9 +678,6 @@ impl Rooms { self.stateid_pduid.insert(&state_id, &short_pdu_id)?; } - self.roomid_statehash - .insert(new_pdu.room_id.as_bytes(), &*new_state_hash)?; - Ok(new_state_hash) } else { Err(Error::bad_database( @@ -689,6 +686,13 @@ impl Rooms { } } + pub fn set_room_state(&self, room_id: &RoomId, state_hash: &StateHashId) -> Result<()> { + self.roomid_statehash + .insert(room_id.as_bytes(), state_hash)?; + + Ok(()) + } + /// Creates a new persisted data unit and adds it to a room. #[allow(clippy::too_many_arguments)] pub fn build_and_append_pdu( @@ -929,7 +933,7 @@ impl Rooms { // 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. - self.append_to_state(&pdu_id, &pdu, &globals)?; + let statehashid = self.append_to_state(&pdu_id, &pdu, &globals)?; self.append_pdu( &pdu, @@ -941,6 +945,10 @@ impl Rooms { admin, )?; + // We set the room state after inserting the pdu, so that we never have a moment in time + // where events in the current room state do not exist + self.set_room_state(&room_id, &statehashid)?; + for server in self .room_servers(room_id) .filter_map(|r| r.ok()) @@ -991,13 +999,12 @@ impl Rooms { if bridge_user_id.map_or(false, |bridge_user_id| { self.is_joined(&bridge_user_id, room_id).unwrap_or(false) }) || users.iter().any(|users| { - dbg!( - users.is_match(pdu.sender.as_str()) - || pdu.kind == EventType::RoomMember - && pdu.state_key.as_ref().map_or(false, |state_key| dbg!( - users.is_match(dbg!(&state_key)) - )) - ) + users.is_match(pdu.sender.as_str()) + || pdu.kind == EventType::RoomMember + && pdu + .state_key + .as_ref() + .map_or(false, |state_key| users.is_match(&state_key)) }) || aliases.map_or(false, |aliases| { room_aliases .filter_map(|r| r.ok()) diff --git a/src/server_server.rs b/src/server_server.rs index eb6b2373..7b980e30 100644 --- a/src/server_server.rs +++ b/src/server_server.rs @@ -95,7 +95,7 @@ where ruma::signatures::sign_json( globals.server_name().as_str(), globals.keypair(), - &mut request_json, + dbg!(&mut request_json), ) .expect("our request json is what ruma expects");