Repository navigation
Conversation
f5a07a8 to
4fa82bf
Compare
76ae862 to
338ed0c
Compare
338ed0c to
581e149
Compare
51b9c9d to
72a6801
Compare
8f19e17 to
a835dac
Compare
| batched_auth_events = { | ||
| event_id: event_map[event_id] |
There was a problem hiding this comment.
LLM is spotting another rejection cascade problem:
LLM description
Rejection doesn't cascade on rejoin (most serious).
- Every event from the response goes into
event_mapas a fresh copy withrejected_reason=None. That includes events we already stored and rejected on an earlier join. batched_auth_eventsis built fromevent_map(:2068).check_state_independent_auth_rulesreadsprev_state_eventsfrombatched_auth_eventsbefore it looks at the database (event_auth.py:204).rejectionsonly records decisions made in the current batch.- Result: a new event whose
prev_state_eventsincludes an event we rejected last time passes the check atevent_auth.py:250. This reopens the concern from the earlier thread at:2082, just by a different route. - Suggested fix: when processing the seen events, fill rejections from the database with their reasons, or use the stored copies for seen events.
Previous problem: #20194 (comment)
There was a problem hiding this comment.
2d9da36 - basically doing the suggested fix of replacing the wire-events with stored-events (which contain rejections).
There was a problem hiding this comment.
Probably worth a test so we don't regress these subtleties
| if from_send_join and all( | ||
| prev_state_event_id in event_id_to_state_group | ||
| for prev_state_event_id in event.prev_state_events | ||
| ): |
There was a problem hiding this comment.
LLM is mentioning that if an event's prev_state_events mix an event we already persisted and one that's new in this batch, we fall back to compute_state_after_events from the DB. But nothing in the batch is persisted until the end, so the new parent has no state group yet, and its branch is silently dropped from the state.
Also see #20194 (comment)
There was a problem hiding this comment.
Probably worth a test so we don't regress these subtleties
| # If this assumption is ever violated, `compute_state_after_events` will | ||
| # yell loudly about missing state groups. |
There was a problem hiding this comment.
LLM is calling out that _get_state_group_for_events raises RuntimeError for unknown events, but the @cachedList wrapper swallows it and the caller just gets partial results.
This sounds like a pre-existing bug with @cachedList but it makes our comment inaccurate and we should probably mark it with a FIXME with a link to a Synapse issue tracking this problem.
There was a problem hiding this comment.
This is related to the comment #20194 (comment) as this should have caused a 500 but instead silently dropped the branch :/
There was a problem hiding this comment.
I just added a TODO for this as this PR is sprawling enough as it is.
There was a problem hiding this comment.
The comment should be updated to call this out more clearly as something that's probably unexpected.
XXX: `_get_state_group_for_events` raises `RuntimeError` for unknown events, but
the `@cachedList` wrapper swallows it and the caller just gets partial results.
For the time-being, Callers MUST NOT rely on this to determine missing events,
as cached responses return None for the state group instead of raising.
TODO: audit every caller, as some of them may be relying on the current behaviour.And should be copied over to _get_state_group_for_events as well
| raise SynapseError(HTTPStatus.BAD_REQUEST, "Too many prev_events") | ||
|
|
||
| if len(ev.auth_event_ids()) > 10: | ||
| if supports_msc4242_state_dag(ev) and len(ev.prev_state_events) > 20: |
There was a problem hiding this comment.
LLM is mentioning that we don't also have a check for this when creating local events which means other servers will just reject events that we create.
There was a problem hiding this comment.
I see a 👍 but what's the plan here?
Co-authored-by: Eric Eastwood <madlittlemods@gmail.com>
Co-authored-by: Eric Eastwood <erice@element.io>
Co-authored-by: Eric Eastwood <erice@element.io>
Co-authored-by: Eric Eastwood <erice@element.io>
- Enable MSC4242 complement tests - Fix an issue which caused cascade rejections to not be applied to events in the /send_join response becau se we didn't remember in-memory which events were rejected. - Accept rejected events in the /send_join response, it gives us a bit of robustness at no safety cost. - Recalculate room state if backfilled events caused the state DAG fwd extrems to change. - Don't filter out already seen events from event_map, so the statement "the event_map is the complete stat e DAG" still holds. - Add validation to length of prev_state_events - Don't validate auth_events length for state DAG events as it is done too early, before we've had time to calculate the auth events (and validation is moot anyway given it isn't attacker controlled anymore) - Let backfilled events update state dag fwd extrems - Add test for edge case with backfilled state events
…events that should have been rejected The cascade rejection only worked on in-flight events, not seen events. We now overwrite events in event_map with rejected events (thus setting .rejected_reason) to ensure we continue to cascade rejections correctly. Complement test asserts this.
… if one of the prev_state_events was already persisted Tested in Complement as TestMSC4242RejoinMergesOldAndNewStateDAGBranches
…vent is connected to the state DAG This PR only handles /send_join and connected events in /send, so everything else should return early with coherent error messages. The join event must be connected to the main state DAG but we previously didn't ensure this.
… scanning for other room versions
…-wide ..which would be bad.
1ef48a8 to
82d52c9
Compare
| @@ -0,0 +1 @@ | |||
| Add support for joining [MSC4242](https://github.com/matrix-org/matrix-spec-proposals/pull/4242) rooms over federation. | |||
There was a problem hiding this comment.
❌ CI failing, https://github.com/element-hq/synapse/actions/runs/37028432824/job/110910905270
[FAIL]
Traceback (most recent call last):
File "/home/runner/work/synapse/synapse/tests/federation/test_federation_server.py", line 519, in test_is_opt_in
timeline_events = self._get_missing_events(
File "/home/runner/work/synapse/synapse/tests/federation/test_federation_server.py", line 462, in _get_missing_events
self.assertEqual(HTTPStatus.OK, channel.code, channel.json_body)
File "/home/runner/work/synapse/synapse/tests/unittest.py", line 433, in assertEqual
super().assertEqual(first=first, second=second, msg=msg)
File "/home/runner/.cache/pypoetry/virtualenvs/matrix-synapse-pswDeSvb-py3.10/lib/python3.10/site-packages/twisted/trial/_synctest.py", line 433, in assertEqual
super().assertEqual(first, second, msg)
File "/opt/hostedtoolcache/Python/3.10.21/x64/lib/python3.10/unittest/case.py", line 845, in assertEqual
assertion_func(first, second, msg=msg)
File "/opt/hostedtoolcache/Python/3.10.21/x64/lib/python3.10/unittest/case.py", line 838, in _baseAssertEqual
raise self.failureException(msg)
twisted.trial.unittest.FailTest: <HTTPStatus.OK: 200> != 400 : {'errcode': 'M_UNRECOGNIZED', 'error': '/get_missing_events is not implemented for MSC4242 state DAG rooms'}
tests.federation.test_federation_server.GetMissingEventsStateDagTests.test_is_opt_in
| batched_auth_events = { | ||
| event_id: event_map[event_id] |
There was a problem hiding this comment.
Probably worth a test so we don't regress these subtleties
| if from_send_join and all( | ||
| prev_state_event_id in event_id_to_state_group | ||
| for prev_state_event_id in event.prev_state_events | ||
| ): |
There was a problem hiding this comment.
Probably worth a test so we don't regress these subtleties
| raise SynapseError(HTTPStatus.BAD_REQUEST, "Too many prev_events") | ||
|
|
||
| if len(ev.auth_event_ids()) > 10: | ||
| if supports_msc4242_state_dag(ev) and len(ev.prev_state_events) > 20: |
There was a problem hiding this comment.
I see a 👍 but what's the plan here?
| # If this assumption is ever violated, `compute_state_after_events` will | ||
| # yell loudly about missing state groups. |
There was a problem hiding this comment.
The comment should be updated to call this out more clearly as something that's probably unexpected.
XXX: `_get_state_group_for_events` raises `RuntimeError` for unknown events, but
the `@cachedList` wrapper swallows it and the caller just gets partial results.
For the time-being, Callers MUST NOT rely on this to determine missing events,
as cached responses return None for the state group instead of raising.
TODO: audit every caller, as some of them may be relying on the current behaviour.And should be copied over to _get_state_group_for_events as well
| if len(event.prev_state_events) == 0 and not is_create_event: | ||
| raise SynapseError(502, f"event {event.event_id} has no prev_state_events") |
There was a problem hiding this comment.
Why don't we reject the event instead of dropping it?
Related to the other spot where a rejected event in the DAG only logs "Joining anyway", on the grounds that refusing "would cost availability without buying any safety".
Process inbound requests to join a state DAG room.
Split out from #19425
Part of a series of 5x PRs to land the federation part of MSC4242 (#19718, #20127, #20133, inbound-joins (this PR), inbound-pulls).
Has some Complement tests:
Pull Request Checklist
EventStoretoEventWorkerStore.".code blocks.