Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4718 from matrix-org/erikj/fix_backfill_state_shred
Browse files Browse the repository at this point in the history
Fix backfill storing incorrect state for events
  • Loading branch information
erikjohnston authored Feb 25, 2019
2 parents b1a90da + 108d5fb commit 69efe6f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog.d/4718.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix paginating over federation persisting incorrect state.
34 changes: 31 additions & 3 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,10 +770,26 @@ def backfill(self, dest, room_id, limit, extremities):
set(auth_events.keys()) | set(state_events.keys())
)

# We now have a chunk of events plus associated state and auth chain to
# persist. We do the persistence in two steps:
# 1. Auth events and state get persisted as outliers, plus the
# backward extremities get persisted (as non-outliers).
# 2. The rest of the events in the chunk get persisted one by one, as
# each one depends on the previous event for its state.
#
# The important thing is that events in the chunk get persisted as
# non-outliers, including when those events are also in the state or
# auth chain. Caution must therefore be taken to ensure that they are
# not accidentally marked as outliers.

# Step 1a: persist auth events that *don't* appear in the chunk
ev_infos = []
for a in auth_events.values():
if a.event_id in seen_events:
# We only want to persist auth events as outliers that we haven't
# seen and aren't about to persist as part of the backfilled chunk.
if a.event_id in seen_events or a.event_id in event_map:
continue

a.internal_metadata.outlier = True
ev_infos.append({
"event": a,
Expand All @@ -785,14 +801,21 @@ def backfill(self, dest, room_id, limit, extremities):
}
})

# Step 1b: persist the events in the chunk we fetched state for (i.e.
# the backwards extremities) as non-outliers.
for e_id in events_to_state:
# For paranoia we ensure that these events are marked as
# non-outliers
ev = event_map[e_id]
assert(not ev.internal_metadata.is_outlier())

ev_infos.append({
"event": event_map[e_id],
"event": ev,
"state": events_to_state[e_id],
"auth_events": {
(auth_events[a_id].type, auth_events[a_id].state_key):
auth_events[a_id]
for a_id in event_map[e_id].auth_event_ids()
for a_id in ev.auth_event_ids()
if a_id in auth_events
}
})
Expand All @@ -802,12 +825,17 @@ def backfill(self, dest, room_id, limit, extremities):
backfilled=True,
)

# Step 2: Persist the rest of the events in the chunk one by one
events.sort(key=lambda e: e.depth)

for event in events:
if event in events_to_state:
continue

# For paranoia we ensure that these events are marked as
# non-outliers
assert(not event.internal_metadata.is_outlier())

# We store these one at a time since each event depends on the
# previous to work out the state.
# TODO: We can probably do something more clever here.
Expand Down

0 comments on commit 69efe6f

Please sign in to comment.