stop passing the entire create event around

This gets rid of 3 instances of re-parsing the room version.

There's one place where we need the event ID of the room create event to
verify federation responses, so now we just look up the event ID at that
point instead.
This commit is contained in:
Charles Hall 2024-11-08 18:27:47 -08:00
parent a4e1522875
commit 9d0cf428a5
No known key found for this signature in database
GPG key ID: 7B8E0645816E07CF

View file

@ -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::<ExtractVersion>(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<BTreeMap<String, SigningKeys>>,
@ -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::<Vec<_>>(),
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<PduEvent>,
val: CanonicalJsonObject,
create_event: &PduEvent,
origin: &ServerName,
room_id: &RoomId,
room_version_id: &RoomVersionId,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
) -> Result<Option<PduId>> {
// 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<EventId>],
create_event: &'a PduEvent,
room_id: &'a RoomId,
room_version_id: &'a RoomVersionId,
pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>,
@ -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<BTreeMap<String, SigningKeys>>,
@ -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,