@@ -482,6 +482,9 @@ async def create_event(
482
482
prev_event_ids : Optional [List [str ]] = None ,
483
483
auth_event_ids : Optional [List [str ]] = None ,
484
484
require_consent : bool = True ,
485
+ outlier : bool = False ,
486
+ historical : bool = False ,
487
+ depth : Optional [int ] = None ,
485
488
) -> Tuple [EventBase , EventContext ]:
486
489
"""
487
490
Given a dict from a client, create a new event.
@@ -508,6 +511,14 @@ async def create_event(
508
511
509
512
require_consent: Whether to check if the requester has
510
513
consented to the privacy policy.
514
+
515
+ outlier: Indicates whether the event is an `outlier`, i.e. if
516
+ it's from an arbitrary point and floating in the DAG as
517
+ opposed to being inline with the current DAG.
518
+ depth: Override the depth used to order the event in the DAG.
519
+ Should normally be set to None, which will cause the depth to be calculated
520
+ based on the prev_events.
521
+
511
522
Raises:
512
523
ResourceLimitError if server is blocked to some resource being
513
524
exceeded
@@ -563,11 +574,36 @@ async def create_event(
563
574
if txn_id is not None :
564
575
builder .internal_metadata .txn_id = txn_id
565
576
577
+ builder .internal_metadata .outlier = outlier
578
+
579
+ builder .internal_metadata .historical = historical
580
+
581
+ # Strip down the auth_event_ids to only what we need to auth the event.
582
+ # For example, we don't need extra m.room.member that don't match event.sender
583
+ if auth_event_ids is not None :
584
+ temp_event = await builder .build (
585
+ prev_event_ids = prev_event_ids ,
586
+ auth_event_ids = auth_event_ids ,
587
+ depth = depth ,
588
+ )
589
+ auth_events = await self .store .get_events_as_list (auth_event_ids )
590
+ # Create a StateMap[str]
591
+ auth_event_state_map = {
592
+ (e .type , e .state_key ): e .event_id for e in auth_events
593
+ }
594
+ # Actually strip down and use the necessary auth events
595
+ auth_event_ids = self .auth .compute_auth_events (
596
+ event = temp_event ,
597
+ current_state_ids = auth_event_state_map ,
598
+ for_verification = False ,
599
+ )
600
+
566
601
event , context = await self .create_new_client_event (
567
602
builder = builder ,
568
603
requester = requester ,
569
604
prev_event_ids = prev_event_ids ,
570
605
auth_event_ids = auth_event_ids ,
606
+ depth = depth ,
571
607
)
572
608
573
609
# In an ideal world we wouldn't need the second part of this condition. However,
@@ -724,9 +760,13 @@ async def create_and_send_nonmember_event(
724
760
self ,
725
761
requester : Requester ,
726
762
event_dict : dict ,
763
+ prev_event_ids : Optional [List [str ]] = None ,
764
+ auth_event_ids : Optional [List [str ]] = None ,
727
765
ratelimit : bool = True ,
728
766
txn_id : Optional [str ] = None ,
729
767
ignore_shadow_ban : bool = False ,
768
+ outlier : bool = False ,
769
+ depth : Optional [int ] = None ,
730
770
) -> Tuple [EventBase , int ]:
731
771
"""
732
772
Creates an event, then sends it.
@@ -736,10 +776,24 @@ async def create_and_send_nonmember_event(
736
776
Args:
737
777
requester: The requester sending the event.
738
778
event_dict: An entire event.
779
+ prev_event_ids:
780
+ The event IDs to use as the prev events.
781
+ Should normally be left as None to automatically request them
782
+ from the database.
783
+ auth_event_ids:
784
+ The event ids to use as the auth_events for the new event.
785
+ Should normally be left as None, which will cause them to be calculated
786
+ based on the room state at the prev_events.
739
787
ratelimit: Whether to rate limit this send.
740
788
txn_id: The transaction ID.
741
789
ignore_shadow_ban: True if shadow-banned users should be allowed to
742
790
send this event.
791
+ outlier: Indicates whether the event is an `outlier`, i.e. if
792
+ it's from an arbitrary point and floating in the DAG as
793
+ opposed to being inline with the current DAG.
794
+ depth: Override the depth used to order the event in the DAG.
795
+ Should normally be set to None, which will cause the depth to be calculated
796
+ based on the prev_events.
743
797
744
798
Returns:
745
799
The event, and its stream ordering (if deduplication happened,
@@ -779,7 +833,13 @@ async def create_and_send_nonmember_event(
779
833
return event , event .internal_metadata .stream_ordering
780
834
781
835
event , context = await self .create_event (
782
- requester , event_dict , txn_id = txn_id
836
+ requester ,
837
+ event_dict ,
838
+ txn_id = txn_id ,
839
+ prev_event_ids = prev_event_ids ,
840
+ auth_event_ids = auth_event_ids ,
841
+ outlier = outlier ,
842
+ depth = depth ,
783
843
)
784
844
785
845
assert self .hs .is_mine_id (event .sender ), "User must be our own: %s" % (
@@ -811,6 +871,7 @@ async def create_new_client_event(
811
871
requester : Optional [Requester ] = None ,
812
872
prev_event_ids : Optional [List [str ]] = None ,
813
873
auth_event_ids : Optional [List [str ]] = None ,
874
+ depth : Optional [int ] = None ,
814
875
) -> Tuple [EventBase , EventContext ]:
815
876
"""Create a new event for a local client
816
877
@@ -828,6 +889,10 @@ async def create_new_client_event(
828
889
Should normally be left as None, which will cause them to be calculated
829
890
based on the room state at the prev_events.
830
891
892
+ depth: Override the depth used to order the event in the DAG.
893
+ Should normally be set to None, which will cause the depth to be calculated
894
+ based on the prev_events.
895
+
831
896
Returns:
832
897
Tuple of created event, context
833
898
"""
@@ -851,9 +916,24 @@ async def create_new_client_event(
851
916
), "Attempting to create an event with no prev_events"
852
917
853
918
event = await builder .build (
854
- prev_event_ids = prev_event_ids , auth_event_ids = auth_event_ids
919
+ prev_event_ids = prev_event_ids ,
920
+ auth_event_ids = auth_event_ids ,
921
+ depth = depth ,
855
922
)
856
- context = await self .state .compute_event_context (event )
923
+
924
+ old_state = None
925
+
926
+ # Pass on the outlier property from the builder to the event
927
+ # after it is created
928
+ if builder .internal_metadata .outlier :
929
+ event .internal_metadata .outlier = builder .internal_metadata .outlier
930
+
931
+ # Calculate the state for outliers that pass in their own `auth_event_ids`
932
+ if auth_event_ids :
933
+ old_state = await self .store .get_events_as_list (auth_event_ids )
934
+
935
+ context = await self .state .compute_event_context (event , old_state = old_state )
936
+
857
937
if requester :
858
938
context .app_service = requester .app_service
859
939
@@ -1018,7 +1098,13 @@ async def _persist_event(
1018
1098
the arguments.
1019
1099
"""
1020
1100
1021
- await self .action_generator .handle_push_actions_for_event (event , context )
1101
+ # Skip push notification actions for historical messages
1102
+ # because we don't want to notify people about old history back in time.
1103
+ # The historical messages also do not have the proper `context.current_state_ids`
1104
+ # and `state_groups` because they have `prev_events` that aren't persisted yet
1105
+ # (historical messages persisted in reverse-chronological order).
1106
+ if not event .internal_metadata .is_historical ():
1107
+ await self .action_generator .handle_push_actions_for_event (event , context )
1022
1108
1023
1109
try :
1024
1110
# If we're a worker we need to hit out to the master.
@@ -1317,13 +1403,21 @@ async def persist_and_notify_client_event(
1317
1403
if prev_state_ids :
1318
1404
raise AuthError (403 , "Changing the room create event is forbidden" )
1319
1405
1406
+ # Mark any `m.historical` messages as backfilled so they don't appear
1407
+ # in `/sync` and have the proper decrementing `stream_ordering` as we import
1408
+ backfilled = False
1409
+ if event .internal_metadata .is_historical ():
1410
+ backfilled = True
1411
+
1320
1412
# Note that this returns the event that was persisted, which may not be
1321
1413
# the same as we passed in if it was deduplicated due transaction IDs.
1322
1414
(
1323
1415
event ,
1324
1416
event_pos ,
1325
1417
max_stream_token ,
1326
- ) = await self .storage .persistence .persist_event (event , context = context )
1418
+ ) = await self .storage .persistence .persist_event (
1419
+ event , context = context , backfilled = backfilled
1420
+ )
1327
1421
1328
1422
if self ._ephemeral_events_enabled :
1329
1423
# If there's an expiry timestamp on the event, schedule its expiry.
0 commit comments