fix(1163): Resolve algorithm misinterpretations

This commit is contained in:
timedout
2025-11-13 03:33:47 +00:00
parent f22f35d27b
commit 9375e81974
+19 -19
View File
@@ -101,40 +101,40 @@ where
debug!(version = ?stateres_version, "State resolution starting"); debug!(version = ?stateres_version, "State resolution starting");
// Split non-conflicting and conflicting state // Split non-conflicting and conflicting state
let (clean, conflicting) = separate(state_sets.into_iter()); let (unconflicted, conflicting) = separate(state_sets.into_iter());
debug!(count = clean.len(), "non-conflicting events"); debug!(count = unconflicted.len(), "non-conflicting events");
trace!(map = ?clean, "non-conflicting events"); trace!(map = ?unconflicted, "non-conflicting events");
if conflicting.is_empty() { if conflicting.is_empty() {
debug!("no conflicting state found"); debug!("no conflicting state found");
return Ok(clean); return Ok(unconflicted);
} }
debug!(count = conflicting.len(), "conflicting events"); debug!(count = conflicting.len(), "conflicting events");
trace!(map = ?conflicting, "conflicting events"); trace!(map = ?conflicting, "conflicting events");
let conflicted_state_subgraph: HashSet<_> = match stateres_version { let (conflicted_state_subgraph, initial_state) =
| StateResolutionVersion::V2_1 => if stateres_version == StateResolutionVersion::V2_1 {
calculate_conflicted_subgraph(&conflicting, event_fetch) let csg = calculate_conflicted_subgraph(&conflicting, event_fetch)
.await .await
.ok_or_else(|| { .ok_or_else(|| {
Error::InvalidPdu("Failed to calculate conflicted subgraph".to_owned()) Error::InvalidPdu("Failed to calculate conflicted subgraph".to_owned())
})?, })?;
| _ => HashSet::new(), debug!(count = csg.len(), "conflicted subgraph");
trace!(set = ?csg, "conflicted subgraph");
(csg, HashMap::new())
} else {
(HashSet::new(), unconflicted.clone())
}; };
debug!(count = conflicted_state_subgraph.len(), "conflicted subgraph");
trace!(set = ?conflicted_state_subgraph, "conflicted subgraph");
let conflicting_values = conflicting.into_values().flatten().stream();
// `all_conflicted` contains unique items // `all_conflicted` contains unique items
// synapse says `full_set = {eid for eid in full_conflicted_set if eid in // synapse says `full_set = {eid for eid in full_conflicted_set if eid in
// event_map}` // event_map}`
// Hydra: Also consider the conflicted state subgraph // Hydra: Also consider the conflicted state subgraph
let all_conflicted: HashSet<_> = get_auth_chain_diff(auth_chain_sets) let all_conflicted: HashSet<_> = get_auth_chain_diff(auth_chain_sets)
.chain(conflicting_values) .chain(conflicting.into_values().flatten().stream())
.chain(conflicted_state_subgraph.into_iter().stream())
.broad_filter_map(async |id| event_exists(id.clone()).await.then_some(id)) .broad_filter_map(async |id| event_exists(id.clone()).await.then_some(id))
.chain(conflicted_state_subgraph.into_iter().stream())
.collect() .collect()
.await; .await;
@@ -171,7 +171,7 @@ where
&room_version, &room_version,
&stateres_version, &stateres_version,
sorted_control_levels.iter().stream().map(AsRef::as_ref), sorted_control_levels.iter().stream().map(AsRef::as_ref),
clean.clone(), initial_state,
&event_fetch, &event_fetch,
) )
.await?; .await?;
@@ -201,7 +201,7 @@ where
let power_levels_ty_sk = (StateEventType::RoomPowerLevels, StateKey::new()); let power_levels_ty_sk = (StateEventType::RoomPowerLevels, StateKey::new());
let power_event = resolved_control.get(&power_levels_ty_sk); let power_event = resolved_control.get(&power_levels_ty_sk);
debug!(event_id = ?power_event, "power event"); trace!(event_id = ?power_event, "power event");
let sorted_left_events = let sorted_left_events =
mainline_sort(&events_to_resolve, power_event.cloned(), &event_fetch).await?; mainline_sort(&events_to_resolve, power_event.cloned(), &event_fetch).await?;
@@ -212,13 +212,13 @@ where
&room_version, &room_version,
&stateres_version, &stateres_version,
sorted_left_events.iter().stream().map(AsRef::as_ref), sorted_left_events.iter().stream().map(AsRef::as_ref),
resolved_control.clone(), // The control events are added to the final resolved state resolved_control, // The control events are added to the final resolved state
&event_fetch, &event_fetch,
) )
.await?; .await?;
// Ensure unconflicting state is in the final state // Ensure unconflicting state is in the final state
resolved_state.extend(clean); resolved_state.extend(unconflicted);
debug!("state resolution finished"); debug!("state resolution finished");
trace!( map = ?resolved_state, "final resolved state" ); trace!( map = ?resolved_state, "final resolved state" );