Skip to content

MSC4370: Federation endpoint for retrieving current extremities#4370

Open
turt2live wants to merge 2 commits intomainfrom
travis/msc/prev-events-fed
Open

MSC4370: Federation endpoint for retrieving current extremities#4370
turt2live wants to merge 2 commits intomainfrom
travis/msc/prev-events-fed

Conversation

@turt2live
Copy link
Copy Markdown
Member

Rendered

Disclosure: I am Director of Standards Development at The Matrix.org Foundation C.I.C., Matrix Spec Core Team (SCT) member, employed by Element, and operate the t2bot.io service. This proposal is written and published as a Trust & Safety team member allocated in full to the Foundation.

@turt2live turt2live changed the title MSC: Federation endpoint for retrieving current extremities MSC4370: Federation endpoint for retrieving current extremities Oct 17, 2025
@turt2live turt2live added proposal A matrix spec change proposal s2s Server-to-Server API (federation) kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. labels Oct 17, 2025
@turt2live turt2live marked this pull request as ready for review October 17, 2025 21:56
Copy link
Copy Markdown
Member Author

@turt2live turt2live Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Server (calling)
  • Server (serving)

Copy link
Copy Markdown
Member Author

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.

Copy link
Copy Markdown
Member Author

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.

Copy link
Copy Markdown
Member Author

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.

@velikopter

This comment was marked as duplicate.

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
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@velikopter says:

This doesn't seem to consider v1 or v2 rooms, which have prev_events laid out differently.

(please use threads to ensure comments are visible and can be replied to)

Copy link
Copy Markdown
Member Author

@turt2live turt2live Oct 18, 2025

Choose a reason for hiding this comment

The 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 GET /event/:eventId endpoint to get the hash, then wedge that tuple into whatever it needs to.

@@ -0,0 +1,141 @@
# MSC4370: Federation endpoint for retrieving current extremities
Copy link
Copy Markdown
Member

@kegsay kegsay Feb 11, 2026

Choose a reason for hiding this comment

The 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:

In current Matrix, eventual delivery of events is only ensured under the assumption that any server continuously sends new events. The additional assumption is needed because homeservers do not eagerly share known forward extremities with each other: it relies on servers sending events. As such, you can have two servers who disagree on the current state because one server is aware of events that affect the current state and the other is not. This is less of a problem than the soft-failure case because it will correct itself when an event is sent, but the system requires some external input to provide eventual delivery, in order to eventually converge. This will be addressed in a future MSC.

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:

so it may then retrieve the current state for the room

that server can request (and cache) current state whenever it feels it needs to rather than waiting for a remote server to become active.

There is no such endpoint to do this today. The closest is GET /_matrix/federation/v1/state/{roomId} but this only accepts a single event ID. It is not secure to just pick a random prev event and use that state, nor is it secure to just merge individual states together without doing state resolution.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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 /state request if it hasn't updated its room state in a while. This can cause its state information to be old if the trusted server doesn't send an event for a while, which isn't great.

The hope is to keep that same "call /state with an event ID" logic, but using the trusted server's extremities. If there's multiple extremities, the policy server can send an event, wait a bit, then learn state off its own event ID. This does mean that a server becomes trusted to not only supply resolved state, but also trusted to be moderately up to date on the room to provide recent extremities.

This isn't perfectly secure because yes, the state can and does change depending on how you look at the DAG, but /state is supposed to do that state resolution to some degree, and the policy server in this case isn't actually that concerned with it being a perfect representation of state anyway. If it gets "wrong" state, it will mean the cache of some state events is a little broken for a bit. In policyserv, that might mean not recognizing a recently-promoted admin as an admin or missing a policy rule from a moderation bot - both of these are easily correctable the next time the cron job runs.

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.

```
Content-Type: application/json
{
"prev_events": ["$event1", "$event2"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Minor: Is prev_events a good name for this, or is it a Synapsism? They aren't really 'previous' to anything yet. I'm not fussy though.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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.

turt2live added a commit to element-hq/synapse that referenced this pull request Mar 5, 2026
MSC (recommended reading):
matrix-org/matrix-spec-proposals#4370

### Pull Request Checklist

<!-- Please read
https://element-hq.github.io/synapse/latest/development/contributing_guide.html
before submitting your pull request -->

* [x] Pull request is based on the develop branch
* [x] Pull request includes a [changelog
file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog).
The entry should:
- Be a short description of your change which makes sense to users.
"Fixed a bug that prevented receiving messages from other servers."
instead of "Moved X method from `EventStore` to `EventWorkerStore`.".
  - Use markdown where necessary, mostly for `code blocks`.
  - End with either a period (.) or an exclamation mark (!).
  - Start with a capital letter.
- Feel free to credit yourself, by adding a sentence "Contributed by
@github_username." or "Contributed by [Your Name]." to the end of the
entry.
* [x] [Code
style](https://element-hq.github.io/synapse/latest/code_style.html) is
correct (run the
[linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))

---------

Co-authored-by: turt2live <1190097+turt2live@users.noreply.github.com>
Co-authored-by: Olivier 'reivilibre' <oliverw@element.io>
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Mar 24, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [element-hq/synapse](https://github.com/element-hq/synapse) | minor | `v1.149.1` → `v1.150.0` |

---

### Release Notes

<details>
<summary>element-hq/synapse (element-hq/synapse)</summary>

### [`v1.150.0`](https://github.com/element-hq/synapse/releases/tag/v1.150.0)

[Compare Source](element-hq/synapse@v1.149.1...v1.150.0)

### Synapse 1.150.0 (2026-03-24)

No significant changes since 1.150.0rc1.

### Synapse 1.150.0rc1 (2026-03-17)

#### Features

- Add experimental support for the [MSC4370](matrix-org/matrix-spec-proposals#4370) Federation API `GET /extremities` endpoint. ([#&#8203;19314](element-hq/synapse#19314))
- [MSC4140: Cancellable delayed events](matrix-org/matrix-spec-proposals#4140): When persisting a delayed event to the timeline, include its `delay_id` in the event's `unsigned` section in `/sync` responses to the event sender. ([#&#8203;19479](element-hq/synapse#19479))
- Expose [MSC4354 Sticky Events](matrix-org/matrix-spec-proposals#4354) over the legacy (v3) /sync API. ([#&#8203;19487](element-hq/synapse#19487))
- When Matrix Authentication Service (MAS) integration is enabled, allow MAS to set the user locked status in Synapse. ([#&#8203;19554](element-hq/synapse#19554))

#### Bugfixes

- Fix `Build and push complement image` CI job pointing to non-existent image. ([#&#8203;19523](element-hq/synapse#19523))
- Fix a bug introduced in v1.26.0 that caused deactivated, erased users to not be removed from the user directory. ([#&#8203;19542](element-hq/synapse#19542))

#### Improved Documentation

- In the Admin API documentation, always express path parameters as `/<param>` instead of as `/$param`. ([#&#8203;19307](element-hq/synapse#19307))
- Update docs to clarify `outbound_federation_restricted_to` can also be used with the [Secure Border Gateway (SBG)](https://element.io/en/server-suite/secure-border-gateways). ([#&#8203;19517](element-hq/synapse#19517))
- Unify Complement developer docs. ([#&#8203;19518](element-hq/synapse#19518))

#### Internal Changes

- Put membership updates in a background resumable task when changing the avatar or the display name. ([#&#8203;19311](element-hq/synapse#19311))
- Add in-repo Complement test to sanity check Synapse version matches git checkout (testing what we think we are). ([#&#8203;19476](element-hq/synapse#19476))
- Migrate `dev` dependencies to [PEP 735](https://peps.python.org/pep-0735/) dependency groups. ([#&#8203;19490](element-hq/synapse#19490))
- Remove the optional `systemd-python` dependency and the `systemd` extra on the `synapse` package. ([#&#8203;19491](element-hq/synapse#19491))
- Avoid re-computing the event ID when cloning events. ([#&#8203;19527](element-hq/synapse#19527))
- Allow caching of the `/versions` and `/auth_metadata` public endpoints. ([#&#8203;19530](element-hq/synapse#19530))
- Add a few labels to the number groupings in the `Processed request` logs. ([#&#8203;19548](element-hq/synapse#19548))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My44NC4yIiwidXBkYXRlZEluVmVyIjoiNDMuODQuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/5040
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hacktoberfest-accepted kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal s2s Server-to-Server API (federation)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants