Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent locking up while processing batched_auth_events #16968

Merged
merged 30 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2c5dc1e
deepcopy batched_auth_events
ggogel Feb 27, 2024
6611341
add changelog
ggogel Feb 27, 2024
0bf1f1f
create copy with make_event_from_dict
ggogel Feb 27, 2024
80fc96e
deepcopy event_dict
ggogel Feb 27, 2024
ccf3011
only copy required attributes
ggogel Feb 27, 2024
1687238
remove auth_events copy and update logic
ggogel Feb 27, 2024
af20b24
only update needed auth events
ggogel Feb 27, 2024
f780f5b
remove import copy
ggogel Feb 27, 2024
711a57d
remove import make_event_from_dict
ggogel Feb 27, 2024
a3bfc23
update changelog
ggogel Feb 27, 2024
0263502
Revert "only update needed auth events"
ggogel Feb 28, 2024
05a00b2
Revert "Revert "only update needed auth events""
ggogel Feb 28, 2024
7d1f98c
do not nest store.get_events in update
ggogel Feb 28, 2024
e1cc684
use a list comprehension instead of set operation
ggogel Feb 28, 2024
e635637
linting
ggogel Mar 4, 2024
e65cabd
type auth_events
ggogel Mar 4, 2024
a4534ed
dict batched_auth_events
ggogel Mar 5, 2024
8197f84
isort lint
ggogel Mar 5, 2024
e199b27
update changelog
ggogel Mar 5, 2024
deba2ce
Revert "dict batched_auth_events"
ggogel Mar 7, 2024
a3fa553
use update
ggogel Mar 8, 2024
3826b99
Revert "use update"
ggogel Mar 8, 2024
31bf88b
add items individually
ggogel Mar 8, 2024
eee0a2b
use unpacking operator
ggogel Mar 8, 2024
d13f298
use cast
ggogel Mar 8, 2024
5bd7d93
update only if needed auth events exist
ggogel Mar 9, 2024
7ccf264
use ChainMap
ggogel Mar 11, 2024
1fc776c
fix isort
ggogel Mar 11, 2024
b6bba10
add comments
ggogel Mar 11, 2024
5fd55d1
linting
ggogel Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/16968.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prevent locking up when checking auth rules that are independent of room state for batched auth events. Contributed by @ggogel.
43 changes: 34 additions & 9 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,20 @@
import collections.abc
import logging
import typing
from typing import Any, Dict, Iterable, List, Mapping, Optional, Set, Tuple, Union
from typing import (
Any,
ChainMap,
Dict,
Iterable,
List,
Mapping,
MutableMapping,
Optional,
Set,
Tuple,
Union,
cast,
)

from canonicaljson import encode_canonical_json
from signedjson.key import decode_verify_key_bytes
Expand Down Expand Up @@ -175,23 +188,35 @@ async def check_state_independent_auth_rules(
return

# 2. Reject if event has auth_events that: ...
auth_events: ChainMap[str, EventBase] = ChainMap()
if batched_auth_events:
# Copy the batched auth events to avoid mutating them.
auth_events = dict(batched_auth_events)
needed_auth_event_ids = set(event.auth_event_ids()) - batched_auth_events.keys()
# batched_auth_events can become very large. To avoid repeatedly copying it, which
# would significantly impact performance, we use a ChainMap.
# batched_auth_events must be cast to MutableMapping because .new_child() requires
# this type. This casting is safe as the mapping is never mutated.
auth_events = auth_events.new_child(
cast(MutableMapping[str, "EventBase"], batched_auth_events)
)
needed_auth_event_ids = [
event_id
for event_id in event.auth_event_ids()
if event_id not in batched_auth_events
]
if needed_auth_event_ids:
auth_events.update(
auth_events = auth_events.new_child(
await store.get_events(
needed_auth_event_ids,
redact_behaviour=EventRedactBehaviour.as_is,
allow_rejected=True,
)
)
else:
auth_events = await store.get_events(
event.auth_event_ids(),
redact_behaviour=EventRedactBehaviour.as_is,
allow_rejected=True,
auth_events = auth_events.new_child(
await store.get_events(
event.auth_event_ids(),
redact_behaviour=EventRedactBehaviour.as_is,
allow_rejected=True,
)
)

room_id = event.room_id
Expand Down