diff --git a/benches/event_auth_bench.rs b/benches/event_auth_bench.rs index e69de29b..8b137891 100644 --- a/benches/event_auth_bench.rs +++ b/benches/event_auth_bench.rs @@ -0,0 +1 @@ + diff --git a/benches/state_res_bench.rs b/benches/state_res_bench.rs index 86d55ff1..b543de02 100644 --- a/benches/state_res_bench.rs +++ b/benches/state_res_bench.rs @@ -48,13 +48,21 @@ fn resolution_shallow_auth_chain(c: &mut Criterion) { let (state_at_bob, state_at_charlie, _) = store.set_up(); b.iter(|| { - let mut ev_map = state_res::EventMap::default(); - let _resolved = match StateResolution::resolve( + let mut ev_map: state_res::EventMap> = store.0.clone(); + let state_sets = vec![state_at_bob.clone(), state_at_charlie.clone()]; + let _ = match StateResolution::resolve::( &room_id(), - &RoomVersionId::Version6, - &[state_at_bob.clone(), state_at_charlie.clone()], + &RoomVersionId::Version2, + &state_sets, + state_sets + .iter() + .map(|map| { + store + .auth_event_ids(&room_id(), &map.values().cloned().collect::>()) + .unwrap() + }) + .collect(), &mut ev_map, - &store, ) { Ok(state) => state, Err(e) => panic!("{}", e), @@ -99,12 +107,20 @@ fn resolve_deeper_event_set(c: &mut Criterion) { .collect::>(); b.iter(|| { - let _resolved = match StateResolution::resolve( + let state_sets = vec![state_set_a.clone(), state_set_b.clone()]; + let _ = match StateResolution::resolve::( &room_id(), - &RoomVersionId::Version6, - &[state_set_a.clone(), state_set_b.clone()], + &RoomVersionId::Version2, + &state_sets, + state_sets + .iter() + .map(|map| { + store + .auth_event_ids(&room_id(), &map.values().cloned().collect::>()) + .unwrap() + }) + .collect(), &mut inner, - &store, ) { Ok(state) => state, Err(_) => panic!("resolution failed during benchmarking"), @@ -530,7 +546,9 @@ pub mod event { fn hashes(&self) -> &EventHash { self.hashes() } - fn signatures(&self) -> BTreeMap, BTreeMap> { + fn signatures( + &self, + ) -> BTreeMap, BTreeMap> { self.signatures() } fn unsigned(&self) -> &BTreeMap { @@ -643,7 +661,10 @@ pub mod event { } impl StateEvent { - pub fn from_id_value(id: EventId, json: serde_json::Value) -> Result { + pub fn from_id_value( + id: EventId, + json: serde_json::Value, + ) -> Result { Ok(Self::Full( id, Pdu::RoomV3Pdu(serde_json::from_value(json)?), @@ -671,6 +692,7 @@ pub mod event { EventType::RoomMember => { if let Ok(content) = // TODO fix clone + serde_json::from_value::(event.content.clone()) { if [MembershipState::Leave, MembershipState::Ban] @@ -771,7 +793,9 @@ pub mod event { pub fn prev_event_ids(&self) -> Vec { match self { Self::Full(_, ev) => match ev { - Pdu::RoomV1Pdu(ev) => ev.prev_events.iter().map(|(id, _)| id).cloned().collect(), + Pdu::RoomV1Pdu(ev) => { + ev.prev_events.iter().map(|(id, _)| id).cloned().collect() + } Pdu::RoomV3Pdu(ev) => ev.prev_events.clone(), }, } @@ -780,7 +804,9 @@ pub mod event { pub fn auth_events(&self) -> Vec { match self { Self::Full(_, ev) => match ev { - Pdu::RoomV1Pdu(ev) => ev.auth_events.iter().map(|(id, _)| id).cloned().collect(), + Pdu::RoomV1Pdu(ev) => { + ev.auth_events.iter().map(|(id, _)| id).cloned().collect() + } Pdu::RoomV3Pdu(ev) => ev.auth_events.to_vec(), }, } @@ -860,4 +886,4 @@ pub mod event { } } } -} \ No newline at end of file +} diff --git a/src/event_auth.rs b/src/event_auth.rs index 29c0e703..21b69515 100644 --- a/src/event_auth.rs +++ b/src/event_auth.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, convert::TryFrom, sync::Arc}; +use std::{convert::TryFrom, sync::Arc}; use maplit::btreeset; use ruma::{ @@ -67,6 +67,10 @@ pub fn auth_types_for_event( /// * check that the event is being authenticated for the correct room /// * check that the events signatures are valid /// * then there are checks for specific event types +/// +/// The `auth_events` that are passed to this function should be a state snapshot. +/// We need to know if the event passes auth against some state not a recursive collection +/// of auth_events fields. pub fn auth_check( room_version: &RoomVersionId, incoming_event: &Arc, diff --git a/src/lib.rs b/src/lib.rs index 2411d42c..5622e15a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,14 +46,13 @@ impl StateResolution { room_version: &RoomVersionId, incoming_event: Arc, current_state: &StateMap, - event_map: &mut EventMap>, - store: &dyn StateStore, + event_map: &EventMap>, ) -> Result { tracing::info!("Applying a single event, state resolution starting"); let ev = incoming_event; let prev_event = if let Some(id) = ev.prev_events().first() { - store.get_event(room_id, id).ok() + event_map.get(id).map(Arc::clone) } else { None }; @@ -63,9 +62,7 @@ impl StateResolution { event_auth::auth_types_for_event(&ev.kind(), &ev.sender(), ev.state_key(), ev.content()) { if let Some(ev_id) = current_state.get(&key) { - if let Some(event) = - StateResolution::get_or_load_event(room_id, ev_id, event_map, store) - { + if let Ok(event) = StateResolution::get_or_load_event(room_id, ev_id, event_map) { // TODO synapse checks `rejected_reason` is None here auth_events.insert(key.clone(), event); } @@ -83,22 +80,21 @@ impl StateResolution { /// * `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 be fetched from the `StateStore` and cached in the `event_map`. There /// is no state kept from separate `resolve` calls, although this could be a potential optimization /// in the future. /// - /// * `store` - Any type that implements `StateStore` acts as the database. When an event is not - /// found in the `event_map` it will be retrieved from the `store`. - /// /// It is up the the caller to check that the events returned from `StateStore::get_event` are /// events for the correct room (synapse checks that all events are in the right room). pub fn resolve( room_id: &RoomId, room_version: &RoomVersionId, state_sets: &[StateMap], + auth_events: Vec>, event_map: &mut EventMap>, - store: &dyn StateStore, ) -> Result> { tracing::info!("State resolution starting"); @@ -115,9 +111,9 @@ impl StateResolution { tracing::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, &state_sets, store)?; + let mut auth_diff = StateResolution::get_auth_chain_diff(room_id, &auth_events)?; - tracing::debug!("auth diff size {}", auth_diff.len()); + tracing::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()); @@ -129,25 +125,6 @@ impl StateResolution { tracing::info!("full conflicted set is {} events", all_conflicted.len()); - // gather missing events for the event_map - let events = store - .get_events( - room_id, - &all_conflicted - .iter() - // we only want the events we don't know about yet - .filter(|id| !event_map.contains_key(id)) - .cloned() - .collect::>(), - ) - .unwrap(); - - // update event_map to include the fetched events - event_map.extend(events.into_iter().map(|ev| (ev.event_id().clone(), ev))); - // at this point our event_map == store there should be no missing events - - tracing::debug!("event map size: {}", event_map.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. @@ -168,17 +145,10 @@ impl StateResolution { room_id, &control_events, event_map, - store, &all_conflicted, ); - tracing::debug!( - "SRTD {:?}", - sorted_control_levels - .iter() - .map(ToString::to_string) - .collect::>() - ); + tracing::debug!("SRTD {:?}", sorted_control_levels); // sequentially auth check each control event. let resolved_control = StateResolution::iterative_auth_check( @@ -187,7 +157,6 @@ impl StateResolution { &sorted_control_levels, &clean, event_map, - store, )?; tracing::debug!( @@ -223,13 +192,8 @@ impl StateResolution { tracing::debug!("PL {:?}", power_event); - let sorted_left_events = StateResolution::mainline_sort( - room_id, - &events_to_resolve, - power_event, - event_map, - store, - ); + let sorted_left_events = + StateResolution::mainline_sort(room_id, &events_to_resolve, power_event, event_map); tracing::debug!( "SORTED LEFT {:?}", @@ -245,7 +209,6 @@ impl StateResolution { &sorted_left_events, &resolved_control, // The control events are added to the final resolved state event_map, - store, )?; // add unconflicted state to the resolved state @@ -298,23 +261,34 @@ impl StateResolution { } /// Returns a Vec of deduped EventIds that appear in some chains but not others. - pub fn get_auth_chain_diff( - room_id: &RoomId, - state_sets: &[StateMap], - store: &dyn StateStore, + pub fn get_auth_chain_diff( + _room_id: &RoomId, + auth_event_ids: &[Vec], ) -> Result> { - use itertools::Itertools; + let mut chains = vec![]; - tracing::debug!("calculating auth chain difference"); + for ids in auth_event_ids { + // TODO state store `auth_event_ids` returns self in the event ids list + // when an event returns `auth_event_ids` self is not contained + let chain = ids.iter().cloned().collect::>(); + chains.push(chain); + } - store.auth_chain_diff( - room_id, - state_sets + if let Some(chain) = chains.first() { + let rest = chains.iter().skip(1).flatten().cloned().collect(); + let common = chain.intersection(&rest).collect::>(); + + Ok(chains .iter() - .map(|map| map.values().cloned().collect()) - .dedup() - .collect::>(), - ) + .flatten() + .filter(|id| !common.contains(&id)) + .cloned() + .collect::>() + .into_iter() + .collect()) + } else { + Ok(vec![]) + } } /// Events are sorted from "earliest" to "latest". They are compared using @@ -328,7 +302,6 @@ impl StateResolution { room_id: &RoomId, events_to_sort: &[EventId], event_map: &mut EventMap>, - store: &dyn StateStore, auth_diff: &[EventId], ) -> Vec { tracing::debug!("reverse topological sort of power events"); @@ -336,7 +309,7 @@ impl StateResolution { let mut graph = BTreeMap::new(); for (idx, event_id) in events_to_sort.iter().enumerate() { StateResolution::add_event_and_auth_chain_to_graph( - room_id, &mut graph, event_id, event_map, store, auth_diff, + room_id, &mut graph, event_id, event_map, auth_diff, ); // We yield occasionally when we're working with large data sets to @@ -349,8 +322,7 @@ impl StateResolution { // this is used in the `key_fn` passed to the lexico_topo_sort fn let mut event_to_pl = BTreeMap::new(); for (idx, event_id) in graph.keys().enumerate() { - let pl = - StateResolution::get_power_level_for_sender(room_id, &event_id, event_map, store); + let pl = StateResolution::get_power_level_for_sender(room_id, &event_id, event_map); tracing::info!("{} power level {}", event_id.to_string(), pl); event_to_pl.insert(event_id.clone(), pl); @@ -454,11 +426,10 @@ impl StateResolution { room_id: &RoomId, event_id: &EventId, event_map: &mut EventMap>, - store: &dyn StateStore, ) -> i64 { tracing::info!("fetch event ({}) senders power level", event_id.to_string()); - let event = StateResolution::get_or_load_event(room_id, event_id, event_map, store); + let event = StateResolution::get_or_load_event(room_id, event_id, event_map); let mut pl = None; // TODO store.auth_event_ids returns "self" with the event ids is this ok @@ -468,7 +439,7 @@ impl StateResolution { .map(|pdu| pdu.auth_events()) .unwrap_or_default() { - if let Some(aev) = StateResolution::get_or_load_event(room_id, &aid, event_map, store) { + if let Ok(aev) = StateResolution::get_or_load_event(room_id, &aid, event_map) { if is_type_and_key(&aev, EventType::RoomPowerLevels, "") { pl = Some(aev); break; @@ -489,9 +460,9 @@ impl StateResolution { }) .flatten() { - if let Some(ev) = event { + if let Ok(ev) = event { if let Some(user) = content.users.get(&ev.sender()) { - tracing::debug!("found {} at power_level {}", ev.sender().to_string(), user); + tracing::debug!("found {} at power_level {}", ev.sender().as_str(), user); return (*user).into(); } } @@ -517,7 +488,6 @@ impl StateResolution { events_to_check: &[EventId], unconflicted_state: &StateMap, event_map: &mut EventMap>, - store: &dyn StateStore, ) -> Result> { tracing::info!("starting iterative auth check"); @@ -532,14 +502,11 @@ impl StateResolution { let mut resolved_state = unconflicted_state.clone(); for (idx, event_id) in events_to_check.iter().enumerate() { - let event = - StateResolution::get_or_load_event(room_id, event_id, event_map, store).unwrap(); + let event = StateResolution::get_or_load_event(room_id, event_id, event_map)?; let mut auth_events = BTreeMap::new(); for aid in &event.auth_events() { - if let Some(ev) = - StateResolution::get_or_load_event(room_id, &aid, event_map, store) - { + if let Ok(ev) = StateResolution::get_or_load_event(room_id, &aid, event_map) { // TODO what to do when no state_key is found ?? // TODO synapse check "rejected_reason", I'm guessing this is redacted_because in ruma ?? auth_events.insert((ev.kind(), ev.state_key()), ev); @@ -555,8 +522,7 @@ impl StateResolution { event.content(), ) { if let Some(ev_id) = resolved_state.get(&key) { - if let Some(event) = - StateResolution::get_or_load_event(room_id, ev_id, event_map, store) + if let Ok(event) = StateResolution::get_or_load_event(room_id, ev_id, event_map) { // TODO synapse checks `rejected_reason` is None here auth_events.insert(key.clone(), event); @@ -569,7 +535,7 @@ impl StateResolution { let most_recent_prev_event = event .prev_events() .iter() - .filter_map(|id| StateResolution::get_or_load_event(room_id, id, event_map, store)) + .filter_map(|id| StateResolution::get_or_load_event(room_id, id, event_map).ok()) .next_back(); // The key for this is (eventType + a state_key of the signed token not sender) so search @@ -620,7 +586,6 @@ impl StateResolution { to_sort: &[EventId], resolved_power_level: Option<&EventId>, event_map: &mut EventMap>, - store: &dyn StateStore, ) -> Vec { tracing::debug!("mainline sort of events"); @@ -635,12 +600,11 @@ impl StateResolution { while let Some(p) = pl { mainline.push(p.clone()); - let event = StateResolution::get_or_load_event(room_id, &p, event_map, store).unwrap(); + let event = StateResolution::get_or_load_event(room_id, &p, event_map).unwrap(); let auth_events = &event.auth_events(); pl = None; for aid in auth_events { - let ev = - StateResolution::get_or_load_event(room_id, &aid, event_map, store).unwrap(); + let ev = StateResolution::get_or_load_event(room_id, &aid, event_map).unwrap(); if is_type_and_key(&ev, EventType::RoomPowerLevels, "") { pl = Some(aid.clone()); break; @@ -663,15 +627,12 @@ impl StateResolution { let mut order_map = BTreeMap::new(); for (idx, ev_id) in to_sort.iter().enumerate() { - if let Some(event) = - StateResolution::get_or_load_event(room_id, ev_id, event_map, store) - { + if let Ok(event) = StateResolution::get_or_load_event(room_id, ev_id, event_map) { if let Ok(depth) = StateResolution::get_mainline_depth( room_id, Some(event), &mainline_map, event_map, - store, ) { order_map.insert( ev_id, @@ -706,7 +667,6 @@ impl StateResolution { mut event: Option>, mainline_map: &EventMap, event_map: &mut EventMap>, - store: &dyn StateStore, ) -> Result { while let Some(sort_ev) = event { tracing::debug!("mainline event_id {}", sort_ev.event_id().to_string()); @@ -720,8 +680,7 @@ impl StateResolution { event = None; for aid in auth_events { // dbg!(&aid); - let aev = StateResolution::get_or_load_event(room_id, &aid, event_map, store) - .ok_or_else(|| Error::NotFound("Auth event not found".to_owned()))?; + let aev = StateResolution::get_or_load_event(room_id, &aid, event_map)?; if is_type_and_key(&aev, EventType::RoomPowerLevels, "") { event = Some(aev); break; @@ -737,7 +696,6 @@ impl StateResolution { graph: &mut BTreeMap>, event_id: &EventId, event_map: &mut EventMap>, - store: &dyn StateStore, auth_diff: &[EventId], ) { let mut state = vec![event_id.clone()]; @@ -747,7 +705,7 @@ impl StateResolution { graph.entry(eid.clone()).or_insert_with(Vec::new); // 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, store) + for aid in &StateResolution::get_or_load_event(room_id, &eid, event_map) .unwrap() .auth_events() { @@ -763,27 +721,16 @@ impl StateResolution { } } - // TODO having the event_map as a field of self would allow us to keep - // cached state from `resolve` to `resolve` calls, good idea or not? - /// Uses the `event_map` to return the full PDU or fetches from the `StateStore` implementation - /// if the event_map does not have the PDU. - /// - /// If the PDU is missing from the `event_map` it is added. + /// Uses the `event_map` to return the full PDU or fails. fn get_or_load_event( - room_id: &RoomId, + _room_id: &RoomId, ev_id: &EventId, - event_map: &mut EventMap>, - store: &dyn StateStore, - ) -> Option> { - if let Some(e) = event_map.get(ev_id) { - return Some(Arc::clone(e)); - } - - if let Ok(e) = store.get_event(room_id, ev_id) { - return Some(Arc::clone(event_map.entry(ev_id.clone()).or_insert(e))); - } - - None + event_map: &EventMap>, + ) -> Result> { + event_map.get(ev_id).map_or_else( + || Err(Error::NotFound(format!("EventId: {:?} not found", ev_id))), + |e| Ok(Arc::clone(e)), + ) } } diff --git a/src/state_store.rs b/src/state_store.rs index 50dad0ea..ada65caa 100644 --- a/src/state_store.rs +++ b/src/state_store.rs @@ -4,6 +4,7 @@ use ruma::identifiers::{EventId, RoomId}; use crate::{Event, Result}; +/// TODO: this is only used in testing on this branch now REMOVE pub trait StateStore { /// Return a single event based on the EventId. fn get_event(&self, room_id: &RoomId, event_id: &EventId) -> Result>; diff --git a/tests/event_sorting.rs b/tests/event_sorting.rs index 2448e0a9..78688322 100644 --- a/tests/event_sorting.rs +++ b/tests/event_sorting.rs @@ -7,7 +7,7 @@ use ruma::{ use state_res::{is_power_event, StateMap}; mod utils; -use utils::{room_id, TestStore, INITIAL_EVENTS}; +use utils::{room_id, INITIAL_EVENTS}; fn shuffle(list: &mut [EventId]) { use rand::Rng; @@ -21,7 +21,6 @@ fn shuffle(list: &mut [EventId]) { fn test_event_sort() { let mut events = INITIAL_EVENTS(); - let store = TestStore(events.clone()); let event_map = events .values() @@ -43,7 +42,6 @@ fn test_event_sort() { &room_id(), &power_events, &mut events, - &store, &auth_chain, ); @@ -55,7 +53,6 @@ fn test_event_sort() { &sorted_power_events, &BTreeMap::new(), // unconflicted events &mut events, - &store, ) .expect("iterative auth check failed on resolved events"); @@ -71,7 +68,6 @@ fn test_event_sort() { &events_to_sort, power_level, &mut events, - &store, ); assert_eq!( diff --git a/tests/res_with_auth_ids.rs b/tests/res_with_auth_ids.rs index 627750e2..169714e4 100644 --- a/tests/res_with_auth_ids.rs +++ b/tests/res_with_auth_ids.rs @@ -7,7 +7,7 @@ use ruma::{ identifiers::{EventId, RoomVersionId}, }; use serde_json::json; -use state_res::{StateMap, StateResolution}; +use state_res::{EventMap, StateMap, StateResolution, StateStore}; mod utils; use utils::{ @@ -36,46 +36,6 @@ fn ban_with_auth_chains() { ); } -// Sanity check that the store is able to fetch auth chain and such -#[test] -fn base_with_auth_chains() { - let store = TestStore(INITIAL_EVENTS()); - - let mut ev_map = state_res::EventMap::default(); - let resolved: BTreeMap<_, EventId> = match StateResolution::resolve( - &room_id(), - &RoomVersionId::Version6, - &[], - &mut ev_map, - &store, - ) { - Ok(state) => state, - Err(e) => panic!("{}", e), - }; - - let resolved = resolved - .values() - .cloned() - .chain(INITIAL_EVENTS().values().map(|e| e.event_id().clone())) - .collect::>(); - - let expected = vec![ - "$CREATE:foo", - "$IJR:foo", - "$IPOWER:foo", - "$IMA:foo", - "$IMB:foo", - "$IMC:foo", - "START", - "END", - ]; - for id in expected.iter().map(|i| event_id(i)) { - // make sure our resolved events are equal to the expected list - assert!(resolved.iter().any(|eid| eid == &id), "{}", id) - } - assert_eq!(expected.len(), resolved.len()) -} - #[test] fn ban_with_auth_chains2() { let init = INITIAL_EVENTS(); @@ -111,13 +71,21 @@ fn ban_with_auth_chains2() { .map(|ev| ((ev.kind(), ev.state_key()), ev.event_id().clone())) .collect::>(); - let mut ev_map = state_res::EventMap::default(); - let resolved: StateMap = match StateResolution::resolve( + let mut ev_map: EventMap> = store.0.clone(); + let state_sets = vec![state_set_a, state_set_b]; + let resolved = match StateResolution::resolve::( &room_id(), - &RoomVersionId::Version6, - &[state_set_a, state_set_b], + &RoomVersionId::Version2, + &state_sets, + state_sets + .iter() + .map(|map| { + store + .auth_event_ids(&room_id(), &map.values().cloned().collect::>()) + .unwrap() + }) + .collect(), &mut ev_map, - &store, ) { Ok(state) => state, Err(e) => panic!("{}", e), diff --git a/tests/state_res.rs b/tests/state_res.rs index f85f7eec..9d72994d 100644 --- a/tests/state_res.rs +++ b/tests/state_res.rs @@ -6,7 +6,7 @@ use ruma::{ identifiers::{EventId, RoomVersionId}, }; use serde_json::json; -use state_res::{StateMap, StateResolution}; +use state_res::{StateMap, StateResolution, StateStore}; use tracing_subscriber as tracer; mod utils; @@ -265,13 +265,21 @@ fn test_event_map_none() { // build up the DAG let (state_at_bob, state_at_charlie, expected) = store.set_up(); - let mut ev_map = state_res::EventMap::default(); - let resolved = match StateResolution::resolve( + let mut ev_map: state_res::EventMap> = store.0.clone(); + let state_sets = vec![state_at_bob, state_at_charlie]; + let resolved = match StateResolution::resolve::( &room_id(), &RoomVersionId::Version2, - &[state_at_bob, state_at_charlie], + &state_sets, + state_sets + .iter() + .map(|map| { + store + .auth_event_ids(&room_id(), &map.values().cloned().collect::>()) + .unwrap() + }) + .collect(), &mut ev_map, - &store, ) { Ok(state) => state, Err(e) => panic!("{}", e), diff --git a/tests/utils.rs b/tests/utils.rs index bec72356..c3570ea6 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -114,8 +114,15 @@ pub fn do_check( &room_id(), &RoomVersionId::Version6, &state_sets, + state_sets + .iter() + .map(|map| { + store + .auth_event_ids(&room_id(), &map.values().cloned().collect::>()) + .unwrap() + }) + .collect(), &mut event_map, - &store, ); match resolved { Ok(state) => state, @@ -565,7 +572,9 @@ pub mod event { fn hashes(&self) -> &EventHash { self.hashes() } - fn signatures(&self) -> BTreeMap, BTreeMap> { + fn signatures( + &self, + ) -> BTreeMap, BTreeMap> { self.signatures() } fn unsigned(&self) -> &BTreeMap { @@ -678,7 +687,10 @@ pub mod event { } impl StateEvent { - pub fn from_id_value(id: EventId, json: serde_json::Value) -> Result { + pub fn from_id_value( + id: EventId, + json: serde_json::Value, + ) -> Result { Ok(Self::Full( id, Pdu::RoomV3Pdu(serde_json::from_value(json)?), @@ -806,7 +818,9 @@ pub mod event { pub fn prev_event_ids(&self) -> Vec { match self { Self::Full(_, ev) => match ev { - Pdu::RoomV1Pdu(ev) => ev.prev_events.iter().map(|(id, _)| id).cloned().collect(), + Pdu::RoomV1Pdu(ev) => { + ev.prev_events.iter().map(|(id, _)| id).cloned().collect() + } Pdu::RoomV3Pdu(ev) => ev.prev_events.clone(), }, } @@ -815,7 +829,9 @@ pub mod event { pub fn auth_events(&self) -> Vec { match self { Self::Full(_, ev) => match ev { - Pdu::RoomV1Pdu(ev) => ev.auth_events.iter().map(|(id, _)| id).cloned().collect(), + Pdu::RoomV1Pdu(ev) => { + ev.auth_events.iter().map(|(id, _)| id).cloned().collect() + } Pdu::RoomV3Pdu(ev) => ev.auth_events.to_vec(), }, } @@ -936,5 +952,4 @@ pub mod event { ) } } - -} \ No newline at end of file +}