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

Commit

Permalink
Fix incorrect truncation in get_missing_events
Browse files Browse the repository at this point in the history
It's quite important that get_missing_events returns the *latest* events in the
room; however we were pulling event ids out of the database until we got *at
least* 10, and then taking the *earliest* of the results.

We also shouldn't really be relying on depth, and should be checking the
room_id.
  • Loading branch information
richvdh committed Oct 16, 2018
1 parent b8a5b00 commit fc0f13d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 35 deletions.
1 change: 1 addition & 0 deletions changelog.d/4045.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug which made get_missing_events return too few events
8 changes: 4 additions & 4 deletions synapse/federation/federation_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,19 @@ def on_claim_client_keys(self, origin, content):
@defer.inlineCallbacks
@log_function
def on_get_missing_events(self, origin, room_id, earliest_events,
latest_events, limit, min_depth):
latest_events, limit):
with (yield self._server_linearizer.queue((origin, room_id))):
origin_host, _ = parse_server_name(origin)
yield self.check_server_matches_acl(origin_host, room_id)

logger.info(
"on_get_missing_events: earliest_events: %r, latest_events: %r,"
" limit: %d, min_depth: %d",
earliest_events, latest_events, limit, min_depth
" limit: %d",
earliest_events, latest_events, limit,
)

missing_events = yield self.handler.on_get_missing_events(
origin, room_id, earliest_events, latest_events, limit, min_depth
origin, room_id, earliest_events, latest_events, limit,
)

if len(missing_events) < 5:
Expand Down
2 changes: 0 additions & 2 deletions synapse/federation/transport/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,6 @@ class FederationGetMissingEventsServlet(BaseFederationServlet):
@defer.inlineCallbacks
def on_POST(self, origin, content, query, room_id):
limit = int(content.get("limit", 10))
min_depth = int(content.get("min_depth", 0))
earliest_events = content.get("earliest_events", [])
latest_events = content.get("latest_events", [])

Expand All @@ -569,7 +568,6 @@ def on_POST(self, origin, content, query, room_id):
room_id=room_id,
earliest_events=earliest_events,
latest_events=latest_events,
min_depth=min_depth,
limit=limit,
)

Expand Down
12 changes: 5 additions & 7 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ def on_receive_pdu(

if sent_to_us_directly:
logger.warn(
"[%s %s] Failed to fetch %d prev events: rejecting",
room_id, event_id, len(prevs - seen),
"[%s %s] Rejecting: failed to fetch %d prev events: %s",
room_id, event_id, len(prevs - seen), shortstr(prevs - seen)
)
raise FederationError(
"ERROR",
Expand Down Expand Up @@ -452,8 +452,8 @@ def _get_missing_events_for_pdu(self, origin, pdu, prevs, min_depth):
latest |= seen

logger.info(
"[%s %s]: Requesting %d prev_events: %s",
room_id, event_id, len(prevs - seen), shortstr(prevs - seen)
"[%s %s]: Requesting missing events between %s and %s",
room_id, event_id, shortstr(latest), event_id,
)

# XXX: we set timeout to 10s to help workaround
Expand Down Expand Up @@ -1852,7 +1852,7 @@ def on_query_auth(self, origin, event_id, room_id, remote_auth_chain, rejects,

@defer.inlineCallbacks
def on_get_missing_events(self, origin, room_id, earliest_events,
latest_events, limit, min_depth):
latest_events, limit):
in_room = yield self.auth.check_host_in_room(
room_id,
origin
Expand All @@ -1861,14 +1861,12 @@ def on_get_missing_events(self, origin, room_id, earliest_events,
raise AuthError(403, "Host not in room.")

limit = min(limit, 20)
min_depth = max(min_depth, 0)

missing_events = yield self.store.get_missing_events(
room_id=room_id,
earliest_events=earliest_events,
latest_events=latest_events,
limit=limit,
min_depth=min_depth,
)

missing_events = yield filter_events_for_server(
Expand Down
38 changes: 16 additions & 22 deletions synapse/storage/event_federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,33 +376,25 @@ def _get_backfill_events(self, txn, room_id, event_list, limit):

@defer.inlineCallbacks
def get_missing_events(self, room_id, earliest_events, latest_events,
limit, min_depth):
limit):
ids = yield self.runInteraction(
"get_missing_events",
self._get_missing_events,
room_id, earliest_events, latest_events, limit, min_depth
room_id, earliest_events, latest_events, limit,
)

events = yield self._get_events(ids)

events = sorted(
[ev for ev in events if ev.depth >= min_depth],
key=lambda e: e.depth,
)

defer.returnValue(events[:limit])
defer.returnValue(events)

def _get_missing_events(self, txn, room_id, earliest_events, latest_events,
limit, min_depth):

earliest_events = set(earliest_events)
front = set(latest_events) - earliest_events
limit):

event_results = set()
seen_events = set(earliest_events)
front = set(latest_events) - seen_events
event_results = []

query = (
"SELECT prev_event_id FROM event_edges "
"WHERE event_id = ? AND is_state = ? "
"WHERE room_id = ? AND event_id = ? AND is_state = ? "
"LIMIT ?"
)

Expand All @@ -411,18 +403,20 @@ def _get_missing_events(self, txn, room_id, earliest_events, latest_events,
for event_id in front:
txn.execute(
query,
(event_id, False, limit - len(event_results))
(room_id, event_id, False, limit - len(event_results))
)

for e_id, in txn:
new_front.add(e_id)
new_results = set(t[0] for t in txn) - seen_events

new_front -= earliest_events
new_front -= event_results
new_front |= new_results
seen_events |= new_results
event_results.extend(new_results)

front = new_front
event_results |= new_front

# we built the list working backwards from latest_events; we now need to
# reverse it so that the events are approximately chronological.
event_results.reverse()
return event_results


Expand Down

0 comments on commit fc0f13d

Please sign in to comment.