Refactor the way we set `outlier` (#11634)
* `_auth_and_persist_outliers`: mark persisted events as outliers Mark any events that get persisted via `_auth_and_persist_outliers` as, well, outliers. Currently this will be a no-op as everything will already be flagged as an outlier, but I'm going to change that. * `process_remote_join`: stop flagging as outlier The events are now flagged as outliers later on, by `_auth_and_persist_outliers`. * `send_join`: remove `outlier=True` The events created here are returned in the result of `send_join` to `FederationHandler.do_invite_join`. From there they are passed into `FederationEventHandler.process_remote_join`, which passes them to `_auth_and_persist_outliers`... which sets the `outlier` flag. * `get_event_auth`: remove `outlier=True` stop flagging the events returned by `get_event_auth` as outliers. This method is only called by `_get_remote_auth_chain_for_event`, which passes the results into `_auth_and_persist_outliers`, which will flag them as outliers. * `_get_remote_auth_chain_for_event`: remove `outlier=True` we pass all the events into `_auth_and_persist_outliers`, which will now flag the events as outliers. * `_check_sigs_and_hash_and_fetch`: remove unused `outlier` parameter This param is now never set to True, so we can remove it. * `_check_sigs_and_hash_and_fetch_one`: remove unused `outlier` param This is no longer set anywhere, so we can remove it. * `get_pdu`: remove unused `outlier` parameter ... and chase it down into `get_pdu_from_destination_raw`. * `event_from_pdu_json`: remove redundant `outlier` param This is never set to `True`, so can be removed. * changelog * update docstringpull/11691/head
							parent
							
								
									eedb4527f1
								
							
						
					
					
						commit
						0fb3dd0830
					
				| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Refactor the way that the `outlier` flag is set on events received over federation.
 | 
				
			||||||
| 
						 | 
					@ -215,15 +215,12 @@ def _is_invite_via_3pid(event: EventBase) -> bool:
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def event_from_pdu_json(
 | 
					def event_from_pdu_json(pdu_json: JsonDict, room_version: RoomVersion) -> EventBase:
 | 
				
			||||||
    pdu_json: JsonDict, room_version: RoomVersion, outlier: bool = False
 | 
					 | 
				
			||||||
) -> EventBase:
 | 
					 | 
				
			||||||
    """Construct an EventBase from an event json received over federation
 | 
					    """Construct an EventBase from an event json received over federation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Args:
 | 
					    Args:
 | 
				
			||||||
        pdu_json: pdu as received over federation
 | 
					        pdu_json: pdu as received over federation
 | 
				
			||||||
        room_version: The version of the room this event belongs to
 | 
					        room_version: The version of the room this event belongs to
 | 
				
			||||||
        outlier: True to mark this event as an outlier
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Raises:
 | 
					    Raises:
 | 
				
			||||||
        SynapseError: if the pdu is missing required fields or is otherwise
 | 
					        SynapseError: if the pdu is missing required fields or is otherwise
 | 
				
			||||||
| 
						 | 
					@ -247,6 +244,4 @@ def event_from_pdu_json(
 | 
				
			||||||
        validate_canonicaljson(pdu_json)
 | 
					        validate_canonicaljson(pdu_json)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event = make_event_from_dict(pdu_json, room_version)
 | 
					    event = make_event_from_dict(pdu_json, room_version)
 | 
				
			||||||
    event.internal_metadata.outlier = outlier
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return event
 | 
					    return event
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,10 +265,7 @@ class FederationClient(FederationBase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        room_version = await self.store.get_room_version(room_id)
 | 
					        room_version = await self.store.get_room_version(room_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pdus = [
 | 
					        pdus = [event_from_pdu_json(p, room_version) for p in transaction_data_pdus]
 | 
				
			||||||
            event_from_pdu_json(p, room_version, outlier=False)
 | 
					 | 
				
			||||||
            for p in transaction_data_pdus
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check signatures and hash of pdus, removing any from the list that fail checks
 | 
					        # Check signatures and hash of pdus, removing any from the list that fail checks
 | 
				
			||||||
        pdus[:] = await self._check_sigs_and_hash_and_fetch(
 | 
					        pdus[:] = await self._check_sigs_and_hash_and_fetch(
 | 
				
			||||||
| 
						 | 
					@ -282,7 +279,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
        destination: str,
 | 
					        destination: str,
 | 
				
			||||||
        event_id: str,
 | 
					        event_id: str,
 | 
				
			||||||
        room_version: RoomVersion,
 | 
					        room_version: RoomVersion,
 | 
				
			||||||
        outlier: bool = False,
 | 
					 | 
				
			||||||
        timeout: Optional[int] = None,
 | 
					        timeout: Optional[int] = None,
 | 
				
			||||||
    ) -> Optional[EventBase]:
 | 
					    ) -> Optional[EventBase]:
 | 
				
			||||||
        """Requests the PDU with given origin and ID from the remote home
 | 
					        """Requests the PDU with given origin and ID from the remote home
 | 
				
			||||||
| 
						 | 
					@ -292,9 +288,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            destination: Which homeserver to query
 | 
					            destination: Which homeserver to query
 | 
				
			||||||
            event_id: event to fetch
 | 
					            event_id: event to fetch
 | 
				
			||||||
            room_version: version of the room
 | 
					            room_version: version of the room
 | 
				
			||||||
            outlier: Indicates whether the PDU is an `outlier`, i.e. if
 | 
					 | 
				
			||||||
                it's from an arbitrary point in the context as opposed to part
 | 
					 | 
				
			||||||
                of the current block of PDUs. Defaults to `False`
 | 
					 | 
				
			||||||
            timeout: How long to try (in ms) each destination for before
 | 
					            timeout: How long to try (in ms) each destination for before
 | 
				
			||||||
                moving to the next destination. None indicates no timeout.
 | 
					                moving to the next destination. None indicates no timeout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,8 +309,7 @@ class FederationClient(FederationBase):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pdu_list: List[EventBase] = [
 | 
					        pdu_list: List[EventBase] = [
 | 
				
			||||||
            event_from_pdu_json(p, room_version, outlier=outlier)
 | 
					            event_from_pdu_json(p, room_version) for p in transaction_data["pdus"]
 | 
				
			||||||
            for p in transaction_data["pdus"]
 | 
					 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if pdu_list and pdu_list[0]:
 | 
					        if pdu_list and pdu_list[0]:
 | 
				
			||||||
| 
						 | 
					@ -334,7 +326,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
        destinations: Iterable[str],
 | 
					        destinations: Iterable[str],
 | 
				
			||||||
        event_id: str,
 | 
					        event_id: str,
 | 
				
			||||||
        room_version: RoomVersion,
 | 
					        room_version: RoomVersion,
 | 
				
			||||||
        outlier: bool = False,
 | 
					 | 
				
			||||||
        timeout: Optional[int] = None,
 | 
					        timeout: Optional[int] = None,
 | 
				
			||||||
    ) -> Optional[EventBase]:
 | 
					    ) -> Optional[EventBase]:
 | 
				
			||||||
        """Requests the PDU with given origin and ID from the remote home
 | 
					        """Requests the PDU with given origin and ID from the remote home
 | 
				
			||||||
| 
						 | 
					@ -347,9 +338,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            destinations: Which homeservers to query
 | 
					            destinations: Which homeservers to query
 | 
				
			||||||
            event_id: event to fetch
 | 
					            event_id: event to fetch
 | 
				
			||||||
            room_version: version of the room
 | 
					            room_version: version of the room
 | 
				
			||||||
            outlier: Indicates whether the PDU is an `outlier`, i.e. if
 | 
					 | 
				
			||||||
                it's from an arbitrary point in the context as opposed to part
 | 
					 | 
				
			||||||
                of the current block of PDUs. Defaults to `False`
 | 
					 | 
				
			||||||
            timeout: How long to try (in ms) each destination for before
 | 
					            timeout: How long to try (in ms) each destination for before
 | 
				
			||||||
                moving to the next destination. None indicates no timeout.
 | 
					                moving to the next destination. None indicates no timeout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -377,7 +365,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
                    destination=destination,
 | 
					                    destination=destination,
 | 
				
			||||||
                    event_id=event_id,
 | 
					                    event_id=event_id,
 | 
				
			||||||
                    room_version=room_version,
 | 
					                    room_version=room_version,
 | 
				
			||||||
                    outlier=outlier,
 | 
					 | 
				
			||||||
                    timeout=timeout,
 | 
					                    timeout=timeout,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -435,7 +422,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
        origin: str,
 | 
					        origin: str,
 | 
				
			||||||
        pdus: Collection[EventBase],
 | 
					        pdus: Collection[EventBase],
 | 
				
			||||||
        room_version: RoomVersion,
 | 
					        room_version: RoomVersion,
 | 
				
			||||||
        outlier: bool = False,
 | 
					 | 
				
			||||||
    ) -> List[EventBase]:
 | 
					    ) -> List[EventBase]:
 | 
				
			||||||
        """Takes a list of PDUs and checks the signatures and hashes of each
 | 
					        """Takes a list of PDUs and checks the signatures and hashes of each
 | 
				
			||||||
        one. If a PDU fails its signature check then we check if we have it in
 | 
					        one. If a PDU fails its signature check then we check if we have it in
 | 
				
			||||||
| 
						 | 
					@ -451,7 +437,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            origin
 | 
					            origin
 | 
				
			||||||
            pdu
 | 
					            pdu
 | 
				
			||||||
            room_version
 | 
					            room_version
 | 
				
			||||||
            outlier: Whether the events are outliers or not
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            A list of PDUs that have valid signatures and hashes.
 | 
					            A list of PDUs that have valid signatures and hashes.
 | 
				
			||||||
| 
						 | 
					@ -466,7 +451,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
					            valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
				
			||||||
                pdu=pdu,
 | 
					                pdu=pdu,
 | 
				
			||||||
                origin=origin,
 | 
					                origin=origin,
 | 
				
			||||||
                outlier=outlier,
 | 
					 | 
				
			||||||
                room_version=room_version,
 | 
					                room_version=room_version,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +466,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
        pdu: EventBase,
 | 
					        pdu: EventBase,
 | 
				
			||||||
        origin: str,
 | 
					        origin: str,
 | 
				
			||||||
        room_version: RoomVersion,
 | 
					        room_version: RoomVersion,
 | 
				
			||||||
        outlier: bool = False,
 | 
					 | 
				
			||||||
    ) -> Optional[EventBase]:
 | 
					    ) -> Optional[EventBase]:
 | 
				
			||||||
        """Takes a PDU and checks its signatures and hashes. If the PDU fails
 | 
					        """Takes a PDU and checks its signatures and hashes. If the PDU fails
 | 
				
			||||||
        its signature check then we check if we have it in the database and if
 | 
					        its signature check then we check if we have it in the database and if
 | 
				
			||||||
| 
						 | 
					@ -494,9 +477,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            origin
 | 
					            origin
 | 
				
			||||||
            pdu
 | 
					            pdu
 | 
				
			||||||
            room_version
 | 
					            room_version
 | 
				
			||||||
            outlier: Whether the events are outliers or not
 | 
					 | 
				
			||||||
            include_none: Whether to include None in the returned list
 | 
					 | 
				
			||||||
                for events that have failed their checks
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            The PDU (possibly redacted) if it has valid signatures and hashes.
 | 
					            The PDU (possibly redacted) if it has valid signatures and hashes.
 | 
				
			||||||
| 
						 | 
					@ -521,7 +501,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
                    destinations=[pdu_origin],
 | 
					                    destinations=[pdu_origin],
 | 
				
			||||||
                    event_id=pdu.event_id,
 | 
					                    event_id=pdu.event_id,
 | 
				
			||||||
                    room_version=room_version,
 | 
					                    room_version=room_version,
 | 
				
			||||||
                    outlier=outlier,
 | 
					 | 
				
			||||||
                    timeout=10000,
 | 
					                    timeout=10000,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            except SynapseError:
 | 
					            except SynapseError:
 | 
				
			||||||
| 
						 | 
					@ -541,13 +520,10 @@ class FederationClient(FederationBase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        room_version = await self.store.get_room_version(room_id)
 | 
					        room_version = await self.store.get_room_version(room_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auth_chain = [
 | 
					        auth_chain = [event_from_pdu_json(p, room_version) for p in res["auth_chain"]]
 | 
				
			||||||
            event_from_pdu_json(p, room_version, outlier=True)
 | 
					 | 
				
			||||||
            for p in res["auth_chain"]
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        signed_auth = await self._check_sigs_and_hash_and_fetch(
 | 
					        signed_auth = await self._check_sigs_and_hash_and_fetch(
 | 
				
			||||||
            destination, auth_chain, outlier=True, room_version=room_version
 | 
					            destination, auth_chain, room_version=room_version
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return signed_auth
 | 
					        return signed_auth
 | 
				
			||||||
| 
						 | 
					@ -816,7 +792,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
                valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
					                valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
				
			||||||
                    pdu=event,
 | 
					                    pdu=event,
 | 
				
			||||||
                    origin=destination,
 | 
					                    origin=destination,
 | 
				
			||||||
                    outlier=True,
 | 
					 | 
				
			||||||
                    room_version=room_version,
 | 
					                    room_version=room_version,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -864,7 +839,6 @@ class FederationClient(FederationBase):
 | 
				
			||||||
                valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
					                valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
 | 
				
			||||||
                    pdu=pdu,
 | 
					                    pdu=pdu,
 | 
				
			||||||
                    origin=destination,
 | 
					                    origin=destination,
 | 
				
			||||||
                    outlier=True,
 | 
					 | 
				
			||||||
                    room_version=room_version,
 | 
					                    room_version=room_version,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1235,7 +1209,7 @@ class FederationClient(FederationBase):
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            signed_events = await self._check_sigs_and_hash_and_fetch(
 | 
					            signed_events = await self._check_sigs_and_hash_and_fetch(
 | 
				
			||||||
                destination, events, outlier=False, room_version=room_version
 | 
					                destination, events, room_version=room_version
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        except HttpResponseException as e:
 | 
					        except HttpResponseException as e:
 | 
				
			||||||
            if not e.code == 400:
 | 
					            if not e.code == 400:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -421,9 +421,6 @@ class FederationEventHandler:
 | 
				
			||||||
        Raises:
 | 
					        Raises:
 | 
				
			||||||
            SynapseError if the response is in some way invalid.
 | 
					            SynapseError if the response is in some way invalid.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        for e in itertools.chain(auth_events, state):
 | 
					 | 
				
			||||||
            e.internal_metadata.outlier = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        event_map = {e.event_id: e for e in itertools.chain(auth_events, state)}
 | 
					        event_map = {e.event_id: e for e in itertools.chain(auth_events, state)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        create_event = None
 | 
					        create_event = None
 | 
				
			||||||
| 
						 | 
					@ -1194,7 +1191,6 @@ class FederationEventHandler:
 | 
				
			||||||
                        [destination],
 | 
					                        [destination],
 | 
				
			||||||
                        event_id,
 | 
					                        event_id,
 | 
				
			||||||
                        room_version,
 | 
					                        room_version,
 | 
				
			||||||
                        outlier=True,
 | 
					 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    if event is None:
 | 
					                    if event is None:
 | 
				
			||||||
                        logger.warning(
 | 
					                        logger.warning(
 | 
				
			||||||
| 
						 | 
					@ -1223,9 +1219,10 @@ class FederationEventHandler:
 | 
				
			||||||
        """Persist a batch of outlier events fetched from remote servers.
 | 
					        """Persist a batch of outlier events fetched from remote servers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        We first sort the events to make sure that we process each event's auth_events
 | 
					        We first sort the events to make sure that we process each event's auth_events
 | 
				
			||||||
        before the event itself, and then auth and persist them.
 | 
					        before the event itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Notifies about the events where appropriate.
 | 
					        We then mark the events as outliers, persist them to the database, and, where
 | 
				
			||||||
 | 
					        appropriate (eg, an invite), awake the notifier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Params:
 | 
					        Params:
 | 
				
			||||||
            room_id: the room that the events are meant to be in (though this has
 | 
					            room_id: the room that the events are meant to be in (though this has
 | 
				
			||||||
| 
						 | 
					@ -1276,7 +1273,8 @@ class FederationEventHandler:
 | 
				
			||||||
        Persists a batch of events where we have (theoretically) already persisted all
 | 
					        Persists a batch of events where we have (theoretically) already persisted all
 | 
				
			||||||
        of their auth events.
 | 
					        of their auth events.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Notifies about the events where appropriate.
 | 
					        Marks the events as outliers, auths them, persists them to the database, and,
 | 
				
			||||||
 | 
					        where appropriate (eg, an invite), awakes the notifier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Params:
 | 
					        Params:
 | 
				
			||||||
            origin: where the events came from
 | 
					            origin: where the events came from
 | 
				
			||||||
| 
						 | 
					@ -1314,6 +1312,9 @@ class FederationEventHandler:
 | 
				
			||||||
                        return None
 | 
					                        return None
 | 
				
			||||||
                    auth.append(ae)
 | 
					                    auth.append(ae)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # we're not bothering about room state, so flag the event as an outlier.
 | 
				
			||||||
 | 
					                event.internal_metadata.outlier = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                context = EventContext.for_outlier()
 | 
					                context = EventContext.for_outlier()
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    validate_event_for_room_version(room_version_obj, event)
 | 
					                    validate_event_for_room_version(room_version_obj, event)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -373,9 +373,7 @@ class FederationTestCase(unittest.HomeserverTestCase):
 | 
				
			||||||
            destination: str, room_id: str, event_id: str
 | 
					            destination: str, room_id: str, event_id: str
 | 
				
			||||||
        ) -> List[EventBase]:
 | 
					        ) -> List[EventBase]:
 | 
				
			||||||
            return [
 | 
					            return [
 | 
				
			||||||
                event_from_pdu_json(
 | 
					                event_from_pdu_json(ae.get_pdu_json(), room_version=room_version)
 | 
				
			||||||
                    ae.get_pdu_json(), room_version=room_version, outlier=True
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                for ae in auth_events
 | 
					                for ae in auth_events
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue