ruma_state_res/lib.rs
1#![doc(html_favicon_url = "https://ruma.dev/favicon.ico")]
2#![doc(html_logo_url = "https://ruma.dev/images/logo.png")]
3//! State resolution and checks on incoming PDUs according to the [Matrix](https://matrix.org/) specification.
4//!
5//! When creating or receiving a PDU (or event), a server must check whether it is valid and how it
6//! affects the room state. The purpose of this crate is to provide functions that solve that.
7//!
8//! # Checks performed on receipt of a PDU
9//!
10//! This crate used with [ruma-signatures] should allow to perform all the [necessary checks on
11//! receipt of a PDU].
12//!
13//! To respect the Matrix specification, the following functions should be called for a PDU:
14//!
15//! 1. [`check_pdu_format()`] - The event should be dropped on error.
16//! 2. [`ruma_signatures::verify_event()`] - The event should be dropped on error. The PDU should be
17//! redacted before checking the authorization rules if the result is `Verified::Signatures`.
18//! 3. [`check_state_independent_auth_rules()`] - The event should be rejected on error.
19//! 4. [`check_state_dependent_auth_rules()`] - This function must be called 3 times:
20//! 1. With the `auth_events` for the state, the event should be rejected on error.
21//! 2. With the state before the event, the event should be rejected on error.
22//! 3. With the current state of the room, the event should be "soft failed" on error.
23//!
24//! # Room State Resolution
25//!
26//! Because of the distributed nature of Matrix, homeservers might not receive all events in the
27//! same order, which might cause the room state to diverge temporarily between homeservers. The
28//! purpose of [state resolution] is to make sure that all homeservers arrive at the same room state
29//! given the same events.
30//!
31//! The [`resolve()`] function allows to do that. It takes an iterator of state maps and applies the
32//! proper state resolution algorithm for the current room version to output the map of events in
33//! the current room state.
34//!
35//! # Event helper types
36//!
37//! The types from [ruma-events] use strict deserialization rules according to their definition in
38//! the specification, which means that they also validate fields that are not checked when
39//! receiving a PDU. Since it is not appropriate for servers to reject an event that passes those
40//! checks, this crate provides helper types in the [`events`] module, built around the [`Event`]
41//! trait, to deserialize lazily a handful of fields from the most common state events. Since these
42//! are the same types used for checking the authorization rules, they are guaranteed to not perform
43//! extra validation on unvalidated fields.
44//!
45//! The types from ruma-events are still appropriate to be used to create a new event, or to
46//! validate an event received from a client.
47//!
48//! [ruma-signatures]: https://crates.io/crates/ruma-signatures
49//! [necessary checks on receipt of a PDU]: https://spec.matrix.org/latest/server-server-api/#checks-performed-on-receipt-of-a-pdu
50//! [ruma-events]: https://crates.io/crates/ruma-events
51
52#![warn(missing_docs)]
53
54mod error;
55mod event_auth;
56mod event_format;
57pub mod events;
58mod state_res;
59#[cfg(test)]
60mod test_utils;
61mod utils;
62
63pub use self::{
64 error::{Error, Result},
65 event_auth::{
66 auth_types_for_event, check_state_dependent_auth_rules, check_state_independent_auth_rules,
67 },
68 event_format::check_pdu_format,
69 events::Event,
70 state_res::{resolve, reverse_topological_power_sort, StateMap},
71};