From bbd909d09f6f0d1b91f66655ed815a5726f3e2ab Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 20 Jul 2018 17:19:32 +0100 Subject: [PATCH 1/8] State Resolution: Reloaded MSC --- proposals/0000-state-resolution.md | 447 +++++++++++++++++++++++++++++ proposals/images/state-res.png | Bin 0 -> 61233 bytes 2 files changed, 447 insertions(+) create mode 100644 proposals/0000-state-resolution.md create mode 100644 proposals/images/state-res.png diff --git a/proposals/0000-state-resolution.md b/proposals/0000-state-resolution.md new file mode 100644 index 000000000..66d1eb38c --- /dev/null +++ b/proposals/0000-state-resolution.md @@ -0,0 +1,447 @@ +# State Resolution: Reloaded + + +Thoughts on the next iteration of the state resolution algorithm that aims to mitigate currently known attacks + + +# Background + +The state of a room at an event is a mapping from key to event, which is built +up and updated by sending state events into the room. All the information about +the room is encoded in the state, from metadata like the name and topic to +membership of the room to security policies like bans and join rules. + +It is therefore important that─wherever possible─the view of the state of the +room is consistent across all servers. If different servers have different +views of the state then it can lead to the room bifurcating, due to differing +ideas on who is in the room, who is allowed to talk, etc. + +The difficulty comes when the room DAG forks and then merges again (which can +happen naturally if two servers send events at the same time or when a network +partition is resolved). The state after the merge has to be resolved from the +state of the two branches: the algorithm to resolve this is called the _state +resolution algorithm_. + +Since the result of state resolution must be consistent across servers, the +information that the algorithm can use is strictly limited to the information +that will always be available to all servers (including future servers that may +not even be in the room at that point) at any point in time where the +resolution needs to be calculated. In particular, this has the consequence that +the algorithm cannot use information from the room DAG, since servers are not +required to store events for any length of time. + +**As such, the state resolution algorithm is effectively a pure function from +sets of state to a single resolved set of state.** + +The final important property for state resolution is that it should not allow +malicious servers to avoid moderation action by forking and merging the room +DAG. For example, if a server gets banned and then forks the room before the +ban, any merge back should always ensure that the ban is still in the state. + + +# Current Algorithm + +The current state resolution is known to have some undesirable properties, +which can be summarized into two separate cases: + +1. Moderation evasion ─ where an attacker can avoid e.g. bans by forking and joining the room DAG in particular ways. +1. State resets ─ where a server (often innocently) sends an event that points to disparate parts of the graph, causing state resolution to pick old state rather than later versions. + +These have the following causes: + +1. Conflicting state must pass auth checks to be eligible to be picked, but the algorithm does not consider previous (superseded) state changes in a fork. For example, where Alice gives Bob power and then Bob gives Charlie power on one branch of a conflict, when the latter power level event is authed against the original power level (where Bob didn't have power), it fails. +1. The algorithm relies on the deprecated and untrustable depth parameter to try and ensure that the "most recent" state is picked. Without having a copy of the complete room DAG the algorithm doesn't know that e.g. one topic event came strictly after another in the DAG. For efficiency and storage reasons servers are not required (or expected) to store the whole room DAG. +1. The algorithm always accepts events where there are no conflicting alternatives in other forks. This means that if an admin changed the join rules to `private`, then new joins on forks based on parts of the DAG which predate that change would always be accepted without being authed against the join_rules event. + + +# Desirable Properties + +As well as the important properties listed in the "Background" section, there are also some other properties that would significantly improve the experience of end users, though not strictly essential. These include: + +* Banning and changing power levels should "do the right thing", i.e. end users shouldn't have to take extra steps to make the state resolution produce the "right" results. +* Minimise occurences of "state resets". Servers will sometimes point to disparate parts of the room DAG (due to a variety of reasons), which ideally should not result in changes in the state. +* Be efficient; state resolution can happen a lot on some large rooms. Ideally it would also support efficiently working on "state deltas" - i.e. the ability to calculate state resolution incrementally from snapshots rather than having to consider the full state of each fork each time a conflict is resolved + + +# Ideas for New Algorithm + + +## Auth Chain + +The _auth events_ of a given event is the set of events which justify why a +given event is allowed to be sent into a room (e.g. an m.room.create, an +m.room.power_levels and the sender's m.room.membership). The _auth chain_ of an +event is its auth events and their auth events, recursively. The auth chains of +a set of events in a given room form a DAG. + +"Auth events" are events that can appear as auth events of an event. These +include power levels, membership etc.[^1] + +Servers in a room are required to have the full auth chain for all events that +they have seen, and so the auth chain is available to be used by state +resolution algorithms. + + +## Unconflicted State + +The current algorithm defines the notion of "unconflicted state" to be all +entries that for each set of state either has the same event or no entry. All +unconflicted state entries are included in the resolved state. This is +problematic due to the fact that any new entries introduced on forks always +appear in the resolved state, regardless of if they would pass the checks +applied to conflicted state. + +The new algorithm could redefine "unconflicted state" to be all entries which +both exist and are the same in every state set (as opposed to previously where +the entry didn't need to exist in every state set). + + +## Replacing Depth + +Since depth of an event cannot be reliably calculated without possessing the +full DAG, and cannot be trusted when provided by other servers, it can not be +used in future versions of state resolution. A potential alternative, however, +is to use "origin_server_ts". While it cannot be relied on to be accurate─an +attacker can set it to arbitrary values─it has the advantage over depth that +end users can clearly see when a server is using incorrect values. (Note that +server clocks don't need to be particularly accurate for the ordering to still +be more useful than other arbitrary orderings). + +It can also be assumed that in most cases the origin_server_ts for a given +benign server will be mostly consistent. For example, if a server sends a join +and then a leave in the vast majority of cases the leave would have a greater +origin_server_ts. + +This makes "origin_server_ts" a good candidate to be used as a last resort to +order events if necessary, where otherwise a different arbitrary ordering would +be used. However, it's important that there is some other mechanism to ensure +that malicious servers can't abuse origin_server_ts to ensure their state +always gets picked during resolution (In the proposal below we use the auth DAG +ordering to override users who set state with malicious origin_server_ts.) + + +## Ordering and Authing + +Roughly, the current algorithm tries to ensure that moderation evasion doesn't +happen by ordering conflicted events by depth and (re)authing them +sequentially. The exact implementation has several issues, but the idea of +ensuring that state events from forks still need to pass auth subject to e.g. +bans and power level changes is a powerful one, as it reduces the utility of +maliciously forking. + +For that to work we need to ensure that there is a suitable ordering that puts +e.g. bans before events sent in other forks. (However events can point to old +parts of the DAG, for a variety of reasons, and ideally in that case the +resolved state would closely match the recent state). + + +## Power Level Ordering + +Actions that malicious servers would try and evade are actions that require +greater power levels to perform, for example banning, reducing power level, +etc. We define "power events" as events that have the potential to remove the +ability of another user to do something.[^2] (Note that they are a subset of +auth events.) + +In all these cases it is desirable for those privileged actions to take +precedence over events in other forks. This can be achieved by first +considering "power events", and requiring the remaining events to pass auth +based on them. + + +## Mainline + +An issue caused by servers not storing the full room DAG is that one can't tell +how two arbitrary events are ordered. The auth chain gives a partial ordering +to certain events, though far from complete; however, all events do contain a +reference to the current power levels in their auth events. As such if two +state events reference two different power levels events, and one power levels' +auth chain references the other, then there is a strong likelihood that the +event referencing the latter power level came after the other event. + +A "mainline" is a list of power levels events created if you pick a particular +power levels event (usually the current resolved power level) and recursively +follow each power level referenced in auth_events back to the first power level +event. + +The mainline can then be used to induce an ordering on events by looking at +where the power level referenced in their auth_events is in the mainline (or +recursively following the chain of power level events back until one is found +that appears in the mainline). This effectively partitions the room into +epochs, where a new epoch is started whenever a new power level is sent. + +If this mainline ordering is combined with ordering by origin_server_ts, then +it gives an ordering that is correct for servers that don't lie about the time, +while giving a mechanism that can be used to deal if a server lied (by room +admins starting a new epoch). + +The natural course of action for a room admin to take when noticing a +user/server is misbehaving is to ban them from the room, rather than changing +the power levels. It would therefore be useful if banning a user or server +started a new epoch as well. This would require being able to create a mainline +that includes power level events and bans[^3], which would suggest that power +level and ban events would need to point to the latest ban event as well. (This +would be significantly easier if we maintained a list of bans in a single +event, however there is concern that would limit the number of possible bans in +a room.) + + +# Proposed Algorithm + +First we define: + +* **"State sets"** are the sets of state that the resolution algorithm tries to resolve, i.e. the inputs to the algorithm. +* **"Power events"** are events that have the potential to remove the ability of another user to do something. These are power levels, join rules, bans and kicks. +* The **"unconflicted state map"** is the state where the value of each key exists and is the same in every state set. The** "conflicted state map"** is everything else. (Note that this is subtly different to the definition used in the existing algorithm, which considered the merge of a present event with an absent event to be unconflicted rather than conflicted) +* The "**auth difference"** is calculated by first calculating the full auth chain for each state set and taking every event that doesn't appear in every auth chain. +* The **"full conflicted set"** is the union of the conflicted state map and auth difference. +* The **"reverse topological power ordering"**[^4] of a set of events is an ordering of the given events, plus any events in their auth chains that appear in the auth difference, ordered such that x < y if: + + 1. x is in the auth chain of y, or if + 1. x's sender has a greater power level than y (calculated by looking at their respective auth events, or if + 1. x's origin_server_ts is less than y's, or if + 1. x's event_id is lexicographically less than y's + + This is also known as a lexicographical topological sort. + +* The **"mainline ordering"** based on a power level event P of a set of events is calculated as follows: + 1. Generate the list of power levels starting at P and recursively take the power level from its auth events. This list is called the mainline, ordered such that P is last. + 1. We say the "closest mainline event" of an event is the first power level event encountered in mainline when iteratively descending through the power level events in the auth events. + 1. Order the set of events such that x < y if: + 1. The closest mainline event of x appears strictly before the closest of y in the mainline list, or if + 1. x's origin_server_ts is less than y's, or if + 1. x's event_id lexicographically sorts before y's +* The **"iterative auth checks"** algorithm is where given a sorted list of events, the auth check algorithm is applied to each event in turn. The state events used to auth are built up from previous events that passed the auth checks, starting from a base set of state. If a required auth key doesn't exist in the state, then the one in the event's auth_events is used. (See _Variations_ and _Attack Vectors_ below). + +The algorithm proceeds 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._ +1. Apply the _iterative auth checks_ algorithm based on the unconflicted state map to get a partial set of resolved state. +1. 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. +1. Apply the _iterative auth checks algorithm_ based on the partial resolved state. +1. Update the result with the _unconflicted state_ to get the final resolved state[^5]. +(_Note_: this is different from the current algorithm, which considered different event types at distinct stages) + +An example python implementation can be found on github +[here](https://github.com/matrix-org/matrix-test-state-resolution-ideas). + +Note that this works best if we also change which events to include as an +event's auth_events. See the "Auth Events" section below. + + +## Discussion + +Essentially, the algorithm works by producing a sorted list of all conflicted +events (and differences in auth chains), and applies the auth checks one by +one, building up the state as it goes. The list is produced in two parts: first +the power events and auth dependencies are ordered by power level of the +senders and resolved, then the remaining events are ordered using the +"mainline" of the resolved power levels and then resolved to produce the final +resolved state. + +(This is equivalent to linearizing the full conflicted set of events and +reapplying the usual state updates and auth rules.) + + +### Variations + +There are multiple options for what to use as the base state for _iterative +auth checks_ algorithm; while it needs to be some variation of auth events and +unconflicted events, it is unclear exactly which combination is best (and least +manipulatable by malicious servers). + +Care has to be taken if we want to ensure that old auth events that appear in +the _auth chain difference_ can't supercede unconflicted state entries. + +Due to auth chain differences being added to the resolved states during +_iterative auth checks_, we therefore need to re-apply the unconflicted state +at the end to ensure that they appear in the final resolved state. This feels +like an odd fudge that shouldn't be necessary, and may point to a flaw in the +proposed algorithm. + + +### State Resets + +The proposed algorithm still has some potentially unexpected behaviour. + +One example of this is when Alice sets a topic and then gets banned. If an +event gets created (potentially much later) that points to both before and +after the topic and ban then the proposed algorithm will resolve and apply the +ban before resolving the topic, causing the topic to be denied and dropped from +the resolved state. This will result in no topic being set in the resolved +state. + + +### Auth Events + +The algorithm relies heavily on the ordering induced by the auth chain DAG. + +There are two types of auth events (not necessarily distinct): + +* Those that give authorization to do something +* Those that revoke authorization to do something. + +For example, invites/joins are in the former category, leaves/kicks/bans are in +the latter and power levels are both. + +Assuming[^6] revocations always point to (i.e., have in their auth chain) the +authorization event that they are revoking, and authorization events point to +revocations that they are superseding, then the algorithm will ensure that the +authorization events are applied in order (so generally the "latest" +authorization state would win). + +This helps ensure that e.g. an invite cannot be reused after a leave/kick, +since the leave (revocation) would have the invite in their auth chain. + +This idea also relies on revocations replacing the state that granted +authorization to do an action (and vice versa). For example, in the current +model bans (basically) revoke the ability for a particular user from being able +to join. If the user later gets unbanned and then rejoins, the join would point +to the join rules as the authorization that lets them join, but would not +(necessarily) point to the unban. This has the effect that if a state +resolution happened between the new join and the ban, the unban would not be +included in the resolution and so the join would be rejected. + +The changes to the current model that would be required to make the above +assumptions true would be, for example: + + + +1. By default permissions are closed. +1. Bans would need to be a list in either the join rules event or a separate event type which all membership events pointed to. +1. Bans would only revoke the ability to join, not automatically remove users from the room. +1. Change the defaults of join_rules to be closed by default + + +### Efficiency and Delta State Resolution + +The current (unoptimised) implementation of the algorithm is 10x slower than +the current algorithm, based on a single, large test case. While hopefully some +optimisations can be made, the ability to [incrementally calculate state +resolution via deltas](https://github.com/matrix-org/synapse/pull/3122) will +also mitigate some of the slow down. + +Another aspect that should be considered is the amount of data that is required +to perform the resolution. The current algorithm only requires the events for +the conflicted set, plus the events from the unconflicted set needed to auth +them. The proposed algorithm also requires the events in the auth chain +difference (calculating the auth chain difference may also require more data to +calculate). + +Delta state resolution is where if you have, say, two state sets and their +resolution, then you can use that result to work out the new resolution where +there has been a small change to the state sets. For the proposed algorithm, if +the following properties hold true then the result can be found by simply +applying steps 3 and 4 to the state deltas. The properties are: + + + +1. The delta contains no power events +1. The origin_server_ts of all events in state delta are strictly greater than those in the previous state sets +1. Any event that has been removed must not have been used to auth subsequent events (e.g. if we replaced a member event and that user had also set a topic) + +These properties will likely hold true for most state updates that happen in a +room, allowing servers to use this more efficient algorithm the majority of the +time. + + +### Full DAG + +It's worth noting that if the algorithm had access to the full room DAG that it +would really only help by ensuring that the ordering in "reverse topological +ordering" and "mainline ordering" respected the ordering induced by the DAG. + +This would help, e.g., ensure the latest topic was always picked rather than +rely on origin_server_ts and mainline. As well as obviate the need to maintain +a separate auth chain, and the difficulties that entails (like having to +reapply the unconflicted state at the end). + + +### Attack Vectors + +The main potential attack vector that needs to be considered is in the +_iterative auth checks_ algorithm, and whether an attacker could make use of +the fact that it's based on the unconflicted state and/or auth events of the +event. + + +# Appendix + +The following is an example room DAG, where time flows down the page. We shall +work through resolving the state at both _Message 2_ and _Message 3_. + + +![alt_text](images/state-res.png) + + +(Note that green circles are events sent by Alice, blue circles sent by Bob and +black arrows point to previous events. The red arrows are the mainline computed +during resolution.) + +First we resolve the state at _Message 2_. The conflicted event types are the +power levels and topics, and since the auth chains are the same for both state +sets the auth difference is the empty set. + +Step 1: The _full conflicted set_ are the events _P2, P3, Topic 2 _and _Topic +3_, of which _P2_ and _P3_ are the only power events. Since Alice (the room +creator) has a greater power level than Bob (and neither _P2 _and _P3_ appear +in each other's auth chain), the reverse topological ordering is: [_P2, P3_]. + +Step 2: Now we apply the auth rules iteratively, _P2_ trivially passes based on +the unconflicted state, but _P3_ does not pass since after _P2_ Bob no longer +has sufficient power to set state. This results in the power levels resolving +to _P2_. + +Step 3: Now we work out the mainline based on P2, which is coloured in red on +the diagram. We use the mainline to order _Topic 2_ and _Topic 3_. _Topic 2_ +points to_ P1_, while the closest mainline to _Topic 3_ is also _P1_. We then +order based on the _origin_server_ts_ of the two events, let's assume that +gives us: [_Topic 2_, _Topic 3_]. + +Step 4: Iteratively applying the auth rules results in _Topic 2_ being allowed, +but _Topic 3 _being denied (since Bob doesn't have power to set state anymore), +so the topic is resolved to _Topic 2_. + +This gives the resolved state at _Message 2_ to be _P2 _and _Topic 2_. (This is +actually the same result as the existing algorithm gives) + +Now let's look at the state at _Message 3_. + +Step 1: The full conflicted set are simple: _Topic 2_ and _Topic 4_. There are +no conflicted power events. + +Step 2: N/A + +Step 3: _Topic 2_ points to _P1_ in the mainline, and _Topic 4_ points to _P2_ +in its auth events. Since _P2_ comes after _P1_ in the mainline, this gives an +ordering of [_Topic 2, Topic 4_]. + +Step 4: Iteratively applying the auth rules results in both topics passing the +auth checks, and so the last topic, _Topic 4_, is chosen. + +This gives the resolved state at _Message 3_ to be _Topic 4_. + + +## Notes + +[^1]: + In the current room protocol these are: the create event, power levels, membership, join rules and third party invites. See the [spec](https://matrix.org/docs/spec/server_server/unstable.html#pdu-fields). + +[^2]: + In the current protocol these are: power levels, kicks, bans and join rules. + +[^3]: + Future room versions may have a concept of server ban event that works like existing bans, which would also be included + +[^4]: + The topology being considered here is the auth chain DAG, rather than the room DAG, so this ordering is only applicable to events which appear in the auth chain DAG. + +[^5]: + We do this so that, if we receive events with misleading auth_events, this ensures that the unconflicted state at least is correct. + +[^6]: + This isn't true in the current protocol + + + diff --git a/proposals/images/state-res.png b/proposals/images/state-res.png new file mode 100644 index 0000000000000000000000000000000000000000..573d1927afa216cd3a59e0d8e015aa300a30c295 GIT binary patch literal 61233 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�~ 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 literal 0 HcmV?d00001 From 4f97b80dccf9413b362f53d75cf85836b44bce19 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 20 Jul 2018 23:35:54 +0100 Subject: [PATCH 2/8] fix MD --- proposals/0000-state-resolution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0000-state-resolution.md b/proposals/0000-state-resolution.md index 66d1eb38c..78d4059b2 100644 --- a/proposals/0000-state-resolution.md +++ b/proposals/0000-state-resolution.md @@ -192,7 +192,7 @@ First we define: * **"State sets"** are the sets of state that the resolution algorithm tries to resolve, i.e. the inputs to the algorithm. * **"Power events"** are events that have the potential to remove the ability of another user to do something. These are power levels, join rules, bans and kicks. -* The **"unconflicted state map"** is the state where the value of each key exists and is the same in every state set. The** "conflicted state map"** is everything else. (Note that this is subtly different to the definition used in the existing algorithm, which considered the merge of a present event with an absent event to be unconflicted rather than conflicted) +* The **"unconflicted state map"** is the state where the value of each key exists and is the same in every state set. The **"conflicted state map"** is everything else. (Note that this is subtly different to the definition used in the existing algorithm, which considered the merge of a present event with an absent event to be unconflicted rather than conflicted) * The "**auth difference"** is calculated by first calculating the full auth chain for each state set and taking every event that doesn't appear in every auth chain. * The **"full conflicted set"** is the union of the conflicted state map and auth difference. * The **"reverse topological power ordering"**[^4] of a set of events is an ordering of the given events, plus any events in their auth chains that appear in the auth difference, ordered such that x < y if: From 3f891681ece09119781fa7222578eb1095ba9118 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Wed, 1 Aug 2018 14:12:46 +0100 Subject: [PATCH 3/8] Move proposal to have MSC number prefix --- proposals/{0000-state-resolution.md => 1442-state-resolution.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{0000-state-resolution.md => 1442-state-resolution.md} (100%) diff --git a/proposals/0000-state-resolution.md b/proposals/1442-state-resolution.md similarity index 100% rename from proposals/0000-state-resolution.md rename to proposals/1442-state-resolution.md From 67757a30274da1aec27dadb60759de729337c77a Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 2 Aug 2018 13:48:44 +0100 Subject: [PATCH 4/8] Wrap lines --- proposals/1442-state-resolution.md | 174 +++++++++++++++++++---------- 1 file changed, 118 insertions(+), 56 deletions(-) diff --git a/proposals/1442-state-resolution.md b/proposals/1442-state-resolution.md index 78d4059b2..4dd0fe7c0 100644 --- a/proposals/1442-state-resolution.md +++ b/proposals/1442-state-resolution.md @@ -1,7 +1,8 @@ # State Resolution: Reloaded -Thoughts on the next iteration of the state resolution algorithm that aims to mitigate currently known attacks +Thoughts on the next iteration of the state resolution algorithm that aims to +mitigate currently known attacks # Background @@ -44,23 +45,48 @@ ban, any merge back should always ensure that the ban is still in the state. The current state resolution is known to have some undesirable properties, which can be summarized into two separate cases: -1. Moderation evasion ─ where an attacker can avoid e.g. bans by forking and joining the room DAG in particular ways. -1. State resets ─ where a server (often innocently) sends an event that points to disparate parts of the graph, causing state resolution to pick old state rather than later versions. +1. Moderation evasion ─ where an attacker can avoid e.g. bans by forking and + joining the room DAG in particular ways. +1. State resets ─ where a server (often innocently) sends an event that points + to disparate parts of the graph, causing state resolution to pick old state + rather than later versions. These have the following causes: -1. Conflicting state must pass auth checks to be eligible to be picked, but the algorithm does not consider previous (superseded) state changes in a fork. For example, where Alice gives Bob power and then Bob gives Charlie power on one branch of a conflict, when the latter power level event is authed against the original power level (where Bob didn't have power), it fails. -1. The algorithm relies on the deprecated and untrustable depth parameter to try and ensure that the "most recent" state is picked. Without having a copy of the complete room DAG the algorithm doesn't know that e.g. one topic event came strictly after another in the DAG. For efficiency and storage reasons servers are not required (or expected) to store the whole room DAG. -1. The algorithm always accepts events where there are no conflicting alternatives in other forks. This means that if an admin changed the join rules to `private`, then new joins on forks based on parts of the DAG which predate that change would always be accepted without being authed against the join_rules event. +1. Conflicting state must pass auth checks to be eligible to be picked, but the + algorithm does not consider previous (superseded) state changes in a fork. + For example, where Alice gives Bob power and then Bob gives Charlie power on + one branch of a conflict, when the latter power level event is authed + against the original power level (where Bob didn't have power), it fails. +1. The algorithm relies on the deprecated and untrustable depth parameter to + try and ensure that the "most recent" state is picked. Without having a copy + of the complete room DAG the algorithm doesn't know that e.g. one topic + event came strictly after another in the DAG. For efficiency and storage + reasons servers are not required (or expected) to store the whole room DAG. +1. The algorithm always accepts events where there are no conflicting + alternatives in other forks. This means that if an admin changed the join + rules to `private`, then new joins on forks based on parts of the DAG which + predate that change would always be accepted without being authed against + the join_rules event. # Desirable Properties -As well as the important properties listed in the "Background" section, there are also some other properties that would significantly improve the experience of end users, though not strictly essential. These include: +As well as the important properties listed in the "Background" section, there +are also some other properties that would significantly improve the experience +of end users, though not strictly essential. These include: -* Banning and changing power levels should "do the right thing", i.e. end users shouldn't have to take extra steps to make the state resolution produce the "right" results. -* Minimise occurences of "state resets". Servers will sometimes point to disparate parts of the room DAG (due to a variety of reasons), which ideally should not result in changes in the state. -* Be efficient; state resolution can happen a lot on some large rooms. Ideally it would also support efficiently working on "state deltas" - i.e. the ability to calculate state resolution incrementally from snapshots rather than having to consider the full state of each fork each time a conflict is resolved +* Banning and changing power levels should "do the right thing", i.e. end + users shouldn't have to take extra steps to make the state resolution + produce the "right" results. +* Minimise occurences of "state resets". Servers will sometimes point to + disparate parts of the room DAG (due to a variety of reasons), which ideally + should not result in changes in the state. +* Be efficient; state resolution can happen a lot on some large rooms. Ideally + it would also support efficiently working on "state deltas" - i.e. the + ability to calculate state resolution incrementally from snapshots rather + than having to consider the full state of each fork each time a conflict is + resolved # Ideas for New Algorithm @@ -132,7 +158,7 @@ maliciously forking. For that to work we need to ensure that there is a suitable ordering that puts e.g. bans before events sent in other forks. (However events can point to old parts of the DAG, for a variety of reasons, and ideally in that case the -resolved state would closely match the recent state). +resolved state would closely match the recent state). ## Power Level Ordering @@ -190,38 +216,69 @@ a room.) First we define: -* **"State sets"** are the sets of state that the resolution algorithm tries to resolve, i.e. the inputs to the algorithm. -* **"Power events"** are events that have the potential to remove the ability of another user to do something. These are power levels, join rules, bans and kicks. -* The **"unconflicted state map"** is the state where the value of each key exists and is the same in every state set. The **"conflicted state map"** is everything else. (Note that this is subtly different to the definition used in the existing algorithm, which considered the merge of a present event with an absent event to be unconflicted rather than conflicted) -* The "**auth difference"** is calculated by first calculating the full auth chain for each state set and taking every event that doesn't appear in every auth chain. -* The **"full conflicted set"** is the union of the conflicted state map and auth difference. -* The **"reverse topological power ordering"**[^4] of a set of events is an ordering of the given events, plus any events in their auth chains that appear in the auth difference, ordered such that x < y if: +* **"State sets"** are the sets of state that the resolution algorithm tries + to resolve, i.e. the inputs to the algorithm. +* **"Power events"** are events that have the potential to remove the ability + of another user to do something. These are power levels, join rules, bans + and kicks. +* The **"unconflicted state map"** is the state where the value of each key + exists and is the same in every state set. The **"conflicted state map"** is + everything else. (Note that this is subtly different to the definition used + in the existing algorithm, which considered the merge of a present event + with an absent event to be unconflicted rather than conflicted) +* The "**auth difference"** is calculated by first calculating the full auth + chain for each state set and taking every event that doesn't appear in every + auth chain. +* The **"full conflicted set"** is the union of the conflicted state map and + auth difference. +* The **"reverse topological power ordering"**[^4] of a set of events is an + ordering of the given events, plus any events in their auth chains that + appear in the auth difference, ordered such that x < y if: 1. x is in the auth chain of y, or if - 1. x's sender has a greater power level than y (calculated by looking at their respective auth events, or if - 1. x's origin_server_ts is less than y's, or if - 1. x's event_id is lexicographically less than y's + 2. x's sender has a greater power level than y (calculated by looking at + their respective auth events, or if + 3. x's origin_server_ts is less than y's, or if + 4. x's event_id is lexicographically less than y's This is also known as a lexicographical topological sort. -* The **"mainline ordering"** based on a power level event P of a set of events is calculated as follows: - 1. Generate the list of power levels starting at P and recursively take the power level from its auth events. This list is called the mainline, ordered such that P is last. - 1. We say the "closest mainline event" of an event is the first power level event encountered in mainline when iteratively descending through the power level events in the auth events. +* The **"mainline ordering"** based on a power level event P of a set of + events is calculated as follows: + 1. Generate the list of power levels starting at P and recursively take the + power level from its auth events. This list is called the mainline, + ordered such that P is last. + 1. We say the "closest mainline event" of an event is the first power level + event encountered in mainline when iteratively descending through the + power level events in the auth events. 1. Order the set of events such that x < y if: - 1. The closest mainline event of x appears strictly before the closest of y in the mainline list, or if + 1. The closest mainline event of x appears strictly before the closest + of y in the mainline list, or if 1. x's origin_server_ts is less than y's, or if 1. x's event_id lexicographically sorts before y's -* The **"iterative auth checks"** algorithm is where given a sorted list of events, the auth check algorithm is applied to each event in turn. The state events used to auth are built up from previous events that passed the auth checks, starting from a base set of state. If a required auth key doesn't exist in the state, then the one in the event's auth_events is used. (See _Variations_ and _Attack Vectors_ below). +* The **"iterative auth checks"** algorithm is where given a sorted list of + events, the auth check algorithm is applied to each event in turn. The state + events used to auth are built up from previous events that passed the auth + checks, starting from a base set of state. If a required auth key doesn't + exist in the state, then the one in the event's auth_events is used. (See + _Variations_ and _Attack Vectors_ below). The algorithm proceeds 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._ -1. Apply the _iterative auth checks_ algorithm based on the unconflicted state map to get a partial set of resolved state. -1. 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. -1. Apply the _iterative auth checks algorithm_ based on the partial resolved state. -1. Update the result with the _unconflicted state_ to get the final resolved state[^5]. -(_Note_: this is different from the current algorithm, which considered different event types at distinct stages) +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._ +1. Apply the _iterative auth checks_ algorithm based on the unconflicted state + map to get a partial set of resolved state. +1. 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. +1. Apply the _iterative auth checks algorithm_ based on the partial resolved + state. +1. Update the result with the _unconflicted state_ to get the final resolved + state[^5]. (_Note_: this is different from the current algorithm, which + considered different event types at distinct stages) An example python implementation can be found on github [here](https://github.com/matrix-org/matrix-test-state-resolution-ideas). @@ -265,12 +322,11 @@ proposed algorithm. The proposed algorithm still has some potentially unexpected behaviour. -One example of this is when Alice sets a topic and then gets banned. If an -event gets created (potentially much later) that points to both before and -after the topic and ban then the proposed algorithm will resolve and apply the -ban before resolving the topic, causing the topic to be denied and dropped from -the resolved state. This will result in no topic being set in the resolved -state. +One example of this is when Alice sets a topic and then gets banned. If an event +gets created (potentially much later) that points to both before and after the +topic and ban then the proposed algorithm will resolve and apply the ban before +resolving the topic, causing the topic to be denied and dropped from the +resolved state. This will result in no topic being set in the resolved state. ### Auth Events @@ -299,9 +355,9 @@ authorization to do an action (and vice versa). For example, in the current model bans (basically) revoke the ability for a particular user from being able to join. If the user later gets unbanned and then rejoins, the join would point to the join rules as the authorization that lets them join, but would not -(necessarily) point to the unban. This has the effect that if a state -resolution happened between the new join and the ban, the unban would not be -included in the resolution and so the join would be rejected. +(necessarily) point to the unban. This has the effect that if a state resolution +happened between the new join and the ban, the unban would not be included in +the resolution and so the join would be rejected. The changes to the current model that would be required to make the above assumptions true would be, for example: @@ -309,8 +365,10 @@ assumptions true would be, for example: 1. By default permissions are closed. -1. Bans would need to be a list in either the join rules event or a separate event type which all membership events pointed to. -1. Bans would only revoke the ability to join, not automatically remove users from the room. +1. Bans would need to be a list in either the join rules event or a separate + event type which all membership events pointed to. +1. Bans would only revoke the ability to join, not automatically remove users + from the room. 1. Change the defaults of join_rules to be closed by default @@ -338,8 +396,11 @@ applying steps 3 and 4 to the state deltas. The properties are: 1. The delta contains no power events -1. The origin_server_ts of all events in state delta are strictly greater than those in the previous state sets -1. Any event that has been removed must not have been used to auth subsequent events (e.g. if we replaced a member event and that user had also set a topic) +1. The origin_server_ts of all events in state delta are strictly greater than + those in the previous state sets +1. Any event that has been removed must not have been used to auth subsequent + events (e.g. if we replaced a member event and that user had also set a + topic) These properties will likely hold true for most state updates that happen in a room, allowing servers to use this more efficient algorithm the majority of the @@ -425,23 +486,24 @@ This gives the resolved state at _Message 3_ to be _Topic 4_. ## Notes -[^1]: - In the current room protocol these are: the create event, power levels, membership, join rules and third party invites. See the [spec](https://matrix.org/docs/spec/server_server/unstable.html#pdu-fields). +[^1]: In the current room protocol these are: the create event, power levels, + membership, join rules and third party invites. See the + [spec](https://matrix.org/docs/spec/server_server/unstable.html#pdu-fields). -[^2]: - In the current protocol these are: power levels, kicks, bans and join rules. +[^2]: In the current protocol these are: power levels, kicks, bans and join + rules. -[^3]: - Future room versions may have a concept of server ban event that works like existing bans, which would also be included +[^3]: Future room versions may have a concept of server ban event that works + like existing bans, which would also be included -[^4]: - The topology being considered here is the auth chain DAG, rather than the room DAG, so this ordering is only applicable to events which appear in the auth chain DAG. +[^4]: The topology being considered here is the auth chain DAG, rather than the + room DAG, so this ordering is only applicable to events which appear in the + auth chain DAG. -[^5]: - We do this so that, if we receive events with misleading auth_events, this ensures that the unconflicted state at least is correct. +[^5]: We do this so that, if we receive events with misleading auth_events, this + ensures that the unconflicted state at least is correct. -[^6]: - This isn't true in the current protocol +[^6]: This isn't true in the current protocol From 9af5ecd080b5ebef7a952c4639774524ec83c7be Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 2 Aug 2018 14:24:25 +0100 Subject: [PATCH 5/8] Fixup definition of reverse topological power ordering --- proposals/1442-state-resolution.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/1442-state-resolution.md b/proposals/1442-state-resolution.md index 4dd0fe7c0..61ee4611b 100644 --- a/proposals/1442-state-resolution.md +++ b/proposals/1442-state-resolution.md @@ -233,13 +233,13 @@ First we define: auth difference. * The **"reverse topological power ordering"**[^4] of a set of events is an ordering of the given events, plus any events in their auth chains that - appear in the auth difference, ordered such that x < y if: + appear in the auth difference, topologically ordered by their auth chains + with ties broken such that x < y if: - 1. x is in the auth chain of y, or if - 2. x's sender has a greater power level than y (calculated by looking at + 1. x's sender has a greater power level than y (calculated by looking at their respective auth events, or if - 3. x's origin_server_ts is less than y's, or if - 4. x's event_id is lexicographically less than y's + 2. x's origin_server_ts is less than y's, or if + 3. x's event_id is lexicographically less than y's This is also known as a lexicographical topological sort. From fa70e3e486952c942573ac2ce066f1b2e92a3713 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 2 Aug 2018 14:42:36 +0100 Subject: [PATCH 6/8] Mention why auth difference are useful --- proposals/1442-state-resolution.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proposals/1442-state-resolution.md b/proposals/1442-state-resolution.md index 61ee4611b..ce36efa51 100644 --- a/proposals/1442-state-resolution.md +++ b/proposals/1442-state-resolution.md @@ -160,6 +160,14 @@ e.g. bans before events sent in other forks. (However events can point to old parts of the DAG, for a variety of reasons, and ideally in that case the resolved state would closely match the recent state). +Similarly care should be taken when multiple changes to e.g. power levels happen +in a fork. If Alice gives Bob power (A), then Bob gives Charlie power (B) and +then Charlie, say, changes the ban level (C). If you try and resolve two state +sets one of which has A and the other has C, C will not pass auth unless B is +also taken into account. This case can be handled if we also consider the +difference in auth chains between the two sets, which in the previous example +would include B. + ## Power Level Ordering @@ -362,8 +370,6 @@ the resolution and so the join would be rejected. The changes to the current model that would be required to make the above assumptions true would be, for example: - - 1. By default permissions are closed. 1. Bans would need to be a list in either the join rules event or a separate event type which all membership events pointed to. From 472f75d9a596b331f49fd0ab3c2a02ae80dfca9f Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 3 Aug 2018 12:18:41 +0100 Subject: [PATCH 7/8] Mention hotel california --- proposals/1442-state-resolution.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/1442-state-resolution.md b/proposals/1442-state-resolution.md index ce36efa51..9fd7da8a8 100644 --- a/proposals/1442-state-resolution.md +++ b/proposals/1442-state-resolution.md @@ -168,6 +168,14 @@ also taken into account. This case can be handled if we also consider the difference in auth chains between the two sets, which in the previous example would include B. +(This is also the root cause of the "Hotel California" issue, where left users +get spontaneously rejoined to rooms. This happens when a user has a sequence of +memberships changes of the form: leave (A), join (B) and then another leave (C). +In the current algorithm a resoluton of A and C would pick A, and a resolution +of A and B would then pick B, i.e. the join. This means that a suitably forked +graph can reset the state to B. This is fixed if when resolving A and C we also +consider B, since its in the auth chain of C.) + ## Power Level Ordering From dc499bc440ae38422f2041e4b2534579940c7756 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 3 Aug 2018 14:00:47 +0100 Subject: [PATCH 8/8] Expand on reverse topological power ordering --- proposals/1442-state-resolution.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/1442-state-resolution.md b/proposals/1442-state-resolution.md index 9fd7da8a8..1a2e82a35 100644 --- a/proposals/1442-state-resolution.md +++ b/proposals/1442-state-resolution.md @@ -257,7 +257,10 @@ First we define: 2. x's origin_server_ts is less than y's, or if 3. x's event_id is lexicographically less than y's - This is also known as a lexicographical topological sort. + This is also known as a lexicographical topological sort (i.e. this is the + unique topological ordering such that for an entry x all entries after it + must either have x in their auth chain or be greater than x as defined + above). This can be implemented using Kahn's algorithm. * The **"mainline ordering"** based on a power level event P of a set of events is calculated as follows: