Skip to content
Snippets Groups Projects
Commit 84af5773 authored by Erik Johnston's avatar Erik Johnston
Browse files

Implement event format v2

parent cc2d650e
No related branches found
No related tags found
No related merge requests found
...@@ -126,10 +126,12 @@ class EventFormatVersions(object): ...@@ -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,
} }
......
# -*- 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 ...@@ -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,22 +224,91 @@ class FrozenEvent(EventBase): ...@@ -225,22 +224,91 @@ class FrozenEvent(EventBase):
rejected_reason=rejected_reason, rejected_reason=rejected_reason,
) )
@staticmethod def __str__(self):
def from_event(event): return self.__repr__()
e = FrozenEvent(
event.get_pdu_json() def __repr__(self):
return "<FrozenEvent event_id='%s', type='%s', state_key='%s'>" % (
self.get("event_id", None),
self.get("type", None),
self.get("state_key", None),
) )
e.internal_metadata = event.internal_metadata
return e 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): def __str__(self):
return self.__repr__() return self.__repr__()
def __repr__(self): def __repr__(self):
return "<FrozenEvent event_id='%s', type='%s', state_key='%s'>" % ( return "<FrozenEventV2 event_id='%s', type='%s', state_key='%s'>" % (
self.get("event_id", None), self.event_id,
self.get("type", None), self.get("type", None),
self.get("state_key", None), self.get("state_key", None),
) )
...@@ -259,7 +327,13 @@ def room_version_to_event_format(room_version): ...@@ -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): ...@@ -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 ( ...@@ -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): ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment