state-res: Use unique over dedup, remove Vec -> BTreeSet conversions

This commit is contained in:
Devin Ragotzy 2021-05-14 18:53:35 -04:00 committed by Jonas Platte
parent 282ffd9c6d
commit ce6fd1e65e
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
8 changed files with 77 additions and 107 deletions

View File

@ -16,7 +16,7 @@ use std::{
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{criterion_group, criterion_main, Criterion};
use event::StateEvent; use event::StateEvent;
use js_int::uint; use js_int::uint;
use maplit::btreemap; use maplit::{btreemap, btreeset};
use ruma_common::MilliSecondsSinceUnixEpoch; use ruma_common::MilliSecondsSinceUnixEpoch;
use ruma_events::{ use ruma_events::{
pdu::{EventHash, Pdu, RoomV3Pdu}, pdu::{EventHash, Pdu, RoomV3Pdu},
@ -35,11 +35,11 @@ static SERVER_TIMESTAMP: AtomicU64 = AtomicU64::new(0);
fn lexico_topo_sort(c: &mut Criterion) { fn lexico_topo_sort(c: &mut Criterion) {
c.bench_function("lexicographical topological sort", |b| { c.bench_function("lexicographical topological sort", |b| {
let graph = btreemap! { let graph = btreemap! {
event_id("l") => vec![event_id("o")], event_id("l") => btreeset![event_id("o")],
event_id("m") => vec![event_id("n"), event_id("o")], event_id("m") => btreeset![event_id("n"), event_id("o")],
event_id("n") => vec![event_id("o")], event_id("n") => btreeset![event_id("o")],
event_id("o") => vec![], // "o" has zero outgoing edges but 4 incoming edges event_id("o") => btreeset![], // "o" has zero outgoing edges but 4 incoming edges
event_id("p") => vec![event_id("o")], event_id("p") => btreeset![event_id("o")],
}; };
b.iter(|| { b.iter(|| {
let _ = StateResolution::lexicographical_topological_sort(&graph, |id| { let _ = StateResolution::lexicographical_topological_sort(&graph, |id| {
@ -61,7 +61,7 @@ fn resolution_shallow_auth_chain(c: &mut Criterion) {
let state_sets = vec![state_at_bob.clone(), state_at_charlie.clone()]; let state_sets = vec![state_at_bob.clone(), state_at_charlie.clone()];
let _ = match StateResolution::resolve::<StateEvent>( let _ = match StateResolution::resolve::<StateEvent>(
&room_id(), &room_id(),
&RoomVersionId::Version2, &RoomVersionId::Version6,
&state_sets, &state_sets,
state_sets state_sets
.iter() .iter()
@ -82,10 +82,9 @@ fn resolution_shallow_auth_chain(c: &mut Criterion) {
fn resolve_deeper_event_set(c: &mut Criterion) { fn resolve_deeper_event_set(c: &mut Criterion) {
c.bench_function("resolve state of 10 events 3 conflicting", |b| { c.bench_function("resolve state of 10 events 3 conflicting", |b| {
let init = INITIAL_EVENTS(); let mut inner = INITIAL_EVENTS();
let ban = BAN_STATE_SET(); let ban = BAN_STATE_SET();
let mut inner = init;
inner.extend(ban); inner.extend(ban);
let store = TestStore(inner.clone()); let store = TestStore(inner.clone());
@ -119,7 +118,7 @@ fn resolve_deeper_event_set(c: &mut Criterion) {
let state_sets = vec![state_set_a.clone(), state_set_b.clone()]; let state_sets = vec![state_set_a.clone(), state_set_b.clone()];
let _ = match StateResolution::resolve::<StateEvent>( let _ = match StateResolution::resolve::<StateEvent>(
&room_id(), &room_id(),
&RoomVersionId::Version2, &RoomVersionId::Version6,
&state_sets, &state_sets,
state_sets state_sets
.iter() .iter()
@ -330,25 +329,11 @@ fn room_id() -> RoomId {
} }
fn member_content_ban() -> JsonValue { fn member_content_ban() -> JsonValue {
serde_json::to_value(MemberEventContent { serde_json::to_value(MemberEventContent::new(MembershipState::Ban)).unwrap()
membership: MembershipState::Ban,
displayname: None,
avatar_url: None,
is_direct: None,
third_party_invite: None,
})
.unwrap()
} }
fn member_content_join() -> JsonValue { fn member_content_join() -> JsonValue {
serde_json::to_value(MemberEventContent { serde_json::to_value(MemberEventContent::new(MembershipState::Join)).unwrap()
membership: MembershipState::Join,
displayname: None,
avatar_url: None,
is_direct: None,
third_party_invite: None,
})
.unwrap()
} }
pub fn to_pdu_event<S>( pub fn to_pdu_event<S>(
@ -363,6 +348,8 @@ pub fn to_pdu_event<S>(
where where
S: AsRef<str>, S: AsRef<str>,
{ {
// We don't care if the addition happens in order just that it is atomic
// (each event has its own value)
let ts = SERVER_TIMESTAMP.fetch_add(1, SeqCst); let ts = SERVER_TIMESTAMP.fetch_add(1, SeqCst);
let id = if id.contains('$') { id.to_string() } else { format!("${}:foo", id) }; let id = if id.contains('$') { id.to_string() } else { format!("${}:foo", id) };
let auth_events = auth_events.iter().map(AsRef::as_ref).map(event_id).collect::<Vec<_>>(); let auth_events = auth_events.iter().map(AsRef::as_ref).map(event_id).collect::<Vec<_>>();

View File

@ -304,7 +304,7 @@ pub fn valid_membership_change<E: Event>(
auth_events: &StateMap<Arc<E>>, auth_events: &StateMap<Arc<E>>,
) -> Result<bool> { ) -> Result<bool> {
let target_membership = serde_json::from_value::<MembershipState>( let target_membership = serde_json::from_value::<MembershipState>(
content.get("membership").expect("we should test before that this field exists").clone(), content.get("membership").expect("we test before that this field exists").clone(),
)?; )?;
let third_party_invite = content let third_party_invite = content
@ -493,7 +493,7 @@ pub fn can_send_event<E: Event>(event: &Arc<E>, auth_events: &StateMap<Arc<E>>)
let event_type_power_level = get_send_level(&event.kind(), event.state_key(), ple); let event_type_power_level = get_send_level(&event.kind(), event.state_key(), ple);
let user_level = get_user_power_level(event.sender(), auth_events); let user_level = get_user_power_level(event.sender(), auth_events);
debug!("{} ev_type {} usr {}", event.event_id().as_str(), event_type_power_level, user_level); debug!("{} ev_type {} usr {}", event.event_id(), event_type_power_level, user_level);
if user_level < event_type_power_level { if user_level < event_type_power_level {
return false; return false;
@ -756,7 +756,6 @@ pub fn get_send_level<E: Event>(
state_key: Option<String>, state_key: Option<String>,
power_lvl: Option<&Arc<E>>, power_lvl: Option<&Arc<E>>,
) -> i64 { ) -> i64 {
debug!("{:?} {:?}", e_type, state_key);
power_lvl power_lvl
.and_then(|ple| { .and_then(|ple| {
serde_json::from_value::<PowerLevelsEventContent>(ple.content()) serde_json::from_value::<PowerLevelsEventContent>(ple.content())

View File

@ -77,19 +77,20 @@ impl StateResolution {
// Add the auth_diff to conflicting now we have a full set of conflicting events // Add the auth_diff to conflicting now we have a full set of conflicting events
auth_diff.extend(conflicting.values().cloned().flatten()); auth_diff.extend(conflicting.values().cloned().flatten());
let mut all_conflicted =
auth_diff.into_iter().collect::<BTreeSet<_>>().into_iter().collect::<Vec<_>>(); // `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()); info!("full conflicted set is {} events", all_conflicted.len());
// We used to check that all events are events from the correct room // We used to check that all events are events from the correct room
// this is now a check the caller of `resolve` must make. // this is now a check the caller of `resolve` must make.
// Synapse says `full_set = {eid for eid in full_conflicted_set if eid in event_map}`
//
// Don't honor events we cannot "verify"
all_conflicted.retain(|id| event_map.contains_key(id));
// Get only the control events with a state_key: "" or ban/kick event (sender != state_key) // Get only the control events with a state_key: "" or ban/kick event (sender != state_key)
let control_events = all_conflicted let control_events = all_conflicted
.iter() .iter()
@ -98,7 +99,7 @@ impl StateResolution {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Sort the control events based on power_level/clock/event_id and outgoing/incoming edges // Sort the control events based on power_level/clock/event_id and outgoing/incoming edges
let mut sorted_control_levels = StateResolution::reverse_topological_power_sort( let sorted_control_levels = StateResolution::reverse_topological_power_sort(
room_id, room_id,
&control_events, &control_events,
event_map, event_map,
@ -117,15 +118,11 @@ impl StateResolution {
event_map, event_map,
)?; )?;
debug!( debug!("AUTHED {:?}", resolved_control.iter().collect::<Vec<_>>());
"AUTHED {:?}",
resolved_control.iter().map(|(key, id)| (key, id.to_string())).collect::<Vec<_>>()
);
// At this point the control_events have been resolved we now have to // 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. // sort the remaining events using the mainline of the resolved power level.
sorted_control_levels.dedup(); let deduped_power_ev = sorted_control_levels.into_iter().collect::<BTreeSet<_>>();
let deduped_power_ev = sorted_control_levels;
// This removes the control events that passed auth and more importantly those that failed // This removes the control events that passed auth and more importantly those that failed
// auth // auth
@ -135,7 +132,7 @@ impl StateResolution {
.cloned() .cloned()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
debug!("LEFT {:?}", events_to_resolve.iter().map(ToString::to_string).collect::<Vec<_>>()); debug!("LEFT {:?}", events_to_resolve.iter().collect::<Vec<_>>());
// This "epochs" power level event // This "epochs" power level event
let power_event = resolved_control.get(&(EventType::RoomPowerLevels, "".into())); let power_event = resolved_control.get(&(EventType::RoomPowerLevels, "".into()));
@ -145,10 +142,7 @@ impl StateResolution {
let sorted_left_events = let sorted_left_events =
StateResolution::mainline_sort(room_id, &events_to_resolve, power_event, event_map); StateResolution::mainline_sort(room_id, &events_to_resolve, power_event, event_map);
debug!( debug!("SORTED LEFT {:?}", sorted_left_events.iter().collect::<Vec<_>>());
"SORTED LEFT {:?}",
sorted_left_events.iter().map(ToString::to_string).collect::<Vec<_>>()
);
let mut resolved_state = StateResolution::iterative_auth_check( let mut resolved_state = StateResolution::iterative_auth_check(
room_id, room_id,
@ -180,16 +174,13 @@ impl StateResolution {
let mut unconflicted_state = StateMap::new(); let mut unconflicted_state = StateMap::new();
let mut conflicted_state = StateMap::new(); let mut conflicted_state = StateMap::new();
for key in state_sets.iter().flat_map(|map| map.keys()).dedup() { for key in state_sets.iter().flat_map(|map| map.keys()).unique() {
let mut event_ids = let mut event_ids =
state_sets.iter().map(|state_set| state_set.get(key)).dedup().collect::<Vec<_>>(); state_sets.iter().map(|state_set| state_set.get(key)).unique().collect::<Vec<_>>();
if event_ids.len() == 1 { if event_ids.len() == 1 {
if let Some(Some(id)) = event_ids.pop() { let id = event_ids.remove(0).expect("unconflicting `EventId` is not None");
unconflicted_state.insert(key.clone(), id.clone()); unconflicted_state.insert(key.clone(), id.clone());
} else {
panic!()
}
} else { } else {
conflicted_state.insert( conflicted_state.insert(
key.clone(), key.clone(),
@ -205,9 +196,7 @@ impl StateResolution {
pub fn get_auth_chain_diff( pub fn get_auth_chain_diff(
_room_id: &RoomId, _room_id: &RoomId,
auth_event_ids: &[Vec<EventId>], auth_event_ids: &[Vec<EventId>],
) -> Result<Vec<EventId>> { ) -> Result<BTreeSet<EventId>> {
use itertools::Itertools;
let mut chains = vec![]; let mut chains = vec![];
for ids in auth_event_ids { for ids in auth_event_ids {
@ -221,9 +210,9 @@ impl StateResolution {
let rest = chains.iter().skip(1).flatten().cloned().collect(); let rest = chains.iter().skip(1).flatten().cloned().collect();
let common = chain.intersection(&rest).collect::<Vec<_>>(); let common = chain.intersection(&rest).collect::<Vec<_>>();
Ok(chains.into_iter().flatten().filter(|id| !common.contains(&id)).dedup().collect()) Ok(chains.into_iter().flatten().filter(|id| !common.contains(&id)).collect())
} else { } else {
Ok(vec![]) Ok(btreeset![])
} }
} }
@ -238,7 +227,7 @@ impl StateResolution {
room_id: &RoomId, room_id: &RoomId,
events_to_sort: &[EventId], events_to_sort: &[EventId],
event_map: &mut EventMap<Arc<E>>, event_map: &mut EventMap<Arc<E>>,
auth_diff: &[EventId], auth_diff: &BTreeSet<EventId>,
) -> Vec<EventId> { ) -> Vec<EventId> {
debug!("reverse topological sort of power events"); debug!("reverse topological sort of power events");
@ -257,7 +246,7 @@ impl StateResolution {
let mut event_to_pl = BTreeMap::new(); let mut event_to_pl = BTreeMap::new();
for event_id in graph.keys() { for event_id in graph.keys() {
let pl = StateResolution::get_power_level_for_sender(room_id, event_id, event_map); let pl = StateResolution::get_power_level_for_sender(room_id, event_id, event_map);
info!("{} power level {}", event_id.to_string(), pl); info!("{} power level {}", event_id, pl);
event_to_pl.insert(event_id.clone(), pl); event_to_pl.insert(event_id.clone(), pl);
@ -283,7 +272,7 @@ impl StateResolution {
/// `key_fn` is used as a tie breaker. The tie breaker happens based on /// `key_fn` is used as a tie breaker. The tie breaker happens based on
/// power level, age, and event_id. /// power level, age, and event_id.
pub fn lexicographical_topological_sort<F>( pub fn lexicographical_topological_sort<F>(
graph: &BTreeMap<EventId, Vec<EventId>>, graph: &BTreeMap<EventId, BTreeSet<EventId>>,
key_fn: F, key_fn: F,
) -> Vec<EventId> ) -> Vec<EventId>
where where
@ -300,8 +289,7 @@ impl StateResolution {
// TODO make the BTreeSet conversion cleaner ?? // TODO make the BTreeSet conversion cleaner ??
// outdegree_map is an event referring to the events before it, the // outdegree_map is an event referring to the events before it, the
// more outdegree's the more recent the event. // more outdegree's the more recent the event.
let mut outdegree_map: BTreeMap<EventId, BTreeSet<EventId>> = let mut outdegree_map = graph.clone();
graph.iter().map(|(k, v)| (k.clone(), v.iter().cloned().collect())).collect();
// The number of events that depend on the given event (the eventId key) // The number of events that depend on the given event (the eventId key)
let mut reverse_graph = BTreeMap::new(); let mut reverse_graph = BTreeMap::new();
@ -353,7 +341,7 @@ impl StateResolution {
event_id: &EventId, event_id: &EventId,
event_map: &mut EventMap<Arc<E>>, event_map: &mut EventMap<Arc<E>>,
) -> i64 { ) -> i64 {
info!("fetch event ({}) senders power level", event_id.to_string()); info!("fetch event ({}) senders power level", event_id);
let event = StateResolution::get_or_load_event(room_id, event_id, event_map); let event = StateResolution::get_or_load_event(room_id, event_id, event_map);
let mut pl = None; let mut pl = None;
@ -378,7 +366,7 @@ impl StateResolution {
{ {
if let Ok(ev) = event { if let Ok(ev) = event {
if let Some(user) = content.users.get(ev.sender()) { if let Some(user) = content.users.get(ev.sender()) {
debug!("found {} at power_level {}", ev.sender().as_str(), user); debug!("found {} at power_level {}", ev.sender(), user);
return (*user).into(); return (*user).into();
} }
} }
@ -407,10 +395,7 @@ impl StateResolution {
) -> Result<StateMap<EventId>> { ) -> Result<StateMap<EventId>> {
info!("starting iterative auth check"); info!("starting iterative auth check");
debug!( debug!("performing auth checks on {:?}", events_to_check.iter().collect::<Vec<_>>());
"performing auth checks on {:?}",
events_to_check.iter().map(ToString::to_string).collect::<Vec<_>>()
);
let mut resolved_state = unconflicted_state.clone(); let mut resolved_state = unconflicted_state.clone();
@ -454,7 +439,7 @@ impl StateResolution {
} }
} }
debug!("event to check {:?}", event.event_id().as_str()); debug!("event to check {:?}", event.event_id());
let most_recent_prev_event = event let most_recent_prev_event = event
.prev_events() .prev_events()
@ -483,7 +468,7 @@ impl StateResolution {
resolved_state.insert((event.kind(), state_key), event_id.clone()); resolved_state.insert((event.kind(), state_key), event_id.clone());
} else { } else {
// synapse passes here on AuthError. We do not add this event to resolved_state. // synapse passes here on AuthError. We do not add this event to resolved_state.
warn!("event {} failed the authentication check", event_id.to_string()); warn!("event {} failed the authentication check", event_id);
} }
// TODO: if these functions are ever made async here // TODO: if these functions are ever made async here
@ -582,7 +567,7 @@ impl StateResolution {
event_map: &mut EventMap<Arc<E>>, event_map: &mut EventMap<Arc<E>>,
) -> Result<usize> { ) -> Result<usize> {
while let Some(sort_ev) = event { while let Some(sort_ev) = event {
debug!("mainline event_id {}", sort_ev.event_id().to_string()); debug!("mainline event_id {}", sort_ev.event_id());
let id = &sort_ev.event_id(); let id = &sort_ev.event_id();
if let Some(depth) = mainline_map.get(id) { if let Some(depth) = mainline_map.get(id) {
return Ok(*depth); return Ok(*depth);
@ -604,20 +589,20 @@ impl StateResolution {
fn add_event_and_auth_chain_to_graph<E: Event>( fn add_event_and_auth_chain_to_graph<E: Event>(
room_id: &RoomId, room_id: &RoomId,
graph: &mut BTreeMap<EventId, Vec<EventId>>, graph: &mut BTreeMap<EventId, BTreeSet<EventId>>,
event_id: &EventId, event_id: &EventId,
event_map: &mut EventMap<Arc<E>>, event_map: &mut EventMap<Arc<E>>,
auth_diff: &[EventId], auth_diff: &BTreeSet<EventId>,
) { ) {
let mut state = vec![event_id.clone()]; let mut state = vec![event_id.clone()];
while !state.is_empty() { while !state.is_empty() {
// We just checked if it was empty so unwrap is fine // We just checked if it was empty so unwrap is fine
let eid = state.pop().unwrap(); let eid = state.pop().unwrap();
graph.entry(eid.clone()).or_insert_with(Vec::new); graph.entry(eid.clone()).or_insert(btreeset![]);
// Prefer the store to event as the store filters dedups the events // Prefer the store to event as the store filters dedups the events
// Otherwise it seems we can loop forever for aid in &StateResolution::get_or_load_event(room_id, &eid, event_map)
for aid in .map(|ev| ev.auth_events())
&StateResolution::get_or_load_event(room_id, &eid, event_map).unwrap().auth_events() .unwrap_or_default()
{ {
if auth_diff.contains(aid) { if auth_diff.contains(aid) {
if !graph.contains_key(aid) { if !graph.contains_key(aid) {
@ -625,7 +610,7 @@ impl StateResolution {
} }
// We just inserted this at the start of the while loop // We just inserted this at the start of the while loop
graph.get_mut(&eid).unwrap().push(aid.clone()); graph.get_mut(&eid).unwrap().insert(aid.clone());
} }
} }
} }

View File

@ -2,9 +2,6 @@ use std::sync::Arc;
use ruma_events::EventType; use ruma_events::EventType;
use ruma_state_res::{event_auth::valid_membership_change, StateMap}; use ruma_state_res::{event_auth::valid_membership_change, StateMap};
// use ruma_state_res::event_auth:::{
// auth_check, auth_types_for_event, can_federate, check_power_levels, check_redaction,
// };
mod utils; mod utils;
use utils::{alice, charlie, event_id, member_content_ban, to_pdu_event, INITIAL_EVENTS}; use utils::{alice, charlie, event_id, member_content_ban, to_pdu_event, INITIAL_EVENTS};

View File

@ -1,4 +1,4 @@
use std::collections::BTreeMap; use std::collections::{BTreeMap, BTreeSet};
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use ruma_events::EventType; use ruma_events::EventType;
@ -15,7 +15,7 @@ fn test_event_sort() {
.map(|ev| ((ev.kind(), ev.state_key()), ev.clone())) .map(|ev| ((ev.kind(), ev.state_key()), ev.clone()))
.collect::<StateMap<_>>(); .collect::<StateMap<_>>();
let auth_chain = &[] as &[_]; let auth_chain = BTreeSet::new();
let power_events = event_map let power_events = event_map
.values() .values()
@ -30,7 +30,7 @@ fn test_event_sort() {
&room_id(), &room_id(),
&power_events, &power_events,
&mut events, &mut events,
auth_chain, &auth_chain,
); );
// This is a TODO in conduit // This is a TODO in conduit

View File

@ -67,7 +67,7 @@ fn ban_with_auth_chains2() {
let state_sets = vec![state_set_a, state_set_b]; let state_sets = vec![state_set_a, state_set_b];
let resolved = match StateResolution::resolve::<StateEvent>( let resolved = match StateResolution::resolve::<StateEvent>(
&room_id(), &room_id(),
&RoomVersionId::Version2, &RoomVersionId::Version6,
&state_sets, &state_sets,
state_sets state_sets
.iter() .iter()

View File

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use js_int::uint; use js_int::uint;
use maplit::btreemap; use maplit::{btreemap, btreeset};
use ruma_common::MilliSecondsSinceUnixEpoch; use ruma_common::MilliSecondsSinceUnixEpoch;
use ruma_events::{room::join_rules::JoinRule, EventType}; use ruma_events::{room::join_rules::JoinRule, EventType};
use ruma_identifiers::{EventId, RoomVersionId}; use ruma_identifiers::{EventId, RoomVersionId};
@ -240,6 +240,13 @@ fn topic_setting() {
#[test] #[test]
fn test_event_map_none() { fn test_event_map_none() {
// This is the only test that does not use `do_check` so we
// have to start the logger if this is what we're running.
//
// to activate logging use `RUST_LOG=debug cargo t one_test_only`
let _ = LOGGER
.call_once(|| tracer::fmt().with_env_filter(tracer::EnvFilter::from_default_env()).init());
let mut store = TestStore::<StateEvent>(btreemap! {}); let mut store = TestStore::<StateEvent>(btreemap! {});
// build up the DAG // build up the DAG
@ -271,11 +278,11 @@ fn test_event_map_none() {
#[test] #[test]
fn test_lexicographical_sort() { fn test_lexicographical_sort() {
let graph = btreemap! { let graph = btreemap! {
event_id("l") => vec![event_id("o")], event_id("l") => btreeset![event_id("o")],
event_id("m") => vec![event_id("n"), event_id("o")], event_id("m") => btreeset![event_id("n"), event_id("o")],
event_id("n") => vec![event_id("o")], event_id("n") => btreeset![event_id("o")],
event_id("o") => vec![], // "o" has zero outgoing edges but 4 incoming edges event_id("o") => btreeset![], // "o" has zero outgoing edges but 4 incoming edges
event_id("p") => vec![event_id("o")], event_id("p") => btreeset![event_id("o")],
}; };
let res = StateResolution::lexicographical_topological_sort(&graph, |id| { let res = StateResolution::lexicographical_topological_sort(&graph, |id| {
@ -296,10 +303,6 @@ fn test_lexicographical_sort() {
// //
impl TestStore<StateEvent> { impl TestStore<StateEvent> {
pub fn set_up(&mut self) -> (StateMap<EventId>, StateMap<EventId>, StateMap<EventId>) { pub fn set_up(&mut self) -> (StateMap<EventId>, StateMap<EventId>, StateMap<EventId>) {
// to activate logging use `RUST_LOG=debug cargo t one_test_only`
let _ = LOGGER.call_once(|| {
tracer::fmt().with_env_filter(tracer::EnvFilter::from_default_env()).init()
});
let create_event = to_pdu_event::<EventId>( let create_event = to_pdu_event::<EventId>(
"CREATE", "CREATE",
alice(), alice(),

View File

@ -10,7 +10,7 @@ use std::{
}; };
use js_int::uint; use js_int::uint;
use maplit::btreemap; use maplit::{btreemap, btreeset};
use ruma_common::MilliSecondsSinceUnixEpoch; use ruma_common::MilliSecondsSinceUnixEpoch;
use ruma_events::{ use ruma_events::{
pdu::{EventHash, Pdu, RoomV3Pdu}, pdu::{EventHash, Pdu, RoomV3Pdu},
@ -37,9 +37,8 @@ pub fn do_check(
edges: Vec<Vec<EventId>>, edges: Vec<Vec<EventId>>,
expected_state_ids: Vec<EventId>, expected_state_ids: Vec<EventId>,
) { ) {
// to activate logging use `RUST_LOG=debug cargo t` // To activate logging use `RUST_LOG=debug cargo t`
let _ = LOGGER // The logger is initialized in the `INITIAL_EVENTS` function.
.call_once(|| tracer::fmt().with_env_filter(tracer::EnvFilter::from_default_env()).init());
let init_events = INITIAL_EVENTS(); let init_events = INITIAL_EVENTS();
@ -55,20 +54,20 @@ pub fn do_check(
// Create the DB of events that led up to this point // Create the DB of events that led up to this point
// TODO maybe clean up some of these clones it is just tests but... // TODO maybe clean up some of these clones it is just tests but...
for ev in init_events.values().chain(events) { for ev in init_events.values().chain(events) {
graph.insert(ev.event_id().clone(), vec![]); graph.insert(ev.event_id().clone(), btreeset![]);
fake_event_map.insert(ev.event_id().clone(), ev.clone()); fake_event_map.insert(ev.event_id().clone(), ev.clone());
} }
for pair in INITIAL_EDGES().windows(2) { for pair in INITIAL_EDGES().windows(2) {
if let [a, b] = &pair { if let [a, b] = &pair {
graph.entry(a.clone()).or_insert(vec![]).push(b.clone()); graph.entry(a.clone()).or_insert(btreeset![]).insert(b.clone());
} }
} }
for edge_list in edges { for edge_list in edges {
for pair in edge_list.windows(2) { for pair in edge_list.windows(2) {
if let [a, b] = &pair { if let [a, b] = &pair {
graph.entry(a.clone()).or_insert(vec![]).push(b.clone()); graph.entry(a.clone()).or_insert(btreeset![]).insert(b.clone());
} }
} }
} }
@ -91,7 +90,7 @@ pub fn do_check(
let state_before: StateMap<EventId> = if prev_events.is_empty() { let state_before: StateMap<EventId> = if prev_events.is_empty() {
BTreeMap::new() BTreeMap::new()
} else if prev_events.len() == 1 { } else if prev_events.len() == 1 {
state_at_event.get(&prev_events[0]).unwrap().clone() state_at_event.get(prev_events.iter().next().unwrap()).unwrap().clone()
} else { } else {
let state_sets = prev_events let state_sets = prev_events
.iter() .iter()
@ -161,7 +160,7 @@ pub fn do_check(
Some(&e.state_key()), Some(&e.state_key()),
e.content(), e.content(),
&auth_events, &auth_events,
prev_events, &prev_events.iter().cloned().collect::<Vec<_>>(),
); );
// We have to update our store, an actual user of this lib would // We have to update our store, an actual user of this lib would