mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-12 00:33:02 +02:00
Post-formatting aesthetic and spacing corrections
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
af4f66c768
commit
364293608d
72 changed files with 704 additions and 528 deletions
|
@ -4,11 +4,13 @@ use std::{
|
|||
};
|
||||
|
||||
use conduwuit::{
|
||||
PduEvent, debug, debug_error, debug_warn, implement, pdu, trace,
|
||||
utils::continue_exponential_backoff_secs, warn,
|
||||
Event, PduEvent, debug, debug_error, debug_warn, implement,
|
||||
matrix::event::gen_event_id_canonical_json, trace, utils::continue_exponential_backoff_secs,
|
||||
warn,
|
||||
};
|
||||
use ruma::{
|
||||
CanonicalJsonValue, OwnedEventId, RoomId, ServerName, api::federation::event::get_event,
|
||||
CanonicalJsonValue, EventId, OwnedEventId, RoomId, ServerName,
|
||||
api::federation::event::get_event,
|
||||
};
|
||||
|
||||
use super::get_room_version_id;
|
||||
|
@ -23,13 +25,17 @@ use super::get_room_version_id;
|
|||
/// c. Ask origin server over federation
|
||||
/// d. TODO: Ask other servers over federation?
|
||||
#[implement(super::Service)]
|
||||
pub(super) async fn fetch_and_handle_outliers<'a>(
|
||||
pub(super) async fn fetch_and_handle_outliers<'a, Pdu, Events>(
|
||||
&self,
|
||||
origin: &'a ServerName,
|
||||
events: &'a [OwnedEventId],
|
||||
create_event: &'a PduEvent,
|
||||
events: Events,
|
||||
create_event: &'a Pdu,
|
||||
room_id: &'a RoomId,
|
||||
) -> Vec<(PduEvent, Option<BTreeMap<String, CanonicalJsonValue>>)> {
|
||||
) -> Vec<(PduEvent, Option<BTreeMap<String, CanonicalJsonValue>>)>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
Events: Iterator<Item = &'a EventId> + Clone + Send,
|
||||
{
|
||||
let back_off = |id| match self
|
||||
.services
|
||||
.globals
|
||||
|
@ -46,22 +52,23 @@ pub(super) async fn fetch_and_handle_outliers<'a>(
|
|||
},
|
||||
};
|
||||
|
||||
let mut events_with_auth_events = Vec::with_capacity(events.len());
|
||||
let mut events_with_auth_events = Vec::with_capacity(events.clone().count());
|
||||
|
||||
for id in events {
|
||||
// a. Look in the main timeline (pduid_pdu tree)
|
||||
// b. Look at outlier pdu tree
|
||||
// (get_pdu_json checks both)
|
||||
if let Ok(local_pdu) = self.services.timeline.get_pdu(id).await {
|
||||
trace!("Found {id} in db");
|
||||
events_with_auth_events.push((id, Some(local_pdu), vec![]));
|
||||
events_with_auth_events.push((id.to_owned(), Some(local_pdu), vec![]));
|
||||
continue;
|
||||
}
|
||||
|
||||
// c. Ask origin server over federation
|
||||
// We also handle its auth chain here so we don't get a stack overflow in
|
||||
// handle_outlier_pdu.
|
||||
let mut todo_auth_events: VecDeque<_> = [id.clone()].into();
|
||||
let mut todo_auth_events: VecDeque<_> = [id.to_owned()].into();
|
||||
let mut events_in_reverse_order = Vec::with_capacity(todo_auth_events.len());
|
||||
|
||||
let mut events_all = HashSet::with_capacity(todo_auth_events.len());
|
||||
while let Some(next_id) = todo_auth_events.pop_front() {
|
||||
if let Some((time, tries)) = self
|
||||
|
@ -117,7 +124,7 @@ pub(super) async fn fetch_and_handle_outliers<'a>(
|
|||
};
|
||||
|
||||
let Ok((calculated_event_id, value)) =
|
||||
pdu::gen_event_id_canonical_json(&res.pdu, &room_version_id)
|
||||
gen_event_id_canonical_json(&res.pdu, &room_version_id)
|
||||
else {
|
||||
back_off((*next_id).to_owned());
|
||||
continue;
|
||||
|
@ -160,7 +167,8 @@ pub(super) async fn fetch_and_handle_outliers<'a>(
|
|||
},
|
||||
}
|
||||
}
|
||||
events_with_auth_events.push((id, None, events_in_reverse_order));
|
||||
|
||||
events_with_auth_events.push((id.to_owned(), None, events_in_reverse_order));
|
||||
}
|
||||
|
||||
let mut pdus = Vec::with_capacity(events_with_auth_events.len());
|
||||
|
@ -217,5 +225,6 @@ pub(super) async fn fetch_and_handle_outliers<'a>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pdus
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap, HashSet, VecDeque},
|
||||
iter::once,
|
||||
};
|
||||
|
||||
use conduwuit::{
|
||||
PduEvent, Result, debug_warn, err, implement,
|
||||
Event, PduEvent, Result, debug_warn, err, implement,
|
||||
state_res::{self},
|
||||
};
|
||||
use futures::{FutureExt, future};
|
||||
use ruma::{
|
||||
CanonicalJsonValue, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, ServerName, UInt, int,
|
||||
uint,
|
||||
CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, ServerName,
|
||||
int, uint,
|
||||
};
|
||||
|
||||
use super::check_room_id;
|
||||
|
@ -19,20 +22,26 @@ use super::check_room_id;
|
|||
fields(%origin),
|
||||
)]
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(super) async fn fetch_prev(
|
||||
pub(super) async fn fetch_prev<'a, Pdu, Events>(
|
||||
&self,
|
||||
origin: &ServerName,
|
||||
create_event: &PduEvent,
|
||||
create_event: &Pdu,
|
||||
room_id: &RoomId,
|
||||
first_ts_in_room: UInt,
|
||||
initial_set: Vec<OwnedEventId>,
|
||||
first_ts_in_room: MilliSecondsSinceUnixEpoch,
|
||||
initial_set: Events,
|
||||
) -> Result<(
|
||||
Vec<OwnedEventId>,
|
||||
HashMap<OwnedEventId, (PduEvent, BTreeMap<String, CanonicalJsonValue>)>,
|
||||
)> {
|
||||
let mut graph: HashMap<OwnedEventId, _> = HashMap::with_capacity(initial_set.len());
|
||||
)>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
Events: Iterator<Item = &'a EventId> + Clone + Send,
|
||||
{
|
||||
let num_ids = initial_set.clone().count();
|
||||
let mut eventid_info = HashMap::new();
|
||||
let mut todo_outlier_stack: VecDeque<OwnedEventId> = initial_set.into();
|
||||
let mut graph: HashMap<OwnedEventId, _> = HashMap::with_capacity(num_ids);
|
||||
let mut todo_outlier_stack: VecDeque<OwnedEventId> =
|
||||
initial_set.map(ToOwned::to_owned).collect();
|
||||
|
||||
let mut amount = 0;
|
||||
|
||||
|
@ -40,7 +49,12 @@ pub(super) async fn fetch_prev(
|
|||
self.services.server.check_running()?;
|
||||
|
||||
match self
|
||||
.fetch_and_handle_outliers(origin, &[prev_event_id.clone()], create_event, room_id)
|
||||
.fetch_and_handle_outliers(
|
||||
origin,
|
||||
once(prev_event_id.as_ref()),
|
||||
create_event,
|
||||
room_id,
|
||||
)
|
||||
.boxed()
|
||||
.await
|
||||
.pop()
|
||||
|
@ -65,17 +79,17 @@ pub(super) async fn fetch_prev(
|
|||
}
|
||||
|
||||
if let Some(json) = json_opt {
|
||||
if pdu.origin_server_ts > first_ts_in_room {
|
||||
if pdu.origin_server_ts() > first_ts_in_room {
|
||||
amount = amount.saturating_add(1);
|
||||
for prev_prev in &pdu.prev_events {
|
||||
for prev_prev in pdu.prev_events() {
|
||||
if !graph.contains_key(prev_prev) {
|
||||
todo_outlier_stack.push_back(prev_prev.clone());
|
||||
todo_outlier_stack.push_back(prev_prev.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
graph.insert(
|
||||
prev_event_id.clone(),
|
||||
pdu.prev_events.iter().cloned().collect(),
|
||||
pdu.prev_events().map(ToOwned::to_owned).collect(),
|
||||
);
|
||||
} else {
|
||||
// Time based check failed
|
||||
|
@ -98,8 +112,7 @@ pub(super) async fn fetch_prev(
|
|||
let event_fetch = |event_id| {
|
||||
let origin_server_ts = eventid_info
|
||||
.get(&event_id)
|
||||
.cloned()
|
||||
.map_or_else(|| uint!(0), |info| info.0.origin_server_ts);
|
||||
.map_or_else(|| uint!(0), |info| info.0.origin_server_ts().get());
|
||||
|
||||
// This return value is the key used for sorting events,
|
||||
// events are then sorted by power level, time,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::{HashMap, hash_map};
|
||||
|
||||
use conduwuit::{Err, Error, PduEvent, Result, debug, debug_warn, implement};
|
||||
use conduwuit::{Err, Event, Result, debug, debug_warn, err, implement};
|
||||
use futures::FutureExt;
|
||||
use ruma::{
|
||||
EventId, OwnedEventId, RoomId, ServerName, api::federation::event::get_room_state_ids,
|
||||
|
@ -18,13 +18,16 @@ use crate::rooms::short::ShortStateKey;
|
|||
skip_all,
|
||||
fields(%origin),
|
||||
)]
|
||||
pub(super) async fn fetch_state(
|
||||
pub(super) async fn fetch_state<Pdu>(
|
||||
&self,
|
||||
origin: &ServerName,
|
||||
create_event: &PduEvent,
|
||||
create_event: &Pdu,
|
||||
room_id: &RoomId,
|
||||
event_id: &EventId,
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>> {
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
let res = self
|
||||
.services
|
||||
.sending
|
||||
|
@ -36,27 +39,27 @@ pub(super) async fn fetch_state(
|
|||
.inspect_err(|e| debug_warn!("Fetching state for event failed: {e}"))?;
|
||||
|
||||
debug!("Fetching state events");
|
||||
let state_ids = res.pdu_ids.iter().map(AsRef::as_ref);
|
||||
let state_vec = self
|
||||
.fetch_and_handle_outliers(origin, &res.pdu_ids, create_event, room_id)
|
||||
.fetch_and_handle_outliers(origin, state_ids, create_event, room_id)
|
||||
.boxed()
|
||||
.await;
|
||||
|
||||
let mut state: HashMap<ShortStateKey, OwnedEventId> = HashMap::with_capacity(state_vec.len());
|
||||
for (pdu, _) in state_vec {
|
||||
let state_key = pdu
|
||||
.state_key
|
||||
.clone()
|
||||
.ok_or_else(|| Error::bad_database("Found non-state pdu in state events."))?;
|
||||
.state_key()
|
||||
.ok_or_else(|| err!(Database("Found non-state pdu in state events.")))?;
|
||||
|
||||
let shortstatekey = self
|
||||
.services
|
||||
.short
|
||||
.get_or_create_shortstatekey(&pdu.kind.to_string().into(), &state_key)
|
||||
.get_or_create_shortstatekey(&pdu.kind().to_string().into(), state_key)
|
||||
.await;
|
||||
|
||||
match state.entry(shortstatekey) {
|
||||
| hash_map::Entry::Vacant(v) => {
|
||||
v.insert(pdu.event_id.clone());
|
||||
v.insert(pdu.event_id().to_owned());
|
||||
},
|
||||
| hash_map::Entry::Occupied(_) => {
|
||||
return Err!(Database(
|
||||
|
@ -73,7 +76,7 @@ pub(super) async fn fetch_state(
|
|||
.get_shortstatekey(&StateEventType::RoomCreate, "")
|
||||
.await?;
|
||||
|
||||
if state.get(&create_shortstatekey) != Some(&create_event.event_id) {
|
||||
if state.get(&create_shortstatekey).map(AsRef::as_ref) != Some(create_event.event_id()) {
|
||||
return Err!(Database("Incoming event refers to wrong create event."));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
};
|
||||
|
||||
use conduwuit::{
|
||||
Err, Result, debug, debug::INFO_SPAN_LEVEL, defer, err, implement, utils::stream::IterStream,
|
||||
Err, Event, Result, debug::INFO_SPAN_LEVEL, defer, err, implement, utils::stream::IterStream,
|
||||
warn,
|
||||
};
|
||||
use futures::{
|
||||
|
@ -12,6 +12,7 @@ use futures::{
|
|||
future::{OptionFuture, try_join5},
|
||||
};
|
||||
use ruma::{CanonicalJsonValue, EventId, RoomId, ServerName, UserId, events::StateEventType};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::rooms::timeline::RawPduId;
|
||||
|
||||
|
@ -121,22 +122,16 @@ pub async fn handle_incoming_pdu<'a>(
|
|||
.timeline
|
||||
.first_pdu_in_room(room_id)
|
||||
.await?
|
||||
.origin_server_ts;
|
||||
.origin_server_ts();
|
||||
|
||||
if incoming_pdu.origin_server_ts < first_ts_in_room {
|
||||
if incoming_pdu.origin_server_ts() < first_ts_in_room {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// 9. Fetch any missing prev events doing all checks listed here starting at 1.
|
||||
// These are timeline events
|
||||
let (sorted_prev_events, mut eventid_info) = self
|
||||
.fetch_prev(
|
||||
origin,
|
||||
create_event,
|
||||
room_id,
|
||||
first_ts_in_room,
|
||||
incoming_pdu.prev_events.clone(),
|
||||
)
|
||||
.fetch_prev(origin, create_event, room_id, first_ts_in_room, incoming_pdu.prev_events())
|
||||
.await?;
|
||||
|
||||
debug!(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::{BTreeMap, HashMap, hash_map};
|
||||
|
||||
use conduwuit::{
|
||||
Err, PduEvent, Result, debug, debug_info, err, implement, state_res, trace, warn,
|
||||
Err, Event, PduEvent, Result, debug, debug_info, err, implement, state_res, trace, warn,
|
||||
};
|
||||
use futures::future::ready;
|
||||
use ruma::{
|
||||
|
@ -12,15 +12,18 @@ use super::{check_room_id, get_room_version_id, to_room_version};
|
|||
|
||||
#[implement(super::Service)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) async fn handle_outlier_pdu<'a>(
|
||||
pub(super) async fn handle_outlier_pdu<'a, Pdu>(
|
||||
&self,
|
||||
origin: &'a ServerName,
|
||||
create_event: &'a PduEvent,
|
||||
create_event: &'a Pdu,
|
||||
event_id: &'a EventId,
|
||||
room_id: &'a RoomId,
|
||||
mut value: CanonicalJsonObject,
|
||||
auth_events_known: bool,
|
||||
) -> Result<(PduEvent, BTreeMap<String, CanonicalJsonValue>)> {
|
||||
) -> Result<(PduEvent, BTreeMap<String, CanonicalJsonValue>)>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
// 1. Remove unsigned field
|
||||
value.remove("unsigned");
|
||||
|
||||
|
@ -29,7 +32,7 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
// 2. Check signatures, otherwise drop
|
||||
// 3. check content hash, redact if doesn't match
|
||||
let room_version_id = get_room_version_id(create_event)?;
|
||||
let mut val = match self
|
||||
let mut incoming_pdu = match self
|
||||
.services
|
||||
.server_keys
|
||||
.verify_event(&value, Some(&room_version_id))
|
||||
|
@ -61,13 +64,15 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
|
||||
// Now that we have checked the signature and hashes we can add the eventID and
|
||||
// convert to our PduEvent type
|
||||
val.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned()));
|
||||
let incoming_pdu = serde_json::from_value::<PduEvent>(
|
||||
serde_json::to_value(&val).expect("CanonicalJsonObj is a valid JsonValue"),
|
||||
incoming_pdu
|
||||
.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned()));
|
||||
|
||||
let pdu_event = serde_json::from_value::<PduEvent>(
|
||||
serde_json::to_value(&incoming_pdu).expect("CanonicalJsonObj is a valid JsonValue"),
|
||||
)
|
||||
.map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))?;
|
||||
|
||||
check_room_id(room_id, &incoming_pdu)?;
|
||||
check_room_id(room_id, &pdu_event)?;
|
||||
|
||||
if !auth_events_known {
|
||||
// 4. fetch any missing auth events doing all checks listed here starting at 1.
|
||||
|
@ -78,7 +83,7 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
debug!("Fetching auth events");
|
||||
Box::pin(self.fetch_and_handle_outliers(
|
||||
origin,
|
||||
&incoming_pdu.auth_events,
|
||||
pdu_event.auth_events(),
|
||||
create_event,
|
||||
room_id,
|
||||
))
|
||||
|
@ -89,8 +94,8 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
// auth events
|
||||
debug!("Checking based on auth events");
|
||||
// Build map of auth events
|
||||
let mut auth_events = HashMap::with_capacity(incoming_pdu.auth_events.len());
|
||||
for id in &incoming_pdu.auth_events {
|
||||
let mut auth_events = HashMap::with_capacity(pdu_event.auth_events().count());
|
||||
for id in pdu_event.auth_events() {
|
||||
let Ok(auth_event) = self.services.timeline.get_pdu(id).await else {
|
||||
warn!("Could not find auth event {id}");
|
||||
continue;
|
||||
|
@ -131,7 +136,7 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
|
||||
let auth_check = state_res::event_auth::auth_check(
|
||||
&to_room_version(&room_version_id),
|
||||
&incoming_pdu,
|
||||
&pdu_event,
|
||||
None, // TODO: third party invite
|
||||
state_fetch,
|
||||
)
|
||||
|
@ -147,9 +152,9 @@ pub(super) async fn handle_outlier_pdu<'a>(
|
|||
// 7. Persist the event as an outlier.
|
||||
self.services
|
||||
.outlier
|
||||
.add_pdu_outlier(&incoming_pdu.event_id, &val);
|
||||
.add_pdu_outlier(pdu_event.event_id(), &incoming_pdu);
|
||||
|
||||
trace!("Added pdu as outlier.");
|
||||
|
||||
Ok((incoming_pdu, val))
|
||||
Ok((pdu_event, incoming_pdu))
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::{collections::BTreeMap, time::Instant};
|
||||
|
||||
use conduwuit::{
|
||||
Err, PduEvent, Result, debug, debug::INFO_SPAN_LEVEL, defer, implement,
|
||||
Err, Event, PduEvent, Result, debug::INFO_SPAN_LEVEL, defer, implement,
|
||||
utils::continue_exponential_backoff_secs,
|
||||
};
|
||||
use ruma::{CanonicalJsonValue, EventId, RoomId, ServerName, UInt};
|
||||
use ruma::{CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, RoomId, ServerName};
|
||||
use tracing::debug;
|
||||
|
||||
#[implement(super::Service)]
|
||||
#[allow(clippy::type_complexity)]
|
||||
|
@ -15,16 +16,19 @@ use ruma::{CanonicalJsonValue, EventId, RoomId, ServerName, UInt};
|
|||
skip_all,
|
||||
fields(%prev_id),
|
||||
)]
|
||||
pub(super) async fn handle_prev_pdu<'a>(
|
||||
pub(super) async fn handle_prev_pdu<'a, Pdu>(
|
||||
&self,
|
||||
origin: &'a ServerName,
|
||||
event_id: &'a EventId,
|
||||
room_id: &'a RoomId,
|
||||
eventid_info: Option<(PduEvent, BTreeMap<String, CanonicalJsonValue>)>,
|
||||
create_event: &'a PduEvent,
|
||||
first_ts_in_room: UInt,
|
||||
create_event: &'a Pdu,
|
||||
first_ts_in_room: MilliSecondsSinceUnixEpoch,
|
||||
prev_id: &'a EventId,
|
||||
) -> Result {
|
||||
) -> Result
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
// Check for disabled again because it might have changed
|
||||
if self.services.metadata.is_disabled(room_id).await {
|
||||
return Err!(Request(Forbidden(debug_warn!(
|
||||
|
@ -59,7 +63,7 @@ pub(super) async fn handle_prev_pdu<'a>(
|
|||
};
|
||||
|
||||
// Skip old events
|
||||
if pdu.origin_server_ts < first_ts_in_room {
|
||||
if pdu.origin_server_ts() < first_ts_in_room {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::{
|
|||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::{Err, PduEvent, Result, RoomVersion, Server, utils::MutexMap};
|
||||
use conduwuit::{Err, Event, PduEvent, Result, RoomVersion, Server, utils::MutexMap};
|
||||
use ruma::{
|
||||
OwnedEventId, OwnedRoomId, RoomId, RoomVersionId,
|
||||
events::room::create::RoomCreateEventContent,
|
||||
|
@ -104,11 +104,11 @@ impl Service {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_room_id(room_id: &RoomId, pdu: &PduEvent) -> Result {
|
||||
if pdu.room_id != room_id {
|
||||
fn check_room_id<Pdu: Event>(room_id: &RoomId, pdu: &Pdu) -> Result {
|
||||
if pdu.room_id() != room_id {
|
||||
return Err!(Request(InvalidParam(error!(
|
||||
pdu_event_id = ?pdu.event_id,
|
||||
pdu_room_id = ?pdu.room_id,
|
||||
pdu_event_id = ?pdu.event_id(),
|
||||
pdu_room_id = ?pdu.room_id(),
|
||||
?room_id,
|
||||
"Found event from room in room",
|
||||
))));
|
||||
|
@ -117,7 +117,7 @@ fn check_room_id(room_id: &RoomId, pdu: &PduEvent) -> Result {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn get_room_version_id(create_event: &PduEvent) -> Result<RoomVersionId> {
|
||||
fn get_room_version_id<Pdu: Event>(create_event: &Pdu) -> Result<RoomVersionId> {
|
||||
let content: RoomCreateEventContent = create_event.get_content()?;
|
||||
let room_version = content.room_version;
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use conduwuit::{Result, err, implement, pdu::gen_event_id_canonical_json, result::FlatOk};
|
||||
use conduwuit::{
|
||||
Result, err, implement, matrix::event::gen_event_id_canonical_json, result::FlatOk,
|
||||
};
|
||||
use ruma::{CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId};
|
||||
use serde_json::value::RawValue as RawJsonValue;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
|
||||
use conduwuit::{
|
||||
Result, debug, err, implement,
|
||||
matrix::{PduEvent, StateMap},
|
||||
matrix::{Event, StateMap},
|
||||
trace,
|
||||
utils::stream::{BroadbandExt, IterStream, ReadyExt, TryBroadbandExt, TryWidebandExt},
|
||||
};
|
||||
|
@ -19,11 +19,18 @@ use crate::rooms::short::ShortStateHash;
|
|||
#[implement(super::Service)]
|
||||
// request and build the state from a known point and resolve if > 1 prev_event
|
||||
#[tracing::instrument(name = "state", level = "debug", skip_all)]
|
||||
pub(super) async fn state_at_incoming_degree_one(
|
||||
pub(super) async fn state_at_incoming_degree_one<Pdu>(
|
||||
&self,
|
||||
incoming_pdu: &PduEvent,
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>> {
|
||||
let prev_event = &incoming_pdu.prev_events[0];
|
||||
incoming_pdu: &Pdu,
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
let prev_event = incoming_pdu
|
||||
.prev_events()
|
||||
.next()
|
||||
.expect("at least one prev_event");
|
||||
|
||||
let Ok(prev_event_sstatehash) = self
|
||||
.services
|
||||
.state_accessor
|
||||
|
@ -55,7 +62,7 @@ pub(super) async fn state_at_incoming_degree_one(
|
|||
.get_or_create_shortstatekey(&prev_pdu.kind.to_string().into(), state_key)
|
||||
.await;
|
||||
|
||||
state.insert(shortstatekey, prev_event.clone());
|
||||
state.insert(shortstatekey, prev_event.to_owned());
|
||||
// Now it's the state after the pdu
|
||||
}
|
||||
|
||||
|
@ -66,16 +73,18 @@ pub(super) async fn state_at_incoming_degree_one(
|
|||
|
||||
#[implement(super::Service)]
|
||||
#[tracing::instrument(name = "state", level = "debug", skip_all)]
|
||||
pub(super) async fn state_at_incoming_resolved(
|
||||
pub(super) async fn state_at_incoming_resolved<Pdu>(
|
||||
&self,
|
||||
incoming_pdu: &PduEvent,
|
||||
incoming_pdu: &Pdu,
|
||||
room_id: &RoomId,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>> {
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
trace!("Calculating extremity statehashes...");
|
||||
let Ok(extremity_sstatehashes) = incoming_pdu
|
||||
.prev_events
|
||||
.iter()
|
||||
.prev_events()
|
||||
.try_stream()
|
||||
.broad_and_then(|prev_eventid| {
|
||||
self.services
|
||||
|
@ -133,12 +142,15 @@ pub(super) async fn state_at_incoming_resolved(
|
|||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
async fn state_at_incoming_fork(
|
||||
async fn state_at_incoming_fork<Pdu>(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
sstatehash: ShortStateHash,
|
||||
prev_event: PduEvent,
|
||||
) -> Result<(StateMap<OwnedEventId>, HashSet<OwnedEventId>)> {
|
||||
prev_event: Pdu,
|
||||
) -> Result<(StateMap<OwnedEventId>, HashSet<OwnedEventId>)>
|
||||
where
|
||||
Pdu: Event,
|
||||
{
|
||||
let mut leaf_state: HashMap<_, _> = self
|
||||
.services
|
||||
.state_accessor
|
||||
|
@ -146,15 +158,15 @@ async fn state_at_incoming_fork(
|
|||
.collect()
|
||||
.await;
|
||||
|
||||
if let Some(state_key) = &prev_event.state_key {
|
||||
if let Some(state_key) = prev_event.state_key() {
|
||||
let shortstatekey = self
|
||||
.services
|
||||
.short
|
||||
.get_or_create_shortstatekey(&prev_event.kind.to_string().into(), state_key)
|
||||
.get_or_create_shortstatekey(&prev_event.kind().to_string().into(), state_key)
|
||||
.await;
|
||||
|
||||
let event_id = &prev_event.event_id;
|
||||
leaf_state.insert(shortstatekey, event_id.clone());
|
||||
let event_id = prev_event.event_id();
|
||||
leaf_state.insert(shortstatekey, event_id.to_owned());
|
||||
// Now it's the state after the pdu
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant};
|
||||
|
||||
use conduwuit::{
|
||||
Err, Result, debug, debug_info, err, implement,
|
||||
Err, Result, debug, debug_info, err, implement, is_equal_to,
|
||||
matrix::{Event, EventTypeExt, PduEvent, StateKey, state_res},
|
||||
trace,
|
||||
utils::stream::{BroadbandExt, ReadyExt},
|
||||
|
@ -17,19 +17,22 @@ use crate::rooms::{
|
|||
};
|
||||
|
||||
#[implement(super::Service)]
|
||||
pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
||||
pub(super) async fn upgrade_outlier_to_timeline_pdu<Pdu>(
|
||||
&self,
|
||||
incoming_pdu: PduEvent,
|
||||
val: BTreeMap<String, CanonicalJsonValue>,
|
||||
create_event: &PduEvent,
|
||||
create_event: &Pdu,
|
||||
origin: &ServerName,
|
||||
room_id: &RoomId,
|
||||
) -> Result<Option<RawPduId>> {
|
||||
) -> Result<Option<RawPduId>>
|
||||
where
|
||||
Pdu: Event + Send + Sync,
|
||||
{
|
||||
// Skip the PDU if we already have it as a timeline event
|
||||
if let Ok(pduid) = self
|
||||
.services
|
||||
.timeline
|
||||
.get_pdu_id(&incoming_pdu.event_id)
|
||||
.get_pdu_id(incoming_pdu.event_id())
|
||||
.await
|
||||
{
|
||||
return Ok(Some(pduid));
|
||||
|
@ -38,7 +41,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
if self
|
||||
.services
|
||||
.pdu_metadata
|
||||
.is_event_soft_failed(&incoming_pdu.event_id)
|
||||
.is_event_soft_failed(incoming_pdu.event_id())
|
||||
.await
|
||||
{
|
||||
return Err!(Request(InvalidParam("Event has been soft failed")));
|
||||
|
@ -53,7 +56,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
// These are not timeline events.
|
||||
|
||||
debug!("Resolving state at event");
|
||||
let mut state_at_incoming_event = if incoming_pdu.prev_events.len() == 1 {
|
||||
let mut state_at_incoming_event = if incoming_pdu.prev_events().count() == 1 {
|
||||
self.state_at_incoming_degree_one(&incoming_pdu).await?
|
||||
} else {
|
||||
self.state_at_incoming_resolved(&incoming_pdu, room_id, &room_version_id)
|
||||
|
@ -62,12 +65,13 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
|
||||
if state_at_incoming_event.is_none() {
|
||||
state_at_incoming_event = self
|
||||
.fetch_state(origin, create_event, room_id, &incoming_pdu.event_id)
|
||||
.fetch_state(origin, create_event, room_id, incoming_pdu.event_id())
|
||||
.await?;
|
||||
}
|
||||
|
||||
let state_at_incoming_event =
|
||||
state_at_incoming_event.expect("we always set this to some above");
|
||||
|
||||
let room_version = to_room_version(&room_version_id);
|
||||
|
||||
debug!("Performing auth check");
|
||||
|
@ -99,10 +103,10 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
.state
|
||||
.get_auth_events(
|
||||
room_id,
|
||||
&incoming_pdu.kind,
|
||||
&incoming_pdu.sender,
|
||||
incoming_pdu.state_key.as_deref(),
|
||||
&incoming_pdu.content,
|
||||
incoming_pdu.kind(),
|
||||
incoming_pdu.sender(),
|
||||
incoming_pdu.state_key(),
|
||||
incoming_pdu.content(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -129,7 +133,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
!self
|
||||
.services
|
||||
.state_accessor
|
||||
.user_can_redact(&redact_id, &incoming_pdu.sender, &incoming_pdu.room_id, true)
|
||||
.user_can_redact(&redact_id, incoming_pdu.sender(), incoming_pdu.room_id(), true)
|
||||
.await?,
|
||||
};
|
||||
|
||||
|
@ -149,7 +153,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
.map(ToOwned::to_owned)
|
||||
.ready_filter(|event_id| {
|
||||
// Remove any that are referenced by this incoming event's prev_events
|
||||
!incoming_pdu.prev_events.contains(event_id)
|
||||
!incoming_pdu.prev_events().any(is_equal_to!(event_id))
|
||||
})
|
||||
.broad_filter_map(|event_id| async move {
|
||||
// Only keep those extremities were not referenced yet
|
||||
|
@ -166,7 +170,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
debug!(
|
||||
"Retained {} extremities checked against {} prev_events",
|
||||
extremities.len(),
|
||||
incoming_pdu.prev_events.len()
|
||||
incoming_pdu.prev_events().count()
|
||||
);
|
||||
|
||||
let state_ids_compressed: Arc<CompressedState> = self
|
||||
|
@ -181,20 +185,20 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
.map(Arc::new)
|
||||
.await;
|
||||
|
||||
if incoming_pdu.state_key.is_some() {
|
||||
if incoming_pdu.state_key().is_some() {
|
||||
debug!("Event is a state-event. Deriving new room state");
|
||||
|
||||
// We also add state after incoming event to the fork states
|
||||
let mut state_after = state_at_incoming_event.clone();
|
||||
if let Some(state_key) = &incoming_pdu.state_key {
|
||||
if let Some(state_key) = incoming_pdu.state_key() {
|
||||
let shortstatekey = self
|
||||
.services
|
||||
.short
|
||||
.get_or_create_shortstatekey(&incoming_pdu.kind.to_string().into(), state_key)
|
||||
.get_or_create_shortstatekey(&incoming_pdu.kind().to_string().into(), state_key)
|
||||
.await;
|
||||
|
||||
let event_id = &incoming_pdu.event_id;
|
||||
state_after.insert(shortstatekey, event_id.clone());
|
||||
let event_id = incoming_pdu.event_id();
|
||||
state_after.insert(shortstatekey, event_id.to_owned());
|
||||
}
|
||||
|
||||
let new_room_state = self
|
||||
|
@ -236,9 +240,9 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
// Soft fail, we keep the event as an outlier but don't add it to the timeline
|
||||
self.services
|
||||
.pdu_metadata
|
||||
.mark_event_soft_failed(&incoming_pdu.event_id);
|
||||
.mark_event_soft_failed(incoming_pdu.event_id());
|
||||
|
||||
warn!("Event was soft failed: {incoming_pdu:?}");
|
||||
warn!("Event was soft failed: {:?}", incoming_pdu.event_id());
|
||||
return Err!(Request(InvalidParam("Event has been soft failed")));
|
||||
}
|
||||
|
||||
|
@ -249,7 +253,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
let extremities = extremities
|
||||
.iter()
|
||||
.map(Borrow::borrow)
|
||||
.chain(once(incoming_pdu.event_id.borrow()));
|
||||
.chain(once(incoming_pdu.event_id()));
|
||||
|
||||
let pdu_id = self
|
||||
.services
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue