Remove StateStore trait, caller must collect all events needed
This commit is contained in:
parent
f4772e0fcb
commit
47b19fdc15
@ -0,0 +1 @@
|
||||
|
@ -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<Arc<event::StateEvent>> = store.0.clone();
|
||||
let state_sets = vec![state_at_bob.clone(), state_at_charlie.clone()];
|
||||
let _ = match StateResolution::resolve::<event::StateEvent>(
|
||||
&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::<Vec<_>>())
|
||||
.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::<StateMap<_>>();
|
||||
|
||||
b.iter(|| {
|
||||
let _resolved = match StateResolution::resolve(
|
||||
let state_sets = vec![state_set_a.clone(), state_set_b.clone()];
|
||||
let _ = match StateResolution::resolve::<event::StateEvent>(
|
||||
&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::<Vec<_>>())
|
||||
.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<Box<ServerName>, BTreeMap<ruma::ServerSigningKeyId, String>> {
|
||||
fn signatures(
|
||||
&self,
|
||||
) -> BTreeMap<Box<ServerName>, BTreeMap<ruma::ServerSigningKeyId, String>> {
|
||||
self.signatures()
|
||||
}
|
||||
fn unsigned(&self) -> &BTreeMap<String, JsonValue> {
|
||||
@ -643,7 +661,10 @@ pub mod event {
|
||||
}
|
||||
|
||||
impl StateEvent {
|
||||
pub fn from_id_value(id: EventId, json: serde_json::Value) -> Result<Self, serde_json::Error> {
|
||||
pub fn from_id_value(
|
||||
id: EventId,
|
||||
json: serde_json::Value,
|
||||
) -> Result<Self, serde_json::Error> {
|
||||
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::<MemberEventContent>(event.content.clone())
|
||||
{
|
||||
if [MembershipState::Leave, MembershipState::Ban]
|
||||
@ -771,7 +793,9 @@ pub mod event {
|
||||
pub fn prev_event_ids(&self) -> Vec<EventId> {
|
||||
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<EventId> {
|
||||
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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<E: Event>(
|
||||
room_version: &RoomVersionId,
|
||||
incoming_event: &Arc<E>,
|
||||
|
169
src/lib.rs
169
src/lib.rs
@ -46,14 +46,13 @@ impl StateResolution {
|
||||
room_version: &RoomVersionId,
|
||||
incoming_event: Arc<E>,
|
||||
current_state: &StateMap<EventId>,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
event_map: &EventMap<Arc<E>>,
|
||||
) -> Result<bool> {
|
||||
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<E: Event>(
|
||||
room_id: &RoomId,
|
||||
room_version: &RoomVersionId,
|
||||
state_sets: &[StateMap<EventId>],
|
||||
auth_events: Vec<Vec<EventId>>,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> Result<StateMap<EventId>> {
|
||||
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::<Vec<_>>(),
|
||||
)
|
||||
.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::<Vec<_>>()
|
||||
);
|
||||
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<E: Event>(
|
||||
room_id: &RoomId,
|
||||
state_sets: &[StateMap<EventId>],
|
||||
store: &dyn StateStore<E>,
|
||||
pub fn get_auth_chain_diff(
|
||||
_room_id: &RoomId,
|
||||
auth_event_ids: &[Vec<EventId>],
|
||||
) -> Result<Vec<EventId>> {
|
||||
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::<BTreeSet<_>>();
|
||||
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::<Vec<_>>();
|
||||
|
||||
Ok(chains
|
||||
.iter()
|
||||
.map(|map| map.values().cloned().collect())
|
||||
.dedup()
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.flatten()
|
||||
.filter(|id| !common.contains(&id))
|
||||
.cloned()
|
||||
.collect::<BTreeSet<_>>()
|
||||
.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<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
auth_diff: &[EventId],
|
||||
) -> Vec<EventId> {
|
||||
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<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> 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<EventId>,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> Result<StateMap<EventId>> {
|
||||
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<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> Vec<EventId> {
|
||||
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<Arc<E>>,
|
||||
mainline_map: &EventMap<usize>,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> Result<usize> {
|
||||
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<EventId, Vec<EventId>>,
|
||||
event_id: &EventId,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
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<E: Event>(
|
||||
room_id: &RoomId,
|
||||
_room_id: &RoomId,
|
||||
ev_id: &EventId,
|
||||
event_map: &mut EventMap<Arc<E>>,
|
||||
store: &dyn StateStore<E>,
|
||||
) -> Option<Arc<E>> {
|
||||
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<Arc<E>>,
|
||||
) -> Result<Arc<E>> {
|
||||
event_map.get(ev_id).map_or_else(
|
||||
|| Err(Error::NotFound(format!("EventId: {:?} not found", ev_id))),
|
||||
|e| Ok(Arc::clone(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<E: Event> {
|
||||
/// Return a single event based on the EventId.
|
||||
fn get_event(&self, room_id: &RoomId, event_id: &EventId) -> Result<Arc<E>>;
|
||||
|
@ -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!(
|
||||
|
@ -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::<Vec<_>>();
|
||||
|
||||
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::<StateMap<_>>();
|
||||
|
||||
let mut ev_map = state_res::EventMap::default();
|
||||
let resolved: StateMap<EventId> = match StateResolution::resolve(
|
||||
let mut ev_map: EventMap<Arc<StateEvent>> = store.0.clone();
|
||||
let state_sets = vec![state_set_a, state_set_b];
|
||||
let resolved = match StateResolution::resolve::<StateEvent>(
|
||||
&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::<Vec<_>>())
|
||||
.unwrap()
|
||||
})
|
||||
.collect(),
|
||||
&mut ev_map,
|
||||
&store,
|
||||
) {
|
||||
Ok(state) => state,
|
||||
Err(e) => panic!("{}", e),
|
||||
|
@ -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<Arc<StateEvent>> = store.0.clone();
|
||||
let state_sets = vec![state_at_bob, state_at_charlie];
|
||||
let resolved = match StateResolution::resolve::<StateEvent>(
|
||||
&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::<Vec<_>>())
|
||||
.unwrap()
|
||||
})
|
||||
.collect(),
|
||||
&mut ev_map,
|
||||
&store,
|
||||
) {
|
||||
Ok(state) => state,
|
||||
Err(e) => panic!("{}", e),
|
||||
|
@ -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::<Vec<_>>())
|
||||
.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<Box<ServerName>, BTreeMap<ruma::ServerSigningKeyId, String>> {
|
||||
fn signatures(
|
||||
&self,
|
||||
) -> BTreeMap<Box<ServerName>, BTreeMap<ruma::ServerSigningKeyId, String>> {
|
||||
self.signatures()
|
||||
}
|
||||
fn unsigned(&self) -> &BTreeMap<String, JsonValue> {
|
||||
@ -678,7 +687,10 @@ pub mod event {
|
||||
}
|
||||
|
||||
impl StateEvent {
|
||||
pub fn from_id_value(id: EventId, json: serde_json::Value) -> Result<Self, serde_json::Error> {
|
||||
pub fn from_id_value(
|
||||
id: EventId,
|
||||
json: serde_json::Value,
|
||||
) -> Result<Self, serde_json::Error> {
|
||||
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<EventId> {
|
||||
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<EventId> {
|
||||
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 {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user