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

Add endpoints for backfilling history (MSC2716) #9247

Merged
merged 96 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
22c038e
Add endpoints for backfilling history (MSC2716)
MadLittleMods Jan 28, 2021
4836954
Add querystring prev_event to pass into message send API
MadLittleMods Jan 29, 2021
c0b0936
Allow override origin_server_ts
MadLittleMods Jan 30, 2021
bf90053
Remove origin_server_ts in favor of spec'ed ts query param
MadLittleMods Feb 2, 2021
bcc6943
Use previous depth if overriding prev_events to insert into history
MadLittleMods Feb 2, 2021
7f4c3a6
Remove m.historical messages from /sync
MadLittleMods Feb 5, 2021
800f3a3
Remove debug logs
MadLittleMods Feb 5, 2021
9b5e057
Fix some lint
MadLittleMods Feb 5, 2021
447eaa8
Add changelog
MadLittleMods Feb 5, 2021
7ec22b5
Fix tox mypy check
MadLittleMods Feb 5, 2021
afa5e5d
Remove debugging fields for TARDIS visualization
MadLittleMods Feb 5, 2021
f1f3fb0
Pass inherit_depth all the way down the line which we define only wh…
MadLittleMods Feb 5, 2021
e7d7f92
Fix some lints
MadLittleMods Feb 5, 2021
b9024f7
Type hinting and docstrings
MadLittleMods Feb 9, 2021
d204880
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Feb 9, 2021
dbba361
Add experimental feature flag for MSC2716
MadLittleMods Feb 9, 2021
f1c31f1
Fix isort linting
MadLittleMods Feb 9, 2021
19aa93c
Fix experimental msc2716 feature flag
MadLittleMods Feb 9, 2021
c074584
Try fix type hints and tox errors
MadLittleMods Feb 9, 2021
c02079d
Fix extra new line lint
MadLittleMods Feb 9, 2021
412ffc3
Update changelog.d/9247.feature
MadLittleMods Feb 11, 2021
7160f3b
Update synapse/events/builder.py
MadLittleMods Feb 11, 2021
5ff398d
Update synapse/visibility.py
MadLittleMods Feb 11, 2021
864b98f
Clean up docstrings and address review
MadLittleMods Feb 11, 2021
6f174f1
Merge branch 'eric/msc2716-backfilling-history' of github.com:matrix-…
MadLittleMods Feb 11, 2021
ba1eb39
Simplify prev_event fetching off the event dictionary
MadLittleMods Feb 11, 2021
6d4fcb6
Filter recent events in both places that we fetch them
MadLittleMods Feb 11, 2021
5d5fb8b
Fix lint
MadLittleMods Feb 11, 2021
ed76d5f
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Feb 11, 2021
1aa3af9
Fix newline lint
MadLittleMods Feb 11, 2021
e63ef8e
Remove return strict type to avoid downstream lint problems
MadLittleMods Feb 11, 2021
c90af9e
Fix test failure with mocked build function
MadLittleMods Feb 11, 2021
270e5ee
Fix lint
MadLittleMods Feb 11, 2021
4359ab8
Fix lint again wanting to reverse what black wants...
MadLittleMods Feb 11, 2021
641e871
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Feb 17, 2021
6d8514f
Run lint.sh
MadLittleMods Feb 17, 2021
5dacc86
Remove default for inherit_depth
MadLittleMods Feb 17, 2021
61dc89f
WIP: Use depth from successor event
MadLittleMods Mar 11, 2021
e12a77d
Fix depth on historical forward extremeties
MadLittleMods Mar 11, 2021
8549219
403 when non appservice trying to use prev_event
MadLittleMods Mar 13, 2021
6c96622
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Mar 30, 2021
23d0379
Bulk send endpoint for backfilling history (MSC2716)
MadLittleMods Mar 30, 2021
ea37564
Add bulk send endpoint
MadLittleMods Mar 31, 2021
7008ee0
Skip everything and just persist the event
MadLittleMods Mar 31, 2021
0d4736f
Scratch commit trying to use existing functions
MadLittleMods Apr 6, 2021
49631e5
Scratch commit 2
MadLittleMods Apr 6, 2021
06dccec
Scratch commit 3
MadLittleMods Apr 7, 2021
8e0684d
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Apr 10, 2021
cbd16b8
Working bulksend endpoint for sending state and historical messages (…
MadLittleMods Apr 10, 2021
044a761
Fix up some CI lints
MadLittleMods Apr 12, 2021
86ec915
Fix some more CI lint and tests
MadLittleMods Apr 14, 2021
81b45b5
Copy over origin_server_ts when bulksend'ing
MadLittleMods Apr 14, 2021
02b7335
Wrap bulksend endpoint around experimental feature flag and only apps…
MadLittleMods Apr 14, 2021
82708cb
Add comment docs for new parameters
MadLittleMods Apr 14, 2021
f0fb732
Add historical messages to /backfill response
MadLittleMods May 1, 2021
c525c5d
Logging to better debug federated event not authing
MadLittleMods May 1, 2021
5deee7c
Add local copy of signedjson to debug sign/verify steps
MadLittleMods May 5, 2021
960ec21
More log debugging
MadLittleMods May 6, 2021
779ef25
Revert debugging commits
MadLittleMods May 6, 2021
7dcc0fa
Fix signature check failing for historical state events
MadLittleMods May 6, 2021
52b1e7b
Clean up remaining debug logs
MadLittleMods May 6, 2021
1d6cf78
Add insertion events to the end of chunks
MadLittleMods May 14, 2021
13b18a8
Add insertion initially, end of chunk, and add live markers
MadLittleMods May 14, 2021
3d513bf
Remove partial federation code in favor of future insertion/marker logic
MadLittleMods May 20, 2021
e92a9e9
Start of new approach for chronolgoical events in chunk
MadLittleMods May 21, 2021
e9ae5e1
Chronological events but persist in reverse-chronological
MadLittleMods May 21, 2021
a978f38
Skip push notification actions for historical messages
MadLittleMods May 26, 2021
2c22929
Use more explicit comparison
MadLittleMods May 26, 2021
0501a11
Fix lint
MadLittleMods May 27, 2021
e231a99
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods May 27, 2021
176a854
Uncomment dropped fields to see if tests pass
MadLittleMods May 27, 2021
a6a05f8
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods May 29, 2021
25aef56
Return early instead of big if nesting
MadLittleMods May 27, 2021
0580d09
Pass in prev_events as function parameter so clients can't set it in …
MadLittleMods Jun 2, 2021
ef68832
Switch to passing depth directly instead of inherit_depth
MadLittleMods Jun 5, 2021
d8316d6
Calculate and pass in depth directly
MadLittleMods Jun 6, 2021
513d7a2
Only get_max_depth_of where we use it
MadLittleMods Jun 7, 2021
f36bdde
Remove random logs used while developing
MadLittleMods Jun 7, 2021
c2e1924
Use nice negative list index to grab last item
MadLittleMods Jun 7, 2021
88327fb
Remove unneeded body from insertion events
MadLittleMods Jun 7, 2021
34f130c
Switch wording from bulk to batch
MadLittleMods Jun 7, 2021
2f35954
Always use auth_event_ids from the event itself
MadLittleMods Jun 7, 2021
6ce47d3
Protect from clients from using the historical logic (only /batchsend…
MadLittleMods Jun 7, 2021
b032370
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Jun 8, 2021
22881e2
Fix incorrect logic when refactoring to is_historical (failed tests a…
MadLittleMods Jun 8, 2021
ae85719
Fix tests using False as a depth value (should be None)
MadLittleMods Jun 9, 2021
d59d6be
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Jun 11, 2021
c236a3c
Fix greedy find/replace
MadLittleMods Jun 11, 2021
429e130
Add docstring to explain batchsend endpoint
MadLittleMods Jun 16, 2021
29c3708
Only use necessary auth_events
MadLittleMods Jun 16, 2021
89e08c5
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Jun 16, 2021
bfe458c
Use unstable endpoint for MSC2716 batch send
MadLittleMods Jun 17, 2021
2c1750f
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Jun 17, 2021
e851dac
Remove complement test jig changes
MadLittleMods Jun 17, 2021
7dcbba9
Merge branch 'develop' into eric/msc2716-backfilling-history
MadLittleMods Jun 21, 2021
f7158ff
Correct comment to make more sense to what the code was doing
MadLittleMods Jun 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/9247.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement MSC2716 to support backfilling history into rooms
6 changes: 2 additions & 4 deletions scripts-dev/complement.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ cd "$(dirname $0)/.."
docker build -t matrixdotorg/synapse:latest -f docker/Dockerfile .
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved

# Download Complement
wget -N https://github.com/matrix-org/complement/archive/master.tar.gz
tar -xzf master.tar.gz
cd complement-master
cd ../complement
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved

# Build the Synapse image from Complement, based on the above image we just built
docker build -t complement-synapse -f dockerfiles/Synapse.Dockerfile ./dockerfiles

# Run the tests on the resulting image!
COMPLEMENT_BASE_IMAGE=complement-synapse go test -v -count=1 ./tests
COMPLEMENT_BASE_IMAGE=complement-synapse go test -tags msc2716 -v -count=1 ./tests/main_test.go ./tests/msc2716_test.go
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
13 changes: 11 additions & 2 deletions synapse/events/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ def is_state(self):
return self._state_key is not None

async def build(
self, prev_event_ids: List[str], auth_event_ids: Optional[List[str]],
self,
prev_event_ids: List[str],
overriding_prev_events: Literal[False] = False,
auth_event_ids: Optional[List[str]],
) -> EventBase:
"""Transform into a fully signed and hashed event

Expand Down Expand Up @@ -131,7 +134,13 @@ async def build(
prev_events = prev_event_ids

old_depth = await self._store.get_max_depth_of(prev_event_ids)
depth = old_depth + 1
# awfewafeafew depth stuff
# If backfilling old message, let's just use the same depth of what we're inserting next to
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
if overriding_prev_events:
depth = old_depth
# Otherwise, progress the depth as normal
else:
depth = old_depth + 1

# we cap depth of generated events, to ensure that they are not
# rejected by other servers (and so that they can be persisted in
Expand Down
14 changes: 7 additions & 7 deletions synapse/events/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ def format_event_for_client_v1(d):

def format_event_for_client_v2(d):
drop_keys = (
"auth_events",
"prev_events",
"hashes",
"signatures",
"depth",
"origin",
"prev_state",
# "auth_events",
# "prev_events",
# "hashes",
# "signatures",
# "depth",
# "origin",
# "prev_state",
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
)
for key in drop_keys:
d.pop(key, None)
Expand Down
13 changes: 11 additions & 2 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,12 @@ async def create_and_send_nonmember_event(
assert event.internal_metadata.stream_ordering
return event, event.internal_metadata.stream_ordering

prev_events = None
if "prev_events" in event_dict:
prev_events = event_dict["prev_events"]
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved

event, context = await self.create_event(
requester, event_dict, txn_id=txn_id
requester, event_dict, txn_id=txn_id, prev_event_ids=prev_events
)

assert self.hs.is_mine_id(event.sender), "User must be our own: %s" % (
Expand Down Expand Up @@ -790,7 +794,10 @@ async def create_new_client_event(
Tuple of created event, context
"""

overriding_prev_events = False
if prev_event_ids is not None:
overriding_prev_events = True
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved

assert len(prev_event_ids) <= 10, (
"Attempting to create an event with %i prev_events"
% (len(prev_event_ids),)
Expand All @@ -808,7 +815,9 @@ async def create_new_client_event(
), "Attempting to create an event with no prev_events"

event = await builder.build(
prev_event_ids=prev_event_ids, auth_event_ids=auth_event_ids
prev_event_ids=prev_event_ids,
overriding_prev_events=overriding_prev_events,
auth_event_ids=auth_event_ids,
)
context = await self.state.compute_event_context(event)
if requester:
Expand Down
5 changes: 4 additions & 1 deletion synapse/handlers/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from synapse.util.caches.lrucache import LruCache
from synapse.util.caches.response_cache import ResponseCache
from synapse.util.metrics import Measure, measure_func
from synapse.visibility import filter_events_for_client
from synapse.visibility import filter_events_for_client, filter_historical_events

if TYPE_CHECKING:
from synapse.server import HomeServer
Expand Down Expand Up @@ -534,6 +534,9 @@ async def _load_filtered_recents(

prev_batch_token = now_token.copy_and_replace("room_key", room_key)

# `m.historical` events should not come down /sync
recents = await filter_historical_events(recents)

return TimelineBatch(
events=recents,
prev_batch=prev_batch_token,
Expand Down
72 changes: 52 additions & 20 deletions synapse/http/servlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
""" This module contains base REST classes for constructing REST servlets. """

import logging
from typing import List

from synapse.api.errors import Codes, SynapseError
from synapse.util import json_decoder
Expand Down Expand Up @@ -147,38 +148,43 @@ def parse_string(
)


def parse_string_from_args(
def parse_string_value(value, allowed_values, name="", encoding="ascii") -> str:
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
if encoding:
try:
value = value.decode(encoding)
except ValueError:
raise SynapseError(400, "Query parameter %r must be %s" % (name, encoding))

if allowed_values is not None and value not in allowed_values:
message = "Query parameter %r must be one of [%s]" % (
name,
", ".join(repr(v) for v in allowed_values),
)
raise SynapseError(400, message)
else:
return value


def parse_strings_from_args(
args,
name,
default=None,
required=False,
allowed_values=None,
param_type="string",
encoding="ascii",
):
) -> List[str]:

if not isinstance(name, bytes):
name = name.encode("ascii")

if name in args:
value = args[name][0]

if encoding:
try:
value = value.decode(encoding)
except ValueError:
raise SynapseError(
400, "Query parameter %r must be %s" % (name, encoding)
)

if allowed_values is not None and value not in allowed_values:
message = "Query parameter %r must be one of [%s]" % (
name,
", ".join(repr(v) for v in allowed_values),
)
raise SynapseError(400, message)
else:
return value
values = args[name]

return [
parse_string_value(value, allowed_values, name=name, encoding=encoding)
for value in values
]
else:
if required:
message = "Missing %s query parameter %r" % (param_type, name)
Expand All @@ -191,6 +197,32 @@ def parse_string_from_args(
return default


def parse_string_from_args(
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
args,
name,
default=None,
required=False,
allowed_values=None,
param_type="string",
encoding="ascii",
):
strings = parse_strings_from_args(
args,
name,
default=default,
required=required,
allowed_values=allowed_values,
param_type=param_type,
encoding=encoding,
)

if isinstance(strings, list) and len(strings):
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
return strings[0]

# Return the default
return strings


def parse_json_value_from_request(request, allow_empty_body=False):
"""Parse a JSON value from the body of a twisted HTTP request.

Expand Down
10 changes: 9 additions & 1 deletion synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
RestServlet,
assert_params_in_dict,
parse_integer,
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
parse_integer_from_args,
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
parse_json_object_from_request,
parse_strings_from_args,
parse_string,
)
from synapse.logging.opentracing import set_tag
Expand Down Expand Up @@ -222,6 +224,7 @@ def register(self, http_server):
async def on_POST(self, request, room_id, event_type, txn_id=None):
requester = await self.auth.get_user_by_req(request, allow_guest=True)
content = parse_json_object_from_request(request)
prev_events = parse_strings_from_args(request.args, "prev_event")

event_dict = {
"type": event_type,
Expand All @@ -230,7 +233,12 @@ async def on_POST(self, request, room_id, event_type, txn_id=None):
"sender": requester.user.to_string(),
}

if b"ts" in request.args and requester.app_service:
if prev_events:
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
event_dict["prev_events"] = prev_events

# TODO: Put app_service logic back in place once we figure out how to make the Complement tests
# run as an app service
if b"ts" in request.args: # and requester.app_service:
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
event_dict["origin_server_ts"] = parse_integer(request, "ts", 0)

try:
Expand Down
10 changes: 10 additions & 0 deletions synapse/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
)


async def filter_historical_events(events):
filtered_events = [e for e in events if not e.content.get("m.historical", None)]

# remove the None entries
filtered_events = filter(operator.truth, filtered_events)

# we turn it into a list before returning it.
return list(filtered_events)
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved


async def filter_events_for_client(
storage: Storage,
user_id,
Expand Down