mirror of
https://github.com/element-hq/synapse.git
synced 2026-05-31 19:44:29 +00:00
Store calculated room ID on top-level
Rather than validating and then re-calcualting it every time, let's just store it on the top-level.
This commit is contained in:
@@ -35,7 +35,7 @@ use crate::events::formats::EventCommonFields;
|
||||
pub struct EventFormatV1 {
|
||||
pub auth_events: Vec<(String, HashMap<String, String>)>,
|
||||
pub prev_events: Vec<(String, HashMap<String, String>)>,
|
||||
pub room_id: Box<str>,
|
||||
pub room_id: Arc<str>,
|
||||
pub event_id: Arc<str>,
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
//! [`SimpleAuthPrevEvents`] is shared with [`v4`](super::v4) since the
|
||||
//! flat-list encoding carries forward unchanged.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -37,7 +39,7 @@ use crate::events::formats::EventCommonFields;
|
||||
/// Version-specific fields for room versions 3-10.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct EventFormatV2V3 {
|
||||
pub room_id: Box<str>,
|
||||
pub room_id: Arc<str>,
|
||||
pub auth_events: Vec<String>,
|
||||
pub prev_events: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
//! [`EventFormatV4::room_id`] and [`EventFormatV4::auth_event_ids`]
|
||||
//! expose the derived values to callers.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{bail, ensure, Error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -45,15 +45,13 @@ pub struct EventFormatV4 {
|
||||
with = "crate::json::allow_missing",
|
||||
skip_serializing_if = "AllowMissing::is_absent"
|
||||
)]
|
||||
pub room_id: AllowMissing<Box<str>>,
|
||||
pub room_id: AllowMissing<Arc<str>>,
|
||||
pub auth_events: Vec<String>,
|
||||
pub prev_events: Vec<String>,
|
||||
}
|
||||
|
||||
impl EventFormatV4 {
|
||||
pub fn validate(&self, common_fields: &EventCommonFields) -> Result<(), Error> {
|
||||
validate_optional_room_id(self.room_id.as_deref_opt(), common_fields)?;
|
||||
|
||||
// Ensure that we don't have an event_id set.
|
||||
if common_fields.other_fields.contains_key("event_id") {
|
||||
bail!("v4 events must not have an explicit event_id");
|
||||
@@ -66,8 +64,8 @@ impl EventFormatV4 {
|
||||
&self,
|
||||
event_id: &str,
|
||||
common_fields: &EventCommonFields,
|
||||
) -> Result<Cow<'_, str>, Error> {
|
||||
get_room_id_for_optional_room_id(self.room_id.as_deref_opt(), event_id, common_fields)
|
||||
) -> Result<Arc<str>, Error> {
|
||||
get_room_id_for_optional_room_id(self.room_id.as_ref_opt(), event_id, common_fields)
|
||||
}
|
||||
|
||||
pub fn auth_event_ids(&self, common_fields: &EventCommonFields) -> Result<Vec<String>, Error> {
|
||||
@@ -104,10 +102,10 @@ impl EventFormatV4 {
|
||||
/// Validation helper for v4+ events that can have an optional room ID.
|
||||
///
|
||||
/// Returns the validated room ID (which will be `None` for create events).
|
||||
pub fn validate_optional_room_id<'a>(
|
||||
room_id: Option<&'a str>,
|
||||
pub fn validate_optional_room_id(
|
||||
room_id: Option<&Arc<str>>,
|
||||
common_fields: &'_ EventCommonFields,
|
||||
) -> Result<Option<&'a str>, Error> {
|
||||
) -> Result<Option<Arc<str>>, Error> {
|
||||
let is_create_event = common_fields.type_state_key_tuple() == Some((M_ROOM_CREATE, ""));
|
||||
|
||||
match (is_create_event, room_id) {
|
||||
@@ -123,7 +121,7 @@ pub fn validate_optional_room_id<'a>(
|
||||
room_id
|
||||
);
|
||||
|
||||
Ok(Some(room_id))
|
||||
Ok(Some(Arc::clone(room_id)))
|
||||
}
|
||||
|
||||
// For create events, room_id must be absent.
|
||||
@@ -134,13 +132,13 @@ pub fn validate_optional_room_id<'a>(
|
||||
|
||||
/// Room ID derivation helper for v4+ events, which can have an optional room
|
||||
/// ID.
|
||||
pub fn get_room_id_for_optional_room_id<'a>(
|
||||
room_id: Option<&'a str>,
|
||||
pub fn get_room_id_for_optional_room_id(
|
||||
room_id: Option<&Arc<str>>,
|
||||
event_id: &str,
|
||||
common_fields: &EventCommonFields,
|
||||
) -> Result<Cow<'a, str>, Error> {
|
||||
) -> Result<Arc<str>, Error> {
|
||||
match validate_optional_room_id(room_id, common_fields)? {
|
||||
Some(room_id) => Ok(room_id.into()),
|
||||
Some(room_id) => Ok(room_id),
|
||||
None => {
|
||||
// This is the create event, where the room ID is derived from the
|
||||
// event ID by replacing the leading '$' with '!'.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//!
|
||||
//! [MSC4242]: https://github.com/matrix-org/matrix-spec-proposals/pull/4242
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::bail;
|
||||
use anyhow::Error;
|
||||
@@ -34,7 +34,6 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::events::constants::event_type::M_ROOM_CREATE;
|
||||
use crate::events::formats::v4::get_room_id_for_optional_room_id;
|
||||
use crate::events::formats::v4::validate_optional_room_id;
|
||||
use crate::events::formats::EventCommonFields;
|
||||
use crate::events::Event;
|
||||
use crate::json::AllowMissing;
|
||||
@@ -49,13 +48,11 @@ pub struct EventFormatVMSC4242 {
|
||||
with = "crate::json::allow_missing",
|
||||
skip_serializing_if = "AllowMissing::is_absent"
|
||||
)]
|
||||
pub room_id: AllowMissing<Box<str>>,
|
||||
pub room_id: AllowMissing<Arc<str>>,
|
||||
}
|
||||
|
||||
impl EventFormatVMSC4242 {
|
||||
pub fn validate(&self, common_fields: &EventCommonFields) -> Result<(), Error> {
|
||||
validate_optional_room_id(self.room_id.as_deref_opt(), common_fields)?;
|
||||
|
||||
// Ensure that we don't have any `auth_events` or `event_id` fields
|
||||
// set.
|
||||
if common_fields.other_fields.contains_key("auth_events") {
|
||||
@@ -72,8 +69,8 @@ impl EventFormatVMSC4242 {
|
||||
&self,
|
||||
event_id: &str,
|
||||
common_fields: &EventCommonFields,
|
||||
) -> Result<Cow<'_, str>, Error> {
|
||||
get_room_id_for_optional_room_id(self.room_id.as_deref_opt(), event_id, common_fields)
|
||||
) -> Result<Arc<str>, Error> {
|
||||
get_room_id_for_optional_room_id(self.room_id.as_ref_opt(), event_id, common_fields)
|
||||
}
|
||||
|
||||
pub fn auth_event_ids(&self, event: &Event) -> PyResult<Vec<String>> {
|
||||
|
||||
+32
-12
@@ -48,7 +48,7 @@
|
||||
//! string describing why auth rejected the event.
|
||||
//!
|
||||
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use pyo3::{
|
||||
exceptions::{PyAttributeError, PyKeyError, PyValueError},
|
||||
@@ -137,6 +137,12 @@ pub struct Event {
|
||||
/// construction time and cached here.
|
||||
event_id: Arc<str>,
|
||||
|
||||
/// The calculated room ID.
|
||||
///
|
||||
/// For some room versions this may be derived, e.g. for create events in
|
||||
/// v4.
|
||||
room_id: Arc<str>,
|
||||
|
||||
/// Synapse-internal per-event state that lives outside the federated
|
||||
/// JSON (e.g. outlier flag, soft-failure, stream positions).
|
||||
#[pyo3(get)]
|
||||
@@ -205,10 +211,32 @@ impl Event {
|
||||
}
|
||||
};
|
||||
|
||||
let room_id = match &*parsed_event.specific_fields {
|
||||
EventFormatEnum::V1(format) => Arc::clone(&format.room_id),
|
||||
EventFormatEnum::V2V3(format) => Arc::clone(&format.room_id),
|
||||
EventFormatEnum::V4(format) => format
|
||||
.room_id(&event_id, &parsed_event.common_fields)
|
||||
.map_err(|err| {
|
||||
PyValueError::new_err(format!(
|
||||
"Failed to calculate room_id for event {}: {}",
|
||||
event_id, err
|
||||
))
|
||||
})?,
|
||||
EventFormatEnum::VMSC4242(format) => format
|
||||
.room_id(&event_id, &parsed_event.common_fields)
|
||||
.map_err(|err| {
|
||||
PyValueError::new_err(format!(
|
||||
"Failed to calculate room_id for event {}: {}",
|
||||
event_id, err
|
||||
))
|
||||
})?,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
parsed_event,
|
||||
|
||||
event_id,
|
||||
room_id,
|
||||
room_version,
|
||||
rejected_reason,
|
||||
internal_metadata,
|
||||
@@ -341,6 +369,7 @@ impl Event {
|
||||
room_version: self.room_version,
|
||||
rejected_reason: self.rejected_reason.clone(),
|
||||
event_id: self.event_id.clone(),
|
||||
room_id: self.room_id.clone(),
|
||||
};
|
||||
Ok(new_event)
|
||||
}
|
||||
@@ -432,17 +461,8 @@ impl Event {
|
||||
}
|
||||
|
||||
#[getter]
|
||||
fn room_id(&self) -> PyResult<Cow<'_, str>> {
|
||||
match &*self.parsed_event.specific_fields {
|
||||
EventFormatEnum::V1(format) => Ok(format.room_id.as_ref().into()),
|
||||
EventFormatEnum::V2V3(format) => Ok(format.room_id.as_ref().into()),
|
||||
EventFormatEnum::V4(format) => {
|
||||
Ok(format.room_id(&self.event_id, &self.parsed_event.common_fields)?)
|
||||
}
|
||||
EventFormatEnum::VMSC4242(format) => {
|
||||
Ok(format.room_id(&self.event_id, &self.parsed_event.common_fields)?)
|
||||
}
|
||||
}
|
||||
fn room_id(&self) -> &str {
|
||||
&self.room_id
|
||||
}
|
||||
|
||||
#[getter]
|
||||
|
||||
@@ -64,6 +64,14 @@ impl<T> AllowMissing<T> {
|
||||
AllowMissing::Absent => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts to `Option<&T>`.
|
||||
pub fn as_ref_opt(&self) -> Option<&T> {
|
||||
match self {
|
||||
AllowMissing::Some(inner) => Some(inner),
|
||||
AllowMissing::Absent => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A module that provides the serialization and deserialization logic for
|
||||
|
||||
Reference in New Issue
Block a user