Support v1/v2 prev_events/auth_events outgoing federation format. (#12)

Support v1/v2 prev_events/auth_events when handling outlier pdu. (#12)

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-08-31 01:37:04 +00:00
parent eec6e45358
commit 6a583a359e
4 changed files with 87 additions and 21 deletions

20
Cargo.lock generated
View File

@@ -3406,7 +3406,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.12.6"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"assign",
"js_int",
@@ -3425,7 +3425,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.12.2"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"js_int",
"ruma-common",
@@ -3437,7 +3437,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.20.4"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"as_variant",
"assign",
@@ -3460,7 +3460,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.15.4"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"as_variant",
"base64",
@@ -3493,7 +3493,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.30.5"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"as_variant",
"indexmap",
@@ -3519,7 +3519,7 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.11.2"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"bytes",
"headers",
@@ -3541,7 +3541,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.10.1"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"js_int",
"thiserror 2.0.14",
@@ -3550,7 +3550,7 @@ dependencies = [
[[package]]
name = "ruma-macros"
version = "0.15.2"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"cfg-if",
"proc-macro-crate",
@@ -3565,7 +3565,7 @@ dependencies = [
[[package]]
name = "ruma-push-gateway-api"
version = "0.11.0"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"js_int",
"ruma-common",
@@ -3577,7 +3577,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.17.1"
source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a"
dependencies = [
"base64",
"ed25519-dalek",

View File

@@ -317,7 +317,7 @@ default-features = false
[workspace.dependencies.ruma]
git = "https://github.com/matrix-construct/ruma"
rev = "8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6"
rev = "93f28d777073e60687e8013e59d8d16b5adbdf9a"
features = [
"__compat",
"appservice-api-c",

View File

@@ -1,6 +1,12 @@
use ruma::{CanonicalJsonObject, CanonicalJsonValue, RoomVersionId};
use ruma::{
CanonicalJsonObject, CanonicalJsonValue, EventId, RoomVersionId,
room_version_rules::{EventsReferenceFormatVersion, RoomVersionRules},
};
use crate::{is_equal_to, matrix::room_version};
use crate::{
Result, err, extract_variant, is_equal_to,
matrix::{PduEvent, room_version},
};
pub fn into_outgoing_federation(
mut pdu_json: CanonicalJsonObject,
@@ -35,5 +41,67 @@ pub fn into_outgoing_federation(
}
}
if matches!(room_rules.events_reference_format, EventsReferenceFormatVersion::V1) {
if let Some(value) = pdu_json.get_mut("auth_events") {
mutate_outgoing_reference_format(value);
}
if let Some(value) = pdu_json.get_mut("prev_events") {
mutate_outgoing_reference_format(value);
}
}
pdu_json
}
fn mutate_outgoing_reference_format(value: &mut CanonicalJsonValue) {
value
.as_array_mut()
.into_iter()
.flatten()
.for_each(|value| {
if let Some(event_id) = value.as_str().map(ToOwned::to_owned) {
*value = CanonicalJsonValue::Array(vec![
CanonicalJsonValue::String(event_id),
CanonicalJsonValue::Object([(String::new(), "".into())].into()),
]);
}
});
}
pub fn from_incoming_federation(
event_id: &EventId,
pdu_json: &mut CanonicalJsonObject,
room_rules: &RoomVersionRules,
) -> Result<PduEvent> {
if matches!(room_rules.events_reference_format, EventsReferenceFormatVersion::V1) {
if let Some(value) = pdu_json.get_mut("auth_events") {
mutate_incoming_reference_format(value);
}
if let Some(value) = pdu_json.get_mut("prev_events") {
mutate_incoming_reference_format(value);
}
}
pdu_json.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.into()));
serde_json::from_value::<PduEvent>(serde_json::to_value(&pdu_json)?)
.map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))
}
fn mutate_incoming_reference_format(value: &mut CanonicalJsonValue) {
value
.as_array_mut()
.into_iter()
.flat_map(|vec| vec.iter_mut())
.for_each(|value| {
let event_id = value
.as_array()
.into_iter()
.find_map(|vec| vec.first())
.and_then(|val| extract_variant!(val, CanonicalJsonValue::String))
.cloned()
.unwrap_or_default();
*value = CanonicalJsonValue::String(event_id);
});
}

View File

@@ -1,11 +1,11 @@
use futures::{StreamExt, TryFutureExt};
use ruma::{
CanonicalJsonObject, CanonicalJsonValue, EventId, RoomId, RoomVersionId, ServerName,
events::TimelineEventType,
CanonicalJsonObject, EventId, RoomId, RoomVersionId, ServerName, events::TimelineEventType,
};
use tuwunel_core::{
Err, Result, debug, debug_info, err, implement,
matrix::{Event, PduEvent, event::TypeExt, room_version},
pdu::format::from_incoming_federation,
ref_at, state_res, trace,
utils::{future::TryExtExt, stream::IterStream},
warn,
@@ -66,12 +66,11 @@ pub(super) async fn handle_outlier_pdu(
},
};
// Now that we have checked the signature and hashes we can add the eventID and
// convert to our PduEvent type
pdu_json.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.to_string()));
let room_rules = room_version::rules(room_version)?;
let event = serde_json::from_value::<PduEvent>(serde_json::to_value(&pdu_json)?)
.map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))?;
// Now that we have checked the signature and hashes we can make mutations and
// convert to our PduEvent type.
let event = from_incoming_federation(event_id, &mut pdu_json, &room_rules)?;
check_room_id(room_id, &event)?;
@@ -89,7 +88,6 @@ pub(super) async fn handle_outlier_pdu(
// auth events
debug!("Checking based on auth events");
let room_rules = room_version::rules(room_version)?;
let is_hydra = !room_rules
.event_format
.allow_room_create_in_auth_events;