pub fn resolve<E: Event>(
        room_id: &RoomId,
        room_version: &RoomVersionId,
        state_sets: &[StateMap<EventId>],
        auth_events: Vec<Vec<EventId>>,
        event_map: &mut EventMap<Arc<E>>,
    ) -> Result<StateMap<EventId>> {
        info!("State resolution starting");

        // Split non-conflicting and conflicting state
        let (clean, conflicting) = StateResolution::separate(state_sets);

        info!("non conflicting {:?}", clean.len());

        if conflicting.is_empty() {
            info!("no conflicting state found");
            return Ok(clean);
        }

        info!("{} conflicting events", conflicting.len());

        // The set of auth events that are not common across server forks
        let mut auth_diff = StateResolution::get_auth_chain_diff(room_id, &auth_events)?;

        debug!("auth diff size {:?}", auth_diff);

        // Add the auth_diff to conflicting now we have a full set of conflicting events
        auth_diff.extend(conflicting.values().cloned().flatten());

        // `all_conflicted` contains unique items
        // synapse says `full_set = {eid for eid in full_conflicted_set if eid in event_map}`
        //
        // Don't honor events we cannot "verify"
        // TODO: BTreeSet::retain() when stable 1.53
        let all_conflicted =
            auth_diff.into_iter().filter(|id| event_map.contains_key(id)).collect::<BTreeSet<_>>();

        info!("full conflicted set is {} events", all_conflicted.len());

        // We used to check that all events are events from the correct room
        // this is now a check the caller of `resolve` must make.

        // Get only the control events with a state_key: "" or ban/kick event (sender != state_key)
        let control_events = all_conflicted
            .iter()
            .filter(|id| is_power_event_id(id, event_map))
            .cloned()
            .collect::<Vec<_>>();

        // Sort the control events based on power_level/clock/event_id and outgoing/incoming edges
        let sorted_control_levels = StateResolution::reverse_topological_power_sort(
            room_id,
            &control_events,
            event_map,
            &all_conflicted,
        );

        debug!("SRTD {:?}", sorted_control_levels);

        let room_version = RoomVersion::new(room_version)?;
        // Sequentially auth check each control event.
        let resolved_control = StateResolution::iterative_auth_check(
            room_id,
            &room_version,
            &sorted_control_levels,
            &clean,
            event_map,
        )?;

        debug!("AUTHED {:?}", resolved_control.iter().collect::<Vec<_>>());

        // At this point the control_events have been resolved we now have to
        // sort the remaining events using the mainline of the resolved power level.
        let deduped_power_ev = sorted_control_levels.into_iter().collect::<BTreeSet<_>>();

        // This removes the control events that passed auth and more importantly those that failed
        // auth
        let events_to_resolve = all_conflicted
            .iter()
            .filter(|id| !deduped_power_ev.contains(id))
            .cloned()
            .collect::<Vec<_>>();

        debug!("LEFT {:?}", events_to_resolve.iter().collect::<Vec<_>>());

        // This "epochs" power level event
        let power_event = resolved_control.get(&(EventType::RoomPowerLevels, "".into()));

        debug!("PL {:?}", power_event);

        let sorted_left_events =
            StateResolution::mainline_sort(room_id, &events_to_resolve, power_event, event_map);

        debug!("SORTED LEFT {:?}", sorted_left_events.iter().collect::<Vec<_>>());

        let mut resolved_state = StateResolution::iterative_auth_check(
            room_id,
            &room_version,
            &sorted_left_events,
            &resolved_control, // The control events are added to the final resolved state
            event_map,
        )?;

        // Add unconflicted state to the resolved state
        // We priorities the unconflicting state
        resolved_state.extend(clean);
        Ok(resolved_state)
    }
/// Resolve sets of state events as they come in. Internally `StateResolution` builds a graph
/// and an auth chain to allow for state conflict resolution.
///
/// ## Arguments
///
/// * `state_sets` - The incoming state to resolve. Each `StateMap` represents a possible fork
/// in the state of a room.
///
/// * `auth_events` - The full recursive set of `auth_events` for each event in the
///   `state_sets`.
///
/// * `event_map` - The `EventMap` acts as a local cache of state, any event that is not found
/// in the `event_map` will cause an unrecoverable `Error` in `resolve`.
Resolve sets of state events as they come in. Internally `StateResolution` builds a graph
and an auth chain to allow for state conflict resolution.
Resolve sets of state events as they come in . Internally ` StateResolution ` builds a graph and an auth chain to allow for state conflict resolution .
pub fn resolve<E: Event>(
        room_id: &RoomId,
        room_version: &RoomVersionId,
        state_sets: &[StateMap<EventId>],
        auth_events: Vec<Vec<EventId>>,
        event_map: &mut EventMap<Arc<E>>,
    ) -> Result<StateMap<EventId>> {
        info!("State resolution starting");
        // Split non-conflicting and conflicting state
        let (clean, conflicting) = StateResolution::separate(state_sets);
        info!("non conflicting {:?}", clean.len());
        if conflicting.is_empty() {
            info!("no conflicting state found");
            return Ok(clean);
        }
        info!("{} conflicting events", conflicting.len());
        // The set of auth events that are not common across server forks
        let mut auth_diff = StateResolution::get_auth_chain_diff(room_id, &auth_events)?;
        debug!("auth diff size {:?}", auth_diff);
        // Add the auth_diff to conflicting now we have a full set of conflicting events
        auth_diff.extend(conflicting.values().cloned().flatten());
        // `all_conflicted` contains unique items
        // synapse says `full_set = {eid for eid in full_conflicted_set if eid in event_map}`
        //
        // Don't honor events we cannot "verify"
        // TODO: BTreeSet::retain() when stable 1.53
        let all_conflicted =
            auth_diff.into_iter().filter(|id| event_map.contains_key(id)).collect::<BTreeSet<_>>();
        info!("full conflicted set is {} events", all_conflicted.len());
        // We used to check that all events are events from the correct room
        // this is now a check the caller of `resolve` must make.
        // Get only the control events with a state_key: "" or ban/kick event (sender != state_key)
        let control_events = all_conflicted
            .iter()
            .filter(|id| is_power_event_id(id, event_map))
            .cloned()
            .collect::<Vec<_>>();
        // Sort the control events based on power_level/clock/event_id and outgoing/incoming edges
        let sorted_control_levels = StateResolution::reverse_topological_power_sort(
            room_id,
            &control_events,
            event_map,
            &all_conflicted,
        );
        debug!("SRTD {:?}", sorted_control_levels);
        let room_version = RoomVersion::new(room_version)?;
        // Sequentially auth check each control event.
        let resolved_control = StateResolution::iterative_auth_check(
            room_id,
            &room_version,
            &sorted_control_levels,
            &clean,
            event_map,
        )?;
        debug!("AUTHED {:?}", resolved_control.iter().collect::<Vec<_>>());
        // At this point the control_events have been resolved we now have to
        // sort the remaining events using the mainline of the resolved power level.
        let deduped_power_ev = sorted_control_levels.into_iter().collect::<BTreeSet<_>>();
        // This removes the control events that passed auth and more importantly those that failed
        // auth
        let events_to_resolve = all_conflicted
            .iter()
            .filter(|id| !deduped_power_ev.contains(id))
            .cloned()
            .collect::<Vec<_>>();
        debug!("LEFT {:?}", events_to_resolve.iter().collect::<Vec<_>>());
        // This "epochs" power level event
        let power_event = resolved_control.get(&(EventType::RoomPowerLevels, "".into()));
        debug!("PL {:?}", power_event);
        let sorted_left_events =
            StateResolution::mainline_sort(room_id, &events_to_resolve, power_event, event_map);
        debug!("SORTED LEFT {:?}", sorted_left_events.iter().collect::<Vec<_>>());
        let mut resolved_state = StateResolution::iterative_auth_check(
            room_id,
            &room_version,
            &sorted_left_events,
            &resolved_control, // The control events are added to the final resolved state
            event_map,
        )?;
        // Add unconflicted state to the resolved state
        // We priorities the unconflicting state
        resolved_state.extend(clean);
        Ok(resolved_state)
    }
pub fn resolve < E : Event > ( room_id : & RoomId , room_version : & RoomVersionId , state_sets : & [ StateMap < EventId > ] , auth_events : Vec < Vec < EventId > > , event_map : & mut EventMap < Arc < E > > , ) -> Result < StateMap < EventId > > { info ! ( " " ) ; // Split non-conflicting and conflicting state let ( clean , conflicting ) = StateResolution :: separate ( state_sets ) ; info ! ( " " clean len ( ) ) ; if conflicting . is_empty ( ) { info ! ( " " ) ; return Ok ( clean ) ; } info ! ( " " conflicting len ( ) ) ; // The set of auth events that are not common across server forks let mut auth_diff = StateResolution :: get_auth_chain_diff ( room_id , & auth_events ) ? ; debug ! ( " " auth_diff ) ; // Add the auth_diff to conflicting now we have a full set of conflicting events auth_diff . extend ( conflicting . values ( ) . cloned ( ) . flatten ( ) ) ; // `all_conflicted` contains unique items // synapse says `full_set = {eid for eid in full_conflicted_set if eid in event_map}` // // Don't honor events we cannot "verify" // TODO: BTreeSet::retain() when stable 1.53 let all_conflicted = auth_diff . into_iter ( ) . filter ( | id | event_map . contains_key ( id ) ) . collect :: < BTreeSet < _ > > ( ) ; info ! ( " " all_conflicted len ( ) ) ; // We used to check that all events are events from the correct room // this is now a check the caller of `resolve` must make. // Get only the control events with a state_key: "" or ban/kick event (sender != state_key) let control_events = all_conflicted . iter ( ) . filter ( | id | is_power_event_id ( id , event_map ) ) . cloned ( ) . collect :: < Vec < _ > > ( ) ; // Sort the control events based on power_level/clock/event_id and outgoing/incoming edges let sorted_control_levels = StateResolution :: reverse_topological_power_sort ( room_id , & control_events , event_map , & all_conflicted , ) ; debug ! ( " " sorted_control_levels ) ; let room_version = RoomVersion :: new ( room_version ) ? ; // Sequentially auth check each control event. let resolved_control = StateResolution :: iterative_auth_check ( room_id , & room_version , & sorted_control_levels , & clean , event_map , ) ? ; debug ! ( " " resolved_control iter ( ) collect Vec ( ) ) ; // At this point the control_events have been resolved we now have to // sort the remaining events using the mainline of the resolved power level. let deduped_power_ev = sorted_control_levels . into_iter ( ) . collect :: < BTreeSet < _ > > ( ) ; // This removes the control events that passed auth and more importantly those that failed // auth let events_to_resolve = all_conflicted . iter ( ) . filter ( | id | ! deduped_power_ev . contains ( id ) ) . cloned ( ) . collect :: < Vec < _ > > ( ) ; debug ! ( " " events_to_resolve iter ( ) collect Vec ( ) ) ; // This "epochs" power level event let power_event = resolved_control . get ( & ( EventType :: RoomPowerLevels , " " . into ( ) ) ) ; debug ! ( " " power_event ) ; let sorted_left_events = StateResolution :: mainline_sort ( room_id , & events_to_resolve , power_event , event_map ) ; debug ! ( " " sorted_left_events iter ( ) collect Vec ( ) ) ; let mut resolved_state = StateResolution :: iterative_auth_check ( room_id , & room_version , & sorted_left_events , & resolved_control , // The control events are added to the final resolved state event_map , ) ? ; // Add unconflicted state to the resolved state // We priorities the unconflicting state resolved_state . extend ( clean ) ; Ok ( resolved_state ) }
Resolve sets of state events as they come in.
Resolve sets of state events as they come in .
room_id
&RoomId
room_version
&RoomVersionId
state_sets
&[StateMap<EventId>]
auth_events
Vec<Vec<EventId>>
event_map
&mut EventMap<Arc<E>>