document new state resolution algorithm

pull/1610/head
Hubert Chathi 6 years ago
parent 5f06694b6f
commit 9b94e588e6

@ -515,11 +515,136 @@ is at the top)::
Suppose E3 and E4 are both ``m.room.name`` events which set the name of the
room. What should the name of the room be at E5?
Servers should follow the following recursively-defined algorithm to determine
the room state at a given point on the DAG.
Servers should follow one of the following recursively-defined algorithms to
determine the room state at a given point on the DAG.
State resolution algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~
State resolution algorithm for version 2 rooms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The room state :math:`S'(E)` after an event :math:`E` is defined in terms of
the room state :math:`S(E)` before :math:`E`, and depends on whether
:math:`E` is a state event or a message event:
* If :math:`E` is a message event, then :math:`S'(E) = S(E)`.
* If :math:`E` is a state event, then :math:`S'(E)` is :math:`S(E)`, except
that its entry corresponding to :math:`E`'s ``event_type`` and ``state_key``
is replaced by :math:`E`'s ``event_id``.
The room state :math:`S(E)` before :math:`E` is the *resolution* of the set of
states :math:`\{ S'(E_1), S'(E_2), … \}` consisting of the states after each of
:math:`E`'s ``prev_event``\s :math:`\{ E_1, E_2, … \}`, where the resolution of
a set of states is given in the algorithm below.
Definitions
+++++++++++
The state resolution algorithm for version 2 rooms uses the following
definitions, given the set of room states :math:`\{ S_1, S_2, \ldots \}`:
Power events
A *power event* is a state event with type ``m.room.power_levels`` or
``m.room.join_rules``, or a state event with type ``m.room.member`` where the
``membership`` is ``leave`` or ``ban`` and the ``sender`` does not match the
``state_key``. The idea behind this is that power events are events that have
may remove someone's ability to do something in the room.
Unconflicted and conflicted state maps
The *unconflicted state map* is the state where the value of each key exists
and is the same in each state :math:`S_i`. The *conflicted state map* is the
set of all other state events. Note that the conflicted state map is a set of
events, rather than a map of ``(event_type, state_key)`` to ``event_id``.
Auth difference
The *auth difference* is calculated by first calculating the full auth chain
for each state :math:`S_i`, that is the union of the auth chains for each
event in :math:`S_i`, and then taking every event that doesn't appear in
every auth chain. If :math:`C_i` is the full auth chain of :math:`S_i`, then
the auth difference is :math:`\cup C_i - \cap C_i`.
Full conflicted set
The *full conflicted set* is the union of the conflicted state map and the
auth difference.
Reverse topological power ordering
The *reverse topological power ordering* of a set of events is the
lexicographically smallest topological ordering based on the DAG formed by
auth events. The reverse topological power ordering is ordered from earliest
event to latest. For comparing two topological orderings to determine which
is the lexicographically smallest, the following comparison relation on
events is used: for events :math:`x` and :math:`y`, :math:`x<y` if
1. :math:`x`'s sender has *greater* power level than :math:`y`'s sender,
when looking at their respective ``auth_event``\s; or
2. the senders have the same power level, but :math:`x`'s
``origin_server_ts`` is *less* than :math:`y`'s ``origin_server_ts``; or
3. the senders have the same power level and the events have the same
``origin_server_ts``, but :math:`x`'s ``event_id`` is *less* than
:math:`y`'s ``event_id``.
The reverse topological power ordering can be found by sorting the events
using Kahn's algorithm for topological sorting, and at each step selecting,
among all the candidate vertices, the smallest vertex using the above
comparison relation.
Mainline ordering
Given an ``m.room.power_levels`` event :math:`P`, the *mainline of* :math:`P`
is the list of events generated by starting with :math:`P` and recursively
taking the ``m.room.power_levels`` events from the ``auth_events``, ordered
such that :math:`P` is last. Given another event :math:`e`, the *closest
mainline event to* :math:`e` is the first event encountered in the mainline
when iteratively descending through the ``m.room.power_levels`` events in the
``auth_events`` starting at :math:`e`. If :math:`e` is not an
``m.room.power_levels`` event, and does not have an ``m.room.power_levels``
event in its ``auth_events`` (this happens if the :math:`e` is sent before
the first ``m.room.power_levels`` event), then the closest mainline event to
:math:`e` can be considered to be a dummy event that is before any other
event in the mainline of :math:`P` for the purposes of condition 1 below.
The *mainline ordering based on* :math:`P` of a set of events is the
ordering, from smallest to largest, using the following comparision relation
on events: for events :math:`x` and :math:`y`, :math:`x<y` if
1. the closest mainline event to :math:`x` appears *before* the closest
mainline event to :math:`y`; or
2. the closest mainline events are the same, but :math:`x`\'s
``origin_server_ts`` is *less* than :math:`y`\'s ``origin_server_ts``; or
3. the closest mainline events are the same and the events have the same
``origin_server_ts``, but :math:`x`\'s ``event_id`` is *less* than
:math:`y`\'s ``event_id``.
Iterative auth checks
The *iterative auth checks algorithm* takes as input an initial room state
and a sorted list of state events, and constructs a new room state by
iterating through the event list and applying the state event to the room
state if the state event is allowed by the `authorization rules`_. If the
state event is not allowed by the authorization rules, then the event is
ignored. If a ``(event_type, state_key)`` key that is required for checking
the authorization rules is not present in the state, then the appropriate
state event from the event's ``auth_events`` is used.
Algorithm
+++++++++
The *resolution* of a set of states is obtained as follows:
1. Take all *power events* and any events in their auth chains that appear in
the *full conflicted set* and order them by the *reverse topological power
ordering*.
2. Apply the *iterative auth checks algorithm* on the *unconflicted state map*
and the list of events from the previous step to get a partially resolved
state.
3. Take all remaining events that weren't picked in step 1 and order them by
the mainline ordering based on the power level in the partially resolved
state obtained in step 2.
4. Apply the *iterative auth checks algorithm* on the partial resolved
state and the list of events from the previous step.
5. Update the result by replacing any event with the event with the same key
from the *unconflicted state map*, if such an event exists, to get the final
resolved state.
State resolution algorithm for version 1 rooms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. WARNING::
This section documents the state resolution algorithm as implemented by

Loading…
Cancel
Save