|
23 | 23 | import collections.abc
|
24 | 24 | import logging
|
25 | 25 | import typing
|
26 |
| -from typing import Any, Dict, Iterable, List, Mapping, Optional, Set, Tuple, Union |
| 26 | +from typing import ( |
| 27 | + Any, |
| 28 | + ChainMap, |
| 29 | + Dict, |
| 30 | + Iterable, |
| 31 | + List, |
| 32 | + Mapping, |
| 33 | + MutableMapping, |
| 34 | + Optional, |
| 35 | + Set, |
| 36 | + Tuple, |
| 37 | + Union, |
| 38 | + cast, |
| 39 | +) |
27 | 40 |
|
28 | 41 | from canonicaljson import encode_canonical_json
|
29 | 42 | from signedjson.key import decode_verify_key_bytes
|
@@ -175,23 +188,35 @@ async def check_state_independent_auth_rules(
|
175 | 188 | return
|
176 | 189 |
|
177 | 190 | # 2. Reject if event has auth_events that: ...
|
| 191 | + auth_events: ChainMap[str, EventBase] = ChainMap() |
178 | 192 | if batched_auth_events:
|
179 |
| - # Copy the batched auth events to avoid mutating them. |
180 |
| - auth_events = dict(batched_auth_events) |
181 |
| - needed_auth_event_ids = set(event.auth_event_ids()) - batched_auth_events.keys() |
| 193 | + # batched_auth_events can become very large. To avoid repeatedly copying it, which |
| 194 | + # would significantly impact performance, we use a ChainMap. |
| 195 | + # batched_auth_events must be cast to MutableMapping because .new_child() requires |
| 196 | + # this type. This casting is safe as the mapping is never mutated. |
| 197 | + auth_events = auth_events.new_child( |
| 198 | + cast(MutableMapping[str, "EventBase"], batched_auth_events) |
| 199 | + ) |
| 200 | + needed_auth_event_ids = [ |
| 201 | + event_id |
| 202 | + for event_id in event.auth_event_ids() |
| 203 | + if event_id not in batched_auth_events |
| 204 | + ] |
182 | 205 | if needed_auth_event_ids:
|
183 |
| - auth_events.update( |
| 206 | + auth_events = auth_events.new_child( |
184 | 207 | await store.get_events(
|
185 | 208 | needed_auth_event_ids,
|
186 | 209 | redact_behaviour=EventRedactBehaviour.as_is,
|
187 | 210 | allow_rejected=True,
|
188 | 211 | )
|
189 | 212 | )
|
190 | 213 | else:
|
191 |
| - auth_events = await store.get_events( |
192 |
| - event.auth_event_ids(), |
193 |
| - redact_behaviour=EventRedactBehaviour.as_is, |
194 |
| - allow_rejected=True, |
| 214 | + auth_events = auth_events.new_child( |
| 215 | + await store.get_events( |
| 216 | + event.auth_event_ids(), |
| 217 | + redact_behaviour=EventRedactBehaviour.as_is, |
| 218 | + allow_rejected=True, |
| 219 | + ) |
195 | 220 | )
|
196 | 221 |
|
197 | 222 | room_id = event.room_id
|
|
0 commit comments