@ -173,6 +173,9 @@ class FederationEventHandler:
pdu : received PDU
pdu : received PDU
"""
"""
# We should never see any outliers here.
assert not pdu . internal_metadata . outlier
room_id = pdu . room_id
room_id = pdu . room_id
event_id = pdu . event_id
event_id = pdu . event_id
@ -232,77 +235,71 @@ class FederationEventHandler:
)
)
return None
return None
# Check that the event passes auth based on the state at the event. This is
# Try to fetch any missing prev events to fill in gaps in the graph
# done for events that are to be added to the timeline (non-outliers).
prevs = set ( pdu . prev_event_ids ( ) )
#
seen = await self . _store . have_events_in_timeline ( prevs )
# Get missing pdus if necessary:
missing_prevs = prevs - seen
# - Fetching any missing prev events to fill in gaps in the graph
# - Fetching state if we have a hole in the graph
if not pdu . internal_metadata . is_outlier ( ) :
prevs = set ( pdu . prev_event_ids ( ) )
seen = await self . _store . have_events_in_timeline ( prevs )
missing_prevs = prevs - seen
if missing_prevs :
if missing_prevs :
# We only backfill backwards to the min depth.
# We only backfill backwards to the min depth.
min_depth = await self . get_min_depth_for_context ( pdu . room_id )
min_depth = await self . get_min_depth_for_context ( pdu . room_id )
logger . debug ( " min_depth: %d " , min_depth )
logger . debug ( " min_depth: %d " , min_depth )
if min_depth is not None and pdu . depth > min_depth :
if min_depth is not None and pdu . depth > min_depth :
# If we're missing stuff, ensure we only fetch stuff one
# If we're missing stuff, ensure we only fetch stuff one
# at a time.
# at a time.
logger . info (
" Acquiring room lock to fetch %d missing prev_events: %s " ,
len ( missing_prevs ) ,
shortstr ( missing_prevs ) ,
)
with ( await self . _room_pdu_linearizer . queue ( pdu . room_id ) ) :
logger . info (
logger . info (
" Acquiring room lock to fetch %d missing prev_events: %s " ,
" Acquired room lock to fetch %d missing prev_events " ,
len ( missing_prevs ) ,
len ( missing_prevs ) ,
shortstr ( missing_prevs ) ,
)
)
with ( await self . _room_pdu_linearizer . queue ( pdu . room_id ) ) :
logger . info (
try :
" Acquired room lock to fetch %d missing prev_events " ,
await self . _get_missing_events_for_pdu (
len ( missing_prevs ) ,
origin , pdu , prevs , min_depth
)
)
except Exception as e :
raise Exception (
" Error fetching missing prev_events for %s : %s "
% ( event_id , e )
) from e
try :
# Update the set of things we've seen after trying to
await self . _get_missing_events_for_pdu (
# fetch the missing stuff
origin , pdu , prevs , min_depth
seen = await self . _store . have_events_in_timeline ( prevs )
)
missing_prevs = prevs - seen
except Exception as e :
raise Exception (
if not missing_prevs :
" Error fetching missing prev_events for %s : %s "
logger . info ( " Found all missing prev_events " )
% ( event_id , e )
) from e
if missing_prevs :
# since this event was pushed to us, it is possible for it to
# Update the set of things we've seen after trying to
# become the only forward-extremity in the room, and we would then
# fetch the missing stuff
# trust its state to be the state for the whole room. This is very
seen = await self . _store . have_events_in_timeline ( prevs )
# bad. Further, if the event was pushed to us, there is no excuse
missing_prevs = prevs - seen
# for us not to have all the prev_events. (XXX: apart from
# min_depth?)
if not missing_prevs :
#
logger . info ( " Found all missing prev_events " )
# We therefore reject any such events.
logger . warning (
if missing_prevs :
" Rejecting: failed to fetch %d prev events: %s " ,
# since this event was pushed to us, it is possible for it to
len ( missing_prevs ) ,
# become the only forward-extremity in the room, and we would then
shortstr ( missing_prevs ) ,
# trust its state to be the state for the whole room. This is very
)
# bad. Further, if the event was pushed to us, there is no excuse
raise FederationError (
# for us not to have all the prev_events. (XXX: apart from
" ERROR " ,
# min_depth?)
403 ,
#
(
# We therefore reject any such events.
" Your server isn ' t divulging details about prev_events "
logger . warning (
" referenced in this event. "
" Rejecting: failed to fetch %d prev events: %s " ,
) ,
len ( missing_prevs ) ,
affected = pdu . event_id ,
shortstr ( missing_prevs ) ,
)
)
raise FederationError (
" ERROR " ,
403 ,
(
" Your server isn ' t divulging details about prev_events "
" referenced in this event. "
) ,
affected = pdu . event_id ,
)
await self . _process_received_pdu ( origin , pdu , state = None )
await self . _process_received_pdu ( origin , pdu , state = None )
@ -885,8 +882,13 @@ class FederationEventHandler:
state : Optional [ Iterable [ EventBase ] ] ,
state : Optional [ Iterable [ EventBase ] ] ,
backfilled : bool = False ,
backfilled : bool = False ,
) - > None :
) - > None :
""" Called when we have a new pdu. We need to do auth checks and put it
""" Called when we have a new non-outlier event.
through the StateHandler .
This is called when we have a new event to add to the room DAG - either directly
via a / send request , retrieved via get_missing_events after a / send request , or
backfilled after a client request .
We need to do auth checks and put it through the StateHandler .
Args :
Args :
origin : server sending the event
origin : server sending the event
@ -901,6 +903,7 @@ class FederationEventHandler:
notification to clients , and validation of device keys . )
notification to clients , and validation of device keys . )
"""
"""
logger . debug ( " Processing event: %s " , event )
logger . debug ( " Processing event: %s " , event )
assert not event . internal_metadata . outlier
try :
try :
context = await self . _state_handler . compute_event_context (
context = await self . _state_handler . compute_event_context (
@ -1263,11 +1266,13 @@ class FederationEventHandler:
Possibly incomplete , and possibly including events that are not yet
Possibly incomplete , and possibly including events that are not yet
persisted , or authed , or in the right room .
persisted , or authed , or in the right room .
Only populated where we may not already have persisted these events -
Only populated when populating outliers .
for example , when populating outliers .
backfilled : True if the event was backfilled .
backfilled : True if the event was backfilled .
"""
"""
# claimed_auth_event_map should be given iff the event is an outlier
assert bool ( claimed_auth_event_map ) == event . internal_metadata . outlier
context = await self . _check_event_auth (
context = await self . _check_event_auth (
origin ,
origin ,
event ,
event ,
@ -1306,15 +1311,16 @@ class FederationEventHandler:
Possibly incomplete , and possibly including events that are not yet
Possibly incomplete , and possibly including events that are not yet
persisted , or authed , or in the right room .
persisted , or authed , or in the right room .
Only populated where we may not already have persisted these events -
Only populated when populating outliers .
for example , when populating outliers , or the state for a backwards
extremity .
backfilled : True if the event was backfilled .
backfilled : True if the event was backfilled .
Returns :
Returns :
The updated context object .
The updated context object .
"""
"""
# claimed_auth_event_map should be given iff the event is an outlier
assert bool ( claimed_auth_event_map ) == event . internal_metadata . outlier
room_version = await self . _store . get_room_version_id ( event . room_id )
room_version = await self . _store . get_room_version_id ( event . room_id )
room_version_obj = KNOWN_ROOM_VERSIONS [ room_version ]
room_version_obj = KNOWN_ROOM_VERSIONS [ room_version ]