forked from MirrorHub/synapse
Implement event format v2
This commit is contained in:
parent
cc2d650ef7
commit
84af577356
4 changed files with 110 additions and 21 deletions
|
@ -126,10 +126,12 @@ class EventFormatVersions(object):
|
||||||
independently from the room version.
|
independently from the room version.
|
||||||
"""
|
"""
|
||||||
V1 = 1
|
V1 = 1
|
||||||
|
V2 = 2
|
||||||
|
|
||||||
|
|
||||||
KNOWN_EVENT_FORMAT_VERSIONS = {
|
KNOWN_EVENT_FORMAT_VERSIONS = {
|
||||||
EventFormatVersions.V1,
|
EventFormatVersions.V1,
|
||||||
|
EventFormatVersions.V2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2014-2016 OpenMarket Ltd
|
# Copyright 2014-2016 OpenMarket Ltd
|
||||||
|
# Copyright 2019 New Vector Ltd
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -18,11 +19,9 @@ from distutils.util import strtobool
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from synapse.api.constants import (
|
from unpaddedbase64 import encode_base64
|
||||||
KNOWN_EVENT_FORMAT_VERSIONS,
|
|
||||||
KNOWN_ROOM_VERSIONS,
|
from synapse.api.constants import KNOWN_ROOM_VERSIONS, EventFormatVersions, RoomVersions
|
||||||
EventFormatVersions,
|
|
||||||
)
|
|
||||||
from synapse.util.caches import intern_dict
|
from synapse.util.caches import intern_dict
|
||||||
from synapse.util.frozenutils import freeze
|
from synapse.util.frozenutils import freeze
|
||||||
|
|
||||||
|
@ -225,16 +224,6 @@ class FrozenEvent(EventBase):
|
||||||
rejected_reason=rejected_reason,
|
rejected_reason=rejected_reason,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_event(event):
|
|
||||||
e = FrozenEvent(
|
|
||||||
event.get_pdu_json()
|
|
||||||
)
|
|
||||||
|
|
||||||
e.internal_metadata = event.internal_metadata
|
|
||||||
|
|
||||||
return e
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
@ -246,6 +235,85 @@ class FrozenEvent(EventBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FrozenEventV2(EventBase):
|
||||||
|
format_version = EventFormatVersions.V2 # All events of this type are V2
|
||||||
|
|
||||||
|
def __init__(self, event_dict, internal_metadata_dict={}, rejected_reason=None):
|
||||||
|
event_dict = dict(event_dict)
|
||||||
|
|
||||||
|
# Signatures is a dict of dicts, and this is faster than doing a
|
||||||
|
# copy.deepcopy
|
||||||
|
signatures = {
|
||||||
|
name: {sig_id: sig for sig_id, sig in sigs.items()}
|
||||||
|
for name, sigs in event_dict.pop("signatures", {}).items()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert "event_id" not in event_dict
|
||||||
|
|
||||||
|
unsigned = dict(event_dict.pop("unsigned", {}))
|
||||||
|
|
||||||
|
# We intern these strings because they turn up a lot (especially when
|
||||||
|
# caching).
|
||||||
|
event_dict = intern_dict(event_dict)
|
||||||
|
|
||||||
|
if USE_FROZEN_DICTS:
|
||||||
|
frozen_dict = freeze(event_dict)
|
||||||
|
else:
|
||||||
|
frozen_dict = event_dict
|
||||||
|
|
||||||
|
self._event_id = None
|
||||||
|
self.type = event_dict["type"]
|
||||||
|
if "state_key" in event_dict:
|
||||||
|
self.state_key = event_dict["state_key"]
|
||||||
|
|
||||||
|
super(FrozenEventV2, self).__init__(
|
||||||
|
frozen_dict,
|
||||||
|
signatures=signatures,
|
||||||
|
unsigned=unsigned,
|
||||||
|
internal_metadata_dict=internal_metadata_dict,
|
||||||
|
rejected_reason=rejected_reason,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def event_id(self):
|
||||||
|
# We have to import this here as otherwise we get an import loop which
|
||||||
|
# is hard to break.
|
||||||
|
from synapse.crypto.event_signing import compute_event_reference_hash
|
||||||
|
|
||||||
|
if self._event_id:
|
||||||
|
return self._event_id
|
||||||
|
self._event_id = "$" + encode_base64(compute_event_reference_hash(self)[1])
|
||||||
|
return self._event_id
|
||||||
|
|
||||||
|
def prev_event_ids(self):
|
||||||
|
"""Returns the list of prev event IDs. The order matches the order
|
||||||
|
specified in the event, though there is no meaning to it.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: The list of event IDs of this event's prev_events
|
||||||
|
"""
|
||||||
|
return self.prev_events
|
||||||
|
|
||||||
|
def auth_event_ids(self):
|
||||||
|
"""Returns the list of auth event IDs. The order matches the order
|
||||||
|
specified in the event, though there is no meaning to it.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: The list of event IDs of this event's auth_events
|
||||||
|
"""
|
||||||
|
return self.auth_events
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<FrozenEventV2 event_id='%s', type='%s', state_key='%s'>" % (
|
||||||
|
self.event_id,
|
||||||
|
self.get("type", None),
|
||||||
|
self.get("state_key", None),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def room_version_to_event_format(room_version):
|
def room_version_to_event_format(room_version):
|
||||||
"""Converts a room version string to the event format
|
"""Converts a room version string to the event format
|
||||||
|
|
||||||
|
@ -259,7 +327,13 @@ def room_version_to_event_format(room_version):
|
||||||
# We should have already checked version, so this should not happen
|
# We should have already checked version, so this should not happen
|
||||||
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
||||||
|
|
||||||
return EventFormatVersions.V1
|
if room_version in (
|
||||||
|
RoomVersions.V1, RoomVersions.V2, RoomVersions.VDH_TEST,
|
||||||
|
RoomVersions.STATE_V2_TEST,
|
||||||
|
):
|
||||||
|
return EventFormatVersions.V1
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
||||||
|
|
||||||
|
|
||||||
def event_type_from_format_version(format_version):
|
def event_type_from_format_version(format_version):
|
||||||
|
@ -273,8 +347,12 @@ def event_type_from_format_version(format_version):
|
||||||
type: A type that can be initialized as per the initializer of
|
type: A type that can be initialized as per the initializer of
|
||||||
`FrozenEvent`
|
`FrozenEvent`
|
||||||
"""
|
"""
|
||||||
if format_version not in KNOWN_EVENT_FORMAT_VERSIONS:
|
|
||||||
|
if format_version == EventFormatVersions.V1:
|
||||||
|
return FrozenEvent
|
||||||
|
elif format_version == EventFormatVersions.V2:
|
||||||
|
return FrozenEventV2
|
||||||
|
else:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"No event format %r" % (format_version,)
|
"No event format %r" % (format_version,)
|
||||||
)
|
)
|
||||||
return FrozenEvent
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ from synapse.api.constants import (
|
||||||
KNOWN_EVENT_FORMAT_VERSIONS,
|
KNOWN_EVENT_FORMAT_VERSIONS,
|
||||||
KNOWN_ROOM_VERSIONS,
|
KNOWN_ROOM_VERSIONS,
|
||||||
MAX_DEPTH,
|
MAX_DEPTH,
|
||||||
|
EventFormatVersions,
|
||||||
)
|
)
|
||||||
from synapse.crypto.event_signing import add_hashes_and_signatures
|
from synapse.crypto.event_signing import add_hashes_and_signatures
|
||||||
from synapse.types import EventID
|
from synapse.types import EventID
|
||||||
|
@ -109,8 +110,12 @@ class EventBuilder(object):
|
||||||
self, state_ids,
|
self, state_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
auth_events = yield self._store.add_event_hashes(auth_ids)
|
if self.format_version == EventFormatVersions.V1:
|
||||||
prev_events = yield self._store.add_event_hashes(prev_event_ids)
|
auth_events = yield self._store.add_event_hashes(auth_ids)
|
||||||
|
prev_events = yield self._store.add_event_hashes(prev_event_ids)
|
||||||
|
else:
|
||||||
|
auth_events = auth_ids
|
||||||
|
prev_events = prev_event_ids
|
||||||
|
|
||||||
old_depth = yield self._store.get_max_depth_of(
|
old_depth = yield self._store.get_max_depth_of(
|
||||||
prev_event_ids,
|
prev_event_ids,
|
||||||
|
@ -228,7 +233,8 @@ def create_local_event_from_event_dict(clock, hostname, signing_key,
|
||||||
|
|
||||||
time_now = int(clock.time_msec())
|
time_now = int(clock.time_msec())
|
||||||
|
|
||||||
event_dict["event_id"] = _create_event_id(clock, hostname)
|
if format_version == EventFormatVersions.V1:
|
||||||
|
event_dict["event_id"] = _create_event_id(clock, hostname)
|
||||||
|
|
||||||
event_dict["origin"] = hostname
|
event_dict["origin"] = hostname
|
||||||
event_dict["origin_server_ts"] = time_now
|
event_dict["origin_server_ts"] = time_now
|
||||||
|
|
|
@ -267,6 +267,7 @@ def serialize_event(e, time_now_ms, as_client_event=True,
|
||||||
Returns:
|
Returns:
|
||||||
dict
|
dict
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# FIXME(erikj): To handle the case of presence events and the like
|
# FIXME(erikj): To handle the case of presence events and the like
|
||||||
if not isinstance(e, EventBase):
|
if not isinstance(e, EventBase):
|
||||||
return e
|
return e
|
||||||
|
@ -276,6 +277,8 @@ def serialize_event(e, time_now_ms, as_client_event=True,
|
||||||
# Should this strip out None's?
|
# Should this strip out None's?
|
||||||
d = {k: v for k, v in e.get_dict().items()}
|
d = {k: v for k, v in e.get_dict().items()}
|
||||||
|
|
||||||
|
d["event_id"] = e.event_id
|
||||||
|
|
||||||
if "age_ts" in d["unsigned"]:
|
if "age_ts" in d["unsigned"]:
|
||||||
d["unsigned"]["age"] = time_now_ms - d["unsigned"]["age_ts"]
|
d["unsigned"]["age"] = time_now_ms - d["unsigned"]["age_ts"]
|
||||||
del d["unsigned"]["age_ts"]
|
del d["unsigned"]["age_ts"]
|
||||||
|
|
Loading…
Reference in a new issue