diff --git a/changelogs/room_versions/newsfragments/1107.clarification b/changelogs/room_versions/newsfragments/1107.clarification new file mode 100644 index 000000000..79b31fef6 --- /dev/null +++ b/changelogs/room_versions/newsfragments/1107.clarification @@ -0,0 +1 @@ +For room versions 2 through 10: More explicitly define the mainline of a power event and the mainline ordering of other events. diff --git a/content/rooms/fragments/v2-state-res.md b/content/rooms/fragments/v2-state-res.md index e666d7f8c..1384c98fe 100644 --- a/content/rooms/fragments/v2-state-res.md +++ b/content/rooms/fragments/v2-state-res.md @@ -82,27 +82,43 @@ selecting, among all the candidate vertices, the smallest vertex using the above comparison relation. **Mainline ordering.** -Given an `m.room.power_levels` event *P*, the *mainline of* *P* is the -list of events generated by starting with *P* and recursively taking the -`m.room.power_levels` events from the `auth_events`, ordered such that -*P* is last. Given another event *e*, the *closest mainline event to* -*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 *e*. If no mainline event is encountered when iteratively -descending through the `m.room.power_levels` events, then the closest -mainline event to *e* can be considered to be a dummy event that is -before any other event in the mainline of *P* for the purposes of -condition 1 below. - -The *mainline ordering based on* *P* of a set of events is the ordering, +Let *P* = *P*0 be an `m.room.power_levels` event. +Starting with *i* = 0, repeatedly fetch *P**i*+1, the +`m.room.power_levels` event in the `auth_events` of *Pi*. +Increment *i* and repeat until *Pi* has no `m.room.power_levels` +event in its `auth_events`. +The *mainline of P*0 is the list of events + [*P*0 , *P*1, ... , *Pn*], +fetched in this way. + +Let *e* = *e0* be another event (possibly another +`m.room.power_levels` event). We can compute a similar list of events + [*e*1, ..., *em*], +where *e**j*+1 is the `m.room.power_levels` event in the +`auth_events` of *ej* and where *em* has no +`m.room.power_levels` event in its `auth_events`. (Note that the event we +started with, *e0*, is not included in this list. Also note that it +may be empty, because *e* may not cite an `m.room.power_levels` event in its +`auth_events` at all.) + +Now compare these two lists as follows. +* Find the smallest index *j* ≥ 1 for which *ej* belongs to the + mainline of *P*. +* If such a *j* exists, then *ej* = *Pi* for some unique + index *i* ≥ 0. Otherwise set *i* = ∞, where ∞ is a sentinel value greater + than any integer. +* In both cases, the *mainline position* of *e* is *i*. + +Given mainline positions calculated from *P*, the *mainline ordering based on* *P* of a set of events is the ordering, from smallest to largest, using the following comparison relation on events: for events *x* and *y*, *x* < *y* if -1. the closest mainline event to *x* appears *before* the closest - mainline event to *y*; or -2. the closest mainline events are the same, but *x*'s +1. the mainline position of *x* is **greater** than + the mainline position of *y* (i.e. the auth chain of + *x* is based on an earlier event in the mainline than *y*); or +2. the mainline positions of the events are the same, but *x*'s `origin_server_ts` is *less* than *y*'s `origin_server_ts`; or -3. the closest mainline events are the same and the events have the +3. the mainline positions of the events are the same and the events have the same `origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s `event_id`.