-
Notifications
You must be signed in to change notification settings - Fork 433
MSC4370: Federation endpoint for retrieving current extremities #4370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| # MSC4370: Federation endpoint for retrieving current extremities | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overall, I approve of this MSC. We need something like this in order to ensure eventual delivery in Matrix. MSC4242 actually talks about this:
Having an endpoint which is compatible with those aims as well as policy server's aims would be helpful. That being said.. what exactly does the policy server do with the information it gets from this new endpoint? The proposal as written is unclear:
There is no such endpoint to do this today. The closest is
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In policyserv, there's a concept of "trusted" servers that it's willing to learn state from. Currently, that state learning happens when policyserv receives an event from one of those trusted servers. It uses that event's ID to make a The hope is to keep that same "call This isn't perfectly secure because yes, the state can and does change depending on how you look at the DAG, but Aside from that, the policy server can also use the extremities from a (trusted) server to send its own redactions and other events without having to bear the burden of the DAG itself. |
||
|
|
||
| [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) introduces | ||
| an idea for an extremely lightweight server implementation to be developed to reduce the amount of | ||
| spam which ends up persisted in a room's DAG. In these server implementations, knowing the "current" | ||
| state of the room can be important for factoring into deciding whether an event is spammy. | ||
|
|
||
| "Current state" is not a concept which exists over federation, however: servers are expected to calculate | ||
| and heal their copy of the DAG to resolve a definition of "current state" for the room. A policy server | ||
| might not be persisting or tracking the DAG for a room though, especially because it typically only | ||
| concerns itself with impact to *current* users in the room at the time the policy server is asked to | ||
| scan an event. | ||
|
|
||
| To avoid the burden of persisting (and calculating, healing, resolving, etc) the room DAG, policy | ||
| servers have two options: | ||
|
|
||
| 1. Attach themselves to a full homeserver implementation via the Client-Server API, calling endpoints | ||
| like [`GET /state`](https://spec.matrix.org/v1.16/client-server-api/#get_matrixclientv3roomsroomidstate). | ||
| 2. Wait for a "trusted" server to ask an event to be scanned, then call [`GET /state/:roomId`](https://spec.matrix.org/v1.16/server-server-api/#get_matrixfederationv1stateroomid) | ||
| against that server using the just-scanned event ID as a reference (after waiting a little bit so | ||
| the remote server can persist its now-approved event). | ||
|
|
||
| The first option is fiddly for policy servers which operate at the Federation layer natively, like | ||
| the Foundation's own policyserv implementation, because managing a bot account for this one information | ||
| source can be a lot of overhead. | ||
|
|
||
| The second option relies on the policy server receiving an event from a server it trusts before it | ||
| can "learn" the state of the room. If the room has a lot of traffic from other servers, its view of | ||
| "current state" may drift significantly and produce inaccurate spam determinations. This is the approach | ||
| policyserv currently uses. | ||
|
|
||
| This MSC introduces a new endpoint that (primarily) policy servers can use to retrieve the *current* | ||
| extremities a given server has so it may then retrieve the current state for the room. Policy servers | ||
| which require historical context of room state (or the DAG in general) should behave like a normal | ||
| homeserver and resolve the DAG to that point in time - this MSC will not be overly useful to them. | ||
|
|
||
| By allowing a server to retrieve the current extremities, that server can request (and cache) current | ||
| state whenever it feels it needs to rather than waiting for a remote server to become active. This | ||
| could be on a timer, after a certain number of events have been scanned in the room, after specific | ||
| event types are seen, or a combination of all 3 - when to call the new endpoint is left as an implementation | ||
| detail. | ||
|
|
||
| This MSC expects that the current extremities for a room are highly cached or easily discovered by | ||
| a given server implementation - it's the exact same information it would populate in `prev_events` | ||
| if it were to send an event at that time. | ||
|
|
||
| Though not primary drivers for this proposal, this MSC's new endpoint also enables two bonus features: | ||
|
|
||
| 1. A server which has lost its copy of the DAG, but has a room ID and server name, can call the new | ||
| endpoint to get current extremities and work backwards from there to rebuild the DAG. This doesn't | ||
| fix a scenario where the server has a total loss of room information, but a step towards recovery | ||
| is always better than none. A server may use this feature after data loss if a user happens to have | ||
| a cache of their room list still, for example. | ||
|
|
||
| Other MSCs in this space include: | ||
| * [MSC2316: Federation queries to aid with database recovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2316) | ||
| * [MSC2314: A method to backfill room state](https://github.com/matrix-org/matrix-spec-proposals/pull/2314) | ||
| (**MSC2314 is a strong alternative to this MSC.**) | ||
|
|
||
| 2. If a lightweight server were to want to send an event, such as a redaction or a ban, it can use | ||
| this MSC's new endpoint to get accurate-enough `prev_events` for its event, then inspect current | ||
| state to populate `auth_events` and send the event to all other servers in the room. | ||
|
|
||
| Currently policy servers manage a bot account to accomplish this task - see above regarding how | ||
| fiddly that can be. Eliminating the need to manage a bot account is a desirable feature for the | ||
| Foundation's policyserv implementation. | ||
|
|
||
| ## Proposal | ||
|
|
||
| A new endpoint is added to the [Server-Server API](https://spec.matrix.org/v1.16/server-server-api/) | ||
| to retrieve the current extremities (as event IDs) the server has in the given room. The endpoint | ||
| requires normal authentication for federation endpoints and MAY be rate limited. "Current" is at the | ||
| time of the request and has no guarantee of being accurate after the request is completed. | ||
|
|
||
| Servers should note that this endpoint returns the same information which would be supplied in the | ||
| `prev_events` for an event, if they were to send one. | ||
|
|
||
| Request shape: | ||
|
|
||
| ``` | ||
| GET /_matrix/federation/v1/extremities/{roomId} | ||
| Authorization: X-Matrix ... | ||
| ``` | ||
|
|
||
| (there are no query parameters or request body) | ||
|
|
||
| Response shape: | ||
|
|
||
| ``` | ||
| Content-Type: application/json | ||
| { | ||
| "prev_events": ["$event1", "$event2"] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must this contain ALL prev_events, even if there are thousands of them? Millions? There is unfortunately no limit to how many forward extremities you can have.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it should be "whatever you'd need to send an event", which I think is limited in some way. Will clarify in the MSC if it's not already there. |
||
| } | ||
| ``` | ||
|
|
||
| The response is contained in an object for future expansion. `prev_events` is required, and MUST have | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Minor: Is
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The theory is someone could just copy the object on top of an event template, though that's not exactly a thing we need to support. |
||
| at least one event ID entry in its array. | ||
|
|
||
| The following errors may be returned: | ||
|
|
||
| * 403 / `M_FORBIDDEN` - The requesting server is not in the room, or is excluded from the room via | ||
| `m.room.server_acl`. | ||
| * 404 / `M_NOT_FOUND` - The server is not aware of the room. | ||
|
|
||
| Servers SHOULD NOT attempt to fully resolve the DAG before returning a response - the calling server | ||
| is expected to handle the extremities as needed. For minimal/lightweight policy server implementations, | ||
| this may mean requesting state at each event and merging the results for a good enough representation | ||
| of current state - specific handling is left as an implementation detail. | ||
|
|
||
| ## Potential issues | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(please use threads to ensure comments are visible and can be replied to)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in all honesty, I'm not concerned about v1 or v2 rooms at this point in our history. If a server really wants to support those room versions, it can call this endpoint then the |
||
|
|
||
| Lightweight server implementations may find it difficult to handle responses where `prev_events` has | ||
| more than a single entry. They could attempt to run state resolution over the information they learn, | ||
| or they could do a "simple" merge to get to somewhere close enough depending on their use case. They | ||
| may also decide to just wait a little bit and hope that the remote server self-resolves the DAG or | ||
| try another server. | ||
|
|
||
| ## Alternatives | ||
|
|
||
| The major alternatives are discussed in the introduction for this proposal. | ||
|
|
||
| ## Security considerations | ||
|
|
||
| **Author's note**: Specifics on how to exploit Matrix or this MSC are intentionally omitted from this | ||
| proposal. Refer to the [Security Disclosure Policy](https://matrix.org/security-disclosure-policy/) | ||
| to discuss such concerns and details. | ||
|
|
||
| Spammers can already use a few different tools to flood a room and this MSC makes it easier to do so. | ||
| This MSC does not have mitigation for such spam and instead expects that other aspects of Matrix will | ||
| take care of it. Features such as rate limits, policy servers, moderation tooling generally, and | ||
| server-side (implementation-specific) DAG/room simplification may be of interest to server developers | ||
| and communities on Matrix. | ||
|
|
||
| ## Unstable prefix | ||
|
|
||
| While this proposal is not considered stable, implementations should use | ||
| `/_matrix/federation/unstable/org.matrix.msc4370/extremities/{roomId}` in place of the stable endpoint. | ||
|
|
||
| ## Dependencies | ||
|
|
||
| This MSC has no direct dependencies, but is primarily intended to be useful to [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284). | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation requirements:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend waiting to implement this MSC until it has a reasonably healthy amount of review given the security considerations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This MSC has not had the healthy amount of review recommended, but I've started an implementation anyway: element-hq/synapse#19314
I intend to keep that PR in a draft state until MSC review can happen, disqualifying it as an implementation for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's been some review on this, so the implementation was put forward for review and has now landed. Next steps are to get it implemented in another server, probably policyserv.