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//! # Supported room versions
9//!
10//! Only room versions enforcing [canonical JSON] (introduced with [room version 6]) are supported.
11//!
12//! Room versions 1 through 5 are supported on a best effort basis:
13//!
14//! * The authorization rules should work for most events but some unconventional JSON encoding of
15//! values might fail to deserialize while still considered to be valid by other implementations.
16//! * The [state resolution algorithm from room version 1][state-res-v1] is not implemented.
17//!
18//! Homeservers using this crate **should not** advertise support for those room versions.
19//!
20//! # Checks performed on receipt of a PDU
21//!
22//! This crate used with [ruma-signatures] should allow to perform all the [necessary checks on
23//! receipt of a PDU].
24//!
25//! To respect the Matrix specification, the following functions should be called for a PDU:
26//!
27//! 1. [`check_pdu_format()`] - The event should be dropped on error.
28//! 2. [`ruma_signatures::verify_event()`] - The event should be dropped on error. The PDU should be
29//! redacted before checking the authorization rules if the result is `Verified::Signatures`.
30//! 3. [`check_state_independent_auth_rules()`] - The event should be rejected on error.
31//! 4. [`check_state_dependent_auth_rules()`] - This function must be called 3 times:
32//! 1. With the `auth_events` for the state, the event should be rejected on error.
33//! 2. With the state before the event, the event should be rejected on error.
34//! 3. With the current state of the room, the event should be "soft failed" on error.
35//!
36//! # Room State Resolution
37//!
38//! Because of the distributed nature of Matrix, homeservers might not receive all events in the
39//! same order, which might cause the room state to diverge temporarily between homeservers. The
40//! purpose of [state resolution] is to make sure that all homeservers arrive at the same room state
41//! given the same events.
42//!
43//! The [`resolve()`] function allows to do that. It takes an iterator of state maps and applies the
44//! proper state resolution algorithm for the current room version to output the map of events in
45//! the current room state.
46//!
47//! # Event helper types
48//!
49//! The types from [ruma-events] use strict deserialization rules according to their definition in
50//! the specification, which means that they also validate fields that are not checked when
51//! receiving a PDU. Since it is not appropriate for servers to reject an event that passes those
52//! checks, this crate provides helper types in the [`events`] module, built around the [`Event`]
53//! trait, to deserialize lazily a handful of fields from the most common state events. Since these
54//! are the same types used for checking the authorization rules, they are guaranteed to not perform
55//! extra validation on unvalidated fields.
56//!
57//! The types from ruma-events are still appropriate to be used to create a new event, or to
58//! validate an event received from a client.
59//!
60//! [canonical JSON]: https://spec.matrix.org/v1.18/appendices/#canonical-json
61//! [room version 6]: https://spec.matrix.org/v1.18/rooms/v6/
62//! [state-res-v1]: https://spec.matrix.org/v1.18/rooms/v1/#state-resolution
63//! [ruma-signatures]: https://crates.io/crates/ruma-signatures
64//! [necessary checks on receipt of a PDU]: https://spec.matrix.org/v1.18/server-server-api/#checks-performed-on-receipt-of-a-pdu
65//! [ruma-events]: https://crates.io/crates/ruma-events
66
67#![warn(missing_docs)]
68
69mod error;
70mod event_auth;
71mod event_format;
72pub mod events;
73mod state_res;
74#[cfg(any(test, feature = "__criterion"))]
75#[doc(hidden)]
76pub mod test_utils;
77mod utils;
78
79pub use self::{
80 error::{Error, Result},
81 event_auth::{
82 auth_types_for_event, check_state_dependent_auth_rules, check_state_independent_auth_rules,
83 },
84 event_format::check_pdu_format,
85 events::Event,
86 state_res::{StateMap, resolve, reverse_topological_power_sort},
87};