Move sticky_ttl_ms serialization to serialize_event

This commit is contained in:
Erik Johnston
2026-03-18 13:27:17 +00:00
parent 1d694c5370
commit 7b671f4dd6
2 changed files with 23 additions and 14 deletions
+23
View File
@@ -41,6 +41,7 @@ from synapse.api.constants import (
MAX_PDU_SIZE,
EventContentFields,
EventTypes,
EventUnsignedContentFields,
RelationTypes,
)
from synapse.api.errors import Codes, SynapseError
@@ -435,6 +436,9 @@ class SerializeEventConfig:
# only server admins can see through other configuration. For example,
# whether an event was soft failed by the server.
include_admin_metadata: bool = False
# Whether MSC4354 (sticky events) is enabled. When True, the sticky TTL
# will be computed and included in the unsigned section of sticky events.
msc4354_enabled: bool = False
_DEFAULT_SERIALIZE_EVENT_CONFIG = SerializeEventConfig()
@@ -554,6 +558,20 @@ def _serialize_event(
if e.internal_metadata.policy_server_spammy:
d["unsigned"]["io.element.synapse.policy_server_spammy"] = True
if config.msc4354_enabled:
sticky_duration = e.sticky_duration()
if sticky_duration:
expires_at = (
# min() ensures that the origin server can't lie about the time and
# send the event 'in the future', as that would allow them to exceed
# the 1 hour limit on stickiness duration.
min(e.origin_server_ts, time_now_ms) + sticky_duration.as_millis()
)
if expires_at > time_now_ms:
d["unsigned"][EventUnsignedContentFields.STICKY_TTL] = (
expires_at - time_now_ms
)
only_event_fields = config.only_event_fields
if only_event_fields:
if not isinstance(only_event_fields, list) or not all(
@@ -575,6 +593,8 @@ class EventClientSerializer:
def __init__(self, hs: "HomeServer") -> None:
self._store = hs.get_datastores().main
self._auth = hs.get_auth()
self._config = hs.config
self._clock = hs.get_clock()
self._add_extra_fields_to_unsigned_client_event_callbacks: list[
ADD_EXTRA_FIELDS_TO_UNSIGNED_CLIENT_EVENT_CALLBACK
] = []
@@ -615,6 +635,9 @@ class EventClientSerializer:
):
config = make_config_for_admin(config)
if self._config.experimental.msc4354_enabled:
config = attr.evolve(config, msc4354_enabled=True)
serialized_event = _serialize_event(event, time_now, config=config)
# If the event was redacted, fetch the redaction event from the database
-14
View File
@@ -237,20 +237,6 @@ async def filter_and_transform_events_for_client(
# to the cache!
cloned = clone_event(filtered)
cloned.unsigned[EventUnsignedContentFields.MEMBERSHIP] = user_membership
if storage.main.config.experimental.msc4354_enabled:
sticky_duration = cloned.sticky_duration()
if sticky_duration:
now_ms = storage.main.clock.time_msec()
expires_at = (
# min() ensures that the origin server can't lie about the time and
# send the event 'in the future', as that would allow them to exceed
# the 1 hour limit on stickiness duration.
min(cloned.origin_server_ts, now_ms) + sticky_duration.as_millis()
)
if expires_at > now_ms:
cloned.unsigned[EventUnsignedContentFields.STICKY_TTL] = (
expires_at - now_ms
)
return cloned