mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
fix(1163): Resolve algorithm misinterpretations
This commit is contained in:
@@ -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" );
|
||||||
|
|||||||
Reference in New Issue
Block a user