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

Commit

Permalink
Only drop dummy events if they reference remote events
Browse files Browse the repository at this point in the history
  • Loading branch information
erikjohnston committed Dec 14, 2020
1 parent 62c30e8 commit a4d8bd9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 5 deletions.
29 changes: 26 additions & 3 deletions synapse/storage/persist_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -846,9 +846,32 @@ async def _prune_extremities(
one_day_ago = self._clock.time_msec() - 24 * 60 * 60 * 1000
current_depth = max(e.depth for e, _ in events_context)
for event in dropped_events.values():
if self.is_mine_id(event.sender) and event.type != EventTypes.Dummy:
logger.debug("Not dropping own event")
return new_latest_event_ids
# If the event is a local dummy event then we should check it
# doesn't reference any local events, as we want to reference those
# if we send any new events.
#
# Note we do this recursively to handle the case where a dummy event
# references a dummy event that only references remote events.
#
# Ideally we'd figure out a way of still being able to drop old
# dummy events that reference local events, but this is good enough
# as a first cut.
events_to_check = [event]
while events_to_check:
new_events = set()
for event_to_check in events_to_check:
if self.is_mine_id(event_to_check.sender):
if event_to_check.type != EventTypes.Dummy:
logger.debug("Not dropping own event")
return new_latest_event_ids
new_events.update(event_to_check.prev_event_ids())

prev_events = await self.main_store.get_events(
new_events,
allow_rejected=True,
redact_behaviour=EventRedactBehaviour.AS_IS,
)
events_to_check = prev_events.values()

if (
event.origin_server_ts < one_day_ago
Expand Down
46 changes: 44 additions & 2 deletions tests/storage/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ def test_do_not_prune_gap_if_other_server(self):
# Check the new extremity is just the new remote event.
self.assert_extremities([self.remote_event_1.event_id, remote_event_2.event_id])

def test_prune_gap_if_dummy(self):
def test_prune_gap_if_dummy_remote(self):
"""Test that we drop extremities after a gap when the previous extremity
is a local dummy event and "old".
is a local dummy event and only points to remote events.
"""

body = self.helper.send_event(
Expand Down Expand Up @@ -257,6 +257,48 @@ def test_prune_gap_if_dummy(self):
# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id])

def test_prune_gap_if_dummy_local(self):
"""Test that we don't drop extremities after a gap when the previous
extremity is a local dummy event and points to local events.
"""

body = self.helper.send(self.room_id, body="Test", tok=self.token)

body = self.helper.send_event(
self.room_id, type=EventTypes.Dummy, content={}, tok=self.token
)
local_message_event_id = body["event_id"]
self.assert_extremities([local_message_event_id])

# Advance the clock for many days to make the old extremity "old". We
# also set the depth to "lots".
self.reactor.advance(7 * 24 * 60 * 60)

# Fudge a second event which points to an event we don't have. This is a
# state event so that the state changes (otherwise we won't prune the
# extremity as they'll have the same state group).
remote_event_2 = event_from_pdu_json(
{
"type": EventTypes.Member,
"state_key": "@user:other2",
"content": {"membership": Membership.JOIN},
"room_id": self.room_id,
"sender": "@user:other2",
"depth": 10000,
"prev_events": ["$some_unknown_message"],
"auth_events": [],
"origin_server_ts": self.clock.time_msec(),
},
RoomVersions.V6,
)

state_before_gap = self.get_success(self.state.get_current_state(self.room_id))

self.persist_event(remote_event_2, state=state_before_gap.values())

# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id, local_message_event_id])

def test_do_not_prune_gap_if_not_dummy(self):
"""Test that we do not drop extremities after a gap when the previous extremity
is not a dummy event.
Expand Down

0 comments on commit a4d8bd9

Please sign in to comment.