From 492e07bee6692a9b995f4862ebef362f8f7daea0 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 16 Mar 2023 19:12:50 -0300 Subject: [PATCH 1/6] feat(events): implement EventType enum and update BaseEvent --- hathor/event/event_manager.py | 1 - hathor/event/model/base_event.py | 30 +++++++---------------- hathor/event/model/event_type.py | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 hathor/event/model/event_type.py diff --git a/hathor/event/event_manager.py b/hathor/event/event_manager.py index 458d4878e..2b782c02e 100644 --- a/hathor/event/event_manager.py +++ b/hathor/event/event_manager.py @@ -39,7 +39,6 @@ HathorEvents.REORG_FINISHED, HathorEvents.VERTEX_METADATA_CHANGED, HathorEvents.CONSENSUS_TX_UPDATE, - HathorEvents.CONSENSUS_TX_REMOVED, ] _EVENT_CONVERTERS = { diff --git a/hathor/event/model/base_event.py b/hathor/event/model/base_event.py index cba86a0bc..9c1e0c6b4 100644 --- a/hathor/event/model/base_event.py +++ b/hathor/event/model/base_event.py @@ -12,24 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Optional, Type +from typing import Optional from pydantic import NonNegativeInt, validator -from hathor.event.model.event_data import BaseEventData, EmptyData, EventData, ReorgData, TxData -from hathor.pubsub import EventArguments, HathorEvents +from hathor.event.model.event_data import EventData +from hathor.event.model.event_type import EventType +from hathor.pubsub import EventArguments from hathor.utils.pydantic import BaseModel -_EVENT_DATA_MAP: Dict[HathorEvents, Type[BaseEventData]] = { - HathorEvents.LOAD_FINISHED: EmptyData, - HathorEvents.NETWORK_NEW_TX_ACCEPTED: TxData, - HathorEvents.REORG_STARTED: ReorgData, - HathorEvents.REORG_FINISHED: EmptyData, - HathorEvents.VERTEX_METADATA_CHANGED: TxData, - HathorEvents.CONSENSUS_TX_UPDATE: TxData, - HathorEvents.CONSENSUS_TX_REMOVED: TxData, -} - class BaseEvent(BaseModel, use_enum_values=True): # Full node id, because different full nodes can have different sequences of events @@ -41,7 +32,7 @@ class BaseEvent(BaseModel, use_enum_values=True): # events it's possible that timestamps will temporarily decrease. timestamp: float # One of the event types - type: HathorEvents + type: EventType # Variable for event type data: EventData # Used to link events, for example, many TX_METADATA_CHANGED will have the same group_id when they belong to the @@ -54,14 +45,11 @@ def from_event_arguments( peer_id: str, event_id: NonNegativeInt, timestamp: float, - event_type: HathorEvents, + event_type: EventType, event_args: EventArguments, group_id: Optional[NonNegativeInt] ) -> 'BaseEvent': - event_data_type = _EVENT_DATA_MAP.get(event_type) - - if event_data_type is None: - raise ValueError(f'The given event type ({event_type}) is not a supported event') + event_data_type = event_type.data_type() return cls( peer_id=peer_id, @@ -74,8 +62,8 @@ def from_event_arguments( @validator('data') def data_type_must_match_event_type(cls, v, values): - event_type = HathorEvents(values['type']) - expected_data_type = _EVENT_DATA_MAP.get(event_type) + event_type = EventType(values['type']) + expected_data_type = event_type.data_type() if type(v) != expected_data_type: raise ValueError('event data type does not match event type') diff --git a/hathor/event/model/event_type.py b/hathor/event/model/event_type.py new file mode 100644 index 000000000..c87a59228 --- /dev/null +++ b/hathor/event/model/event_type.py @@ -0,0 +1,41 @@ +# Copyright 2023 Hathor Labs +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from enum import Enum +from typing import Dict, Type + +from hathor.event.model.event_data import BaseEventData, EmptyData, ReorgData, TxData + + +class EventType(Enum): + LOAD_STARTED = 'LOAD_STARTED' + LOAD_FINISHED = 'LOAD_FINISHED' + NEW_VERTEX_ACCEPTED = 'NEW_VERTEX_ACCEPTED' + NEW_VERTEX_VOIDED = 'NEW_VERTEX_VOIDED' + REORG_STARTED = 'REORG_STARTED' + REORG_FINISHED = 'REORG_FINISHED' + VERTEX_METADATA_CHANGED = 'VERTEX_METADATA_CHANGED' + + def data_type(self) -> Type[BaseEventData]: + type_map: Dict[EventType, Type[BaseEventData]] = { + EventType.LOAD_STARTED: EmptyData, + EventType.LOAD_FINISHED: EmptyData, + EventType.NEW_VERTEX_ACCEPTED: TxData, + EventType.NEW_VERTEX_VOIDED: TxData, + EventType.REORG_STARTED: ReorgData, + EventType.REORG_FINISHED: ReorgData, + EventType.VERTEX_METADATA_CHANGED: TxData, + } + + return type_map[self] From 9daceb85828d132d803652efba8a932ed16ca93b Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 16 Mar 2023 19:59:01 -0300 Subject: [PATCH 2/6] feat(events): update EventManager to use EventType and improve handling --- hathor/event/event_manager.py | 33 +++++++++++++++----------------- hathor/event/model/event_type.py | 24 ++++++++++++++++++++++- hathor/pubsub.py | 2 -- tests/utils.py | 6 +++--- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/hathor/event/event_manager.py b/hathor/event/event_manager.py index 2b782c02e..ec7372f7b 100644 --- a/hathor/event/event_manager.py +++ b/hathor/event/event_manager.py @@ -17,6 +17,7 @@ from structlog import get_logger from hathor.event.model.base_event import BaseEvent +from hathor.event.model.event_type import EventType from hathor.event.storage import EventStorage from hathor.event.websocket import EventWebsocketFactory from hathor.pubsub import EventArguments, HathorEvents, PubSubManager @@ -25,26 +26,22 @@ logger = get_logger() _GROUP_START_EVENTS = { - HathorEvents.REORG_STARTED, + EventType.REORG_STARTED, } _GROUP_END_EVENTS = { - HathorEvents.REORG_FINISHED, + EventType.REORG_FINISHED, } _SUBSCRIBE_EVENTS = [ - HathorEvents.NETWORK_NEW_TX_ACCEPTED, + HathorEvents.MANAGER_ON_START, HathorEvents.LOAD_FINISHED, + HathorEvents.NETWORK_NEW_TX_ACCEPTED, HathorEvents.REORG_STARTED, HathorEvents.REORG_FINISHED, - HathorEvents.VERTEX_METADATA_CHANGED, HathorEvents.CONSENSUS_TX_UPDATE, ] -_EVENT_CONVERTERS = { - HathorEvents.CONSENSUS_TX_UPDATE: HathorEvents.VERTEX_METADATA_CHANGED -} - class EventManager: """Class that manages integration events. @@ -106,7 +103,7 @@ def _event_group_is_closed(self): return ( self._last_event is None or self._last_event.group_id is None or - HathorEvents(self._last_event.type) in _GROUP_END_EVENTS + EventType(self._last_event.type) in _GROUP_END_EVENTS ) def _subscribe_events(self): @@ -115,12 +112,12 @@ def _subscribe_events(self): for event in _SUBSCRIBE_EVENTS: self._pubsub.subscribe(event, self._handle_event) - def _handle_event(self, event_type: HathorEvents, event_args: EventArguments) -> None: + def _handle_event(self, hathor_event: HathorEvents, event_args: EventArguments) -> None: assert self._is_running, 'Cannot handle event, EventManager is not started.' - event_type = _EVENT_CONVERTERS.get(event_type, event_type) + event_type = EventType.from_hathor_event(hathor_event, event_args) event_specific_handlers = { - HathorEvents.LOAD_FINISHED: self._handle_load_finished + EventType.LOAD_FINISHED: self._handle_load_finished } if event_specific_handler := event_specific_handlers.get(event_type): @@ -131,8 +128,8 @@ def _handle_event(self, event_type: HathorEvents, event_args: EventArguments) -> self._handle_event_creation(event_type, event_args) - def _handle_event_creation(self, event_type: HathorEvents, event_args: EventArguments) -> None: - create_event_fn: Callable[[HathorEvents, EventArguments], BaseEvent] + def _handle_event_creation(self, event_type: EventType, event_args: EventArguments) -> None: + create_event_fn: Callable[[EventType, EventArguments], BaseEvent] if event_type in _GROUP_START_EVENTS: create_event_fn = self._create_group_start_event @@ -148,7 +145,7 @@ def _handle_event_creation(self, event_type: HathorEvents, event_args: EventArgu self._last_event = event - def _create_group_start_event(self, event_type: HathorEvents, event_args: EventArguments) -> BaseEvent: + def _create_group_start_event(self, event_type: EventType, event_args: EventArguments) -> BaseEvent: assert self._event_group_is_closed(), 'A new event group cannot be started as one is already in progress.' new_group_id = 0 if self._last_existing_group_id is None else self._last_existing_group_id + 1 @@ -161,7 +158,7 @@ def _create_group_start_event(self, event_type: HathorEvents, event_args: EventA group_id=new_group_id, ) - def _create_group_end_event(self, event_type: HathorEvents, event_args: EventArguments) -> BaseEvent: + def _create_group_end_event(self, event_type: EventType, event_args: EventArguments) -> BaseEvent: assert self._last_event is not None, 'Cannot end event group if there are no events.' assert not self._event_group_is_closed(), 'Cannot end event group as none is in progress.' @@ -171,7 +168,7 @@ def _create_group_end_event(self, event_type: HathorEvents, event_args: EventArg group_id=self._last_event.group_id, ) - def _create_non_group_edge_event(self, event_type: HathorEvents, event_args: EventArguments) -> BaseEvent: + def _create_non_group_edge_event(self, event_type: EventType, event_args: EventArguments) -> BaseEvent: group_id = None if not self._event_group_is_closed(): @@ -189,7 +186,7 @@ def _handle_load_finished(self): def _create_event( self, - event_type: HathorEvents, + event_type: EventType, event_args: EventArguments, group_id: Optional[int], ) -> BaseEvent: diff --git a/hathor/event/model/event_type.py b/hathor/event/model/event_type.py index c87a59228..2848b904f 100644 --- a/hathor/event/model/event_type.py +++ b/hathor/event/model/event_type.py @@ -16,6 +16,7 @@ from typing import Dict, Type from hathor.event.model.event_data import BaseEventData, EmptyData, ReorgData, TxData +from hathor.pubsub import EventArguments, HathorEvents class EventType(Enum): @@ -27,6 +28,27 @@ class EventType(Enum): REORG_FINISHED = 'REORG_FINISHED' VERTEX_METADATA_CHANGED = 'VERTEX_METADATA_CHANGED' + @classmethod + def from_hathor_event(cls, hathor_event: HathorEvents, event_args: EventArguments) -> 'EventType': + if hathor_event == HathorEvents.NETWORK_NEW_TX_ACCEPTED: + metadata = event_args.tx.get_metadata() + + return cls.NEW_VERTEX_VOIDED if metadata.voided_by else cls.NEW_VERTEX_ACCEPTED + + event_map = { + HathorEvents.MANAGER_ON_START: EventType.LOAD_STARTED, + HathorEvents.LOAD_FINISHED: EventType.LOAD_FINISHED, + HathorEvents.REORG_STARTED: EventType.REORG_STARTED, + HathorEvents.REORG_FINISHED: EventType.REORG_FINISHED, + HathorEvents.CONSENSUS_TX_UPDATE: EventType.VERTEX_METADATA_CHANGED + } + + event = event_map.get(hathor_event) + + assert event is not None, f'Cannot create EventType from {hathor_event}' + + return event + def data_type(self) -> Type[BaseEventData]: type_map: Dict[EventType, Type[BaseEventData]] = { EventType.LOAD_STARTED: EmptyData, @@ -34,7 +56,7 @@ def data_type(self) -> Type[BaseEventData]: EventType.NEW_VERTEX_ACCEPTED: TxData, EventType.NEW_VERTEX_VOIDED: TxData, EventType.REORG_STARTED: ReorgData, - EventType.REORG_FINISHED: ReorgData, + EventType.REORG_FINISHED: EmptyData, EventType.VERTEX_METADATA_CHANGED: TxData, } diff --git a/hathor/pubsub.py b/hathor/pubsub.py index 42b7d44ff..255088f80 100644 --- a/hathor/pubsub.py +++ b/hathor/pubsub.py @@ -135,8 +135,6 @@ class HathorEvents(Enum): REORG_FINISHED = 'reorg:finished' - VERTEX_METADATA_CHANGED = 'vertex:metadata_changed' - class EventArguments: """Simple object for storing event arguments. diff --git a/tests/utils.py b/tests/utils.py index e9b43c27a..3d8e378fd 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -16,8 +16,8 @@ from hathor.crypto.util import decode_address, get_address_b58_from_public_key, get_private_key_from_bytes from hathor.event.model.base_event import BaseEvent from hathor.event.model.event_data import TxData, TxMetadata +from hathor.event.model.event_type import EventType from hathor.manager import HathorManager -from hathor.pubsub import HathorEvents from hathor.transaction import BaseTransaction, Transaction, TxInput, TxOutput, genesis from hathor.transaction.scripts import P2PKH, HathorScript, Opcode, parse_address_script from hathor.transaction.token_creation_tx import TokenCreationTransaction @@ -695,7 +695,7 @@ def generate_mocked_event(self, event_id: Optional[int] = None, group_id: Option id=event_id or self.gen_next_id(), peer_id=peer_id_mock, timestamp=1658892990, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, group_id=group_id, data=self.tx_data, ) @@ -714,6 +714,6 @@ def create_event(cls, event_id: int) -> BaseEvent: peer_id='123', id=event_id, timestamp=123456, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=cls.tx_data ) From 0972d7496a148c94b18a11b5c821c81ede63e39c Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 17 Mar 2023 01:38:29 -0300 Subject: [PATCH 3/6] feat(events): update tests --- tests/event/test_base_event.py | 12 ++--- tests/event/test_event_manager.py | 7 +-- tests/event/test_event_reorg.py | 65 +++++++++++++------------- tests/event/websocket/test_protocol.py | 6 +-- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/event/test_base_event.py b/tests/event/test_base_event.py index a4214c755..90b0b3e76 100644 --- a/tests/event/test_base_event.py +++ b/tests/event/test_base_event.py @@ -17,7 +17,7 @@ from hathor.event.model.base_event import BaseEvent from hathor.event.model.event_data import ReorgData -from hathor.pubsub import HathorEvents +from hathor.event.model.event_type import EventType from tests.utils import EventMocker @@ -28,7 +28,7 @@ def test_create_base_event(event_id, group_id): peer_id='some_peer', id=event_id, timestamp=123.3, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=EventMocker.tx_data, group_id=group_id ) @@ -37,7 +37,7 @@ def test_create_base_event(event_id, group_id): peer_id='some_peer', id=event_id, timestamp=123.3, - type='vertex:metadata_changed', + type='VERTEX_METADATA_CHANGED', data=dict( hash='abc', nonce=123, @@ -78,7 +78,7 @@ def test_create_base_event_fail_id(event_id): peer_id='some_peer', id=event_id, timestamp=123.3, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=EventMocker.tx_data, ) @@ -90,7 +90,7 @@ def test_create_base_event_fail_group_id(group_id): peer_id='some_peer', id=0, timestamp=123.3, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=EventMocker.tx_data, group_id=group_id ) @@ -102,7 +102,7 @@ def test_create_base_event_fail_data_type(): peer_id='some_peer', id=0, timestamp=123.3, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=ReorgData( reorg_size=10, previous_best_block='a', diff --git a/tests/event/test_event_manager.py b/tests/event/test_event_manager.py index 5f8069ebe..7751436fb 100644 --- a/tests/event/test_event_manager.py +++ b/tests/event/test_event_manager.py @@ -1,6 +1,7 @@ from unittest.mock import Mock from hathor.event import EventManager +from hathor.event.model.event_type import EventType from hathor.event.storage.memory_storage import EventMemoryStorage from hathor.event.websocket import EventWebsocketFactory from hathor.pubsub import HathorEvents, PubSubManager @@ -55,10 +56,10 @@ def test_event_group(self): event2 = self.event_storage.get_event(2) event3 = self.event_storage.get_event(3) event4 = self.event_storage.get_event(4) - self.assertEqual(HathorEvents(event0.type), HathorEvents.LOAD_FINISHED) - self.assertEqual(HathorEvents(event1.type), HathorEvents.REORG_STARTED) + self.assertEqual(EventType(event0.type), EventType.LOAD_FINISHED) + self.assertEqual(EventType(event1.type), EventType.REORG_STARTED) self.assertIsNotNone(event1.group_id) - self.assertEqual(HathorEvents(event2.type), HathorEvents.REORG_FINISHED) + self.assertEqual(EventType(event2.type), EventType.REORG_FINISHED) self.assertIsNotNone(event2.group_id) self.assertEqual(event1.group_id, event2.group_id) self.assertNotEqual(event2.group_id, event3.group_id) diff --git a/tests/event/test_event_reorg.py b/tests/event/test_event_reorg.py index 6cee15c2c..feaed01af 100644 --- a/tests/event/test_event_reorg.py +++ b/tests/event/test_event_reorg.py @@ -2,6 +2,7 @@ from hathor.conf import HathorSettings from hathor.event import EventManager +from hathor.event.model.event_type import EventType from hathor.event.storage import EventMemoryStorage from hathor.event.websocket import EventWebsocketFactory from hathor.pubsub import PubSubManager @@ -38,8 +39,6 @@ def setUp(self): self.genesis_public_key = self.genesis_private_key.public_key() def test_reorg_events(self): - from hathor.pubsub import HathorEvents - assert settings.REWARD_SPEND_MIN_BLOCKS == 10, 'this test was made with this hardcoded value in mind' # add some blocks @@ -72,48 +71,48 @@ class unsorted(list): pass expected_events_grouped = [ [ - (HathorEvents.LOAD_FINISHED, {}) + (EventType.LOAD_FINISHED, {}) ], # XXX: the order of the following events can vary depending on which genesis is spent/confirmed first unsorted([ - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX1_HASH.hex()}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX2_HASH.hex()}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[0].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX1_HASH.hex()}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX2_HASH.hex()}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[0].hash_hex}), ]), # XXX: these events must always have this order [ - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[0].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[1].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[1].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[2].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[2].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[3].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[3].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[4].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[4].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[5].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[5].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[6].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[6].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[7].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[7].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[8].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': blocks[9].hash_hex}), - (HathorEvents.REORG_STARTED, {'reorg_size': 2, 'previous_best_block': blocks[9].hash_hex, - 'new_best_block': b0.hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[0].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[1].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[1].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[2].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[2].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[3].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[3].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[4].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[4].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[5].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[5].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[6].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[6].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[7].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[7].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[8].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': blocks[9].hash_hex}), + (EventType.REORG_STARTED, {'reorg_size': 2, 'previous_best_block': blocks[9].hash_hex, + 'new_best_block': b0.hash_hex}), ], # XXX: for some reason the metadata update order of these events isn't always the same unsorted([ - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), - (HathorEvents.VERTEX_METADATA_CHANGED, {'hash': b0.hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': b0.hash_hex}), ]), # XXX: these events must always have this order [ - (HathorEvents.REORG_FINISHED, {}), - (HathorEvents.NETWORK_NEW_TX_ACCEPTED, {'hash': b0.hash_hex}), + (EventType.REORG_FINISHED, {}), + (EventType.NEW_VERTEX_ACCEPTED, {'hash': b0.hash_hex}), ], ] @@ -133,7 +132,7 @@ def zipchunkify(iterable, groups): expected_events.sort(key=lambda i: i[1].get('hash', '')) for actual_event, expected_event in zip(actual_events, expected_events): expected_event_type, expected_partial_data = expected_event - self.assertEqual(HathorEvents(actual_event.type), expected_event_type) + self.assertEqual(EventType(actual_event.type), expected_event_type) for expected_data_key, expected_data_value in expected_partial_data.items(): self.assertEqual(actual_event.data.dict()[expected_data_key], expected_data_value) diff --git a/tests/event/websocket/test_protocol.py b/tests/event/websocket/test_protocol.py index df23640db..0ef5ded16 100644 --- a/tests/event/websocket/test_protocol.py +++ b/tests/event/websocket/test_protocol.py @@ -19,10 +19,10 @@ from autobahn.websocket import ConnectionRequest from hathor.event.model.base_event import BaseEvent +from hathor.event.model.event_type import EventType from hathor.event.websocket import EventWebsocketFactory from hathor.event.websocket.protocol import EventWebsocketProtocol from hathor.event.websocket.response import EventResponse, InvalidRequestType -from hathor.pubsub import HathorEvents from tests.utils import EventMocker @@ -87,7 +87,7 @@ def test_send_event_response(): peer_id='some_peer_id', id=10, timestamp=123, - type=HathorEvents.VERTEX_METADATA_CHANGED, + type=EventType.VERTEX_METADATA_CHANGED, data=EventMocker.tx_data ), latest_event_id=10 @@ -96,7 +96,7 @@ def test_send_event_response(): protocol.send_event_response(response) expected_payload = b'{"type":"EVENT","event":{"peer_id":"some_peer_id","id":10,"timestamp":123.0,' \ - b'"type":"vertex:metadata_changed","data":{"hash":"abc","nonce":123,"timestamp":456,' \ + b'"type":"VERTEX_METADATA_CHANGED","data":{"hash":"abc","nonce":123,"timestamp":456,' \ b'"version":1,"weight":10.0,"inputs":[],"outputs":[],"parents":[],"tokens":[],' \ b'"token_name":null,"token_symbol":null,"metadata":{"hash":"abc","spent_outputs":[],' \ b'"conflict_with":[],"voided_by":[],"received_by":[],"children":[],"twins":[],' \ From 02b8cf8dc9a5f1394ced3d1ef78237342f6a40db Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 17 Mar 2023 02:25:24 -0300 Subject: [PATCH 4/6] feat(events): remove voided event --- hathor/event/event_manager.py | 2 +- hathor/event/model/event_type.py | 51 ++++++++++++++------------------ 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/hathor/event/event_manager.py b/hathor/event/event_manager.py index ec7372f7b..4ab06cbe4 100644 --- a/hathor/event/event_manager.py +++ b/hathor/event/event_manager.py @@ -115,7 +115,7 @@ def _subscribe_events(self): def _handle_event(self, hathor_event: HathorEvents, event_args: EventArguments) -> None: assert self._is_running, 'Cannot handle event, EventManager is not started.' - event_type = EventType.from_hathor_event(hathor_event, event_args) + event_type = EventType.from_hathor_event(hathor_event) event_specific_handlers = { EventType.LOAD_FINISHED: self._handle_load_finished } diff --git a/hathor/event/model/event_type.py b/hathor/event/model/event_type.py index 2848b904f..ff3df2f62 100644 --- a/hathor/event/model/event_type.py +++ b/hathor/event/model/event_type.py @@ -16,48 +16,43 @@ from typing import Dict, Type from hathor.event.model.event_data import BaseEventData, EmptyData, ReorgData, TxData -from hathor.pubsub import EventArguments, HathorEvents +from hathor.pubsub import HathorEvents class EventType(Enum): LOAD_STARTED = 'LOAD_STARTED' LOAD_FINISHED = 'LOAD_FINISHED' NEW_VERTEX_ACCEPTED = 'NEW_VERTEX_ACCEPTED' - NEW_VERTEX_VOIDED = 'NEW_VERTEX_VOIDED' REORG_STARTED = 'REORG_STARTED' REORG_FINISHED = 'REORG_FINISHED' VERTEX_METADATA_CHANGED = 'VERTEX_METADATA_CHANGED' @classmethod - def from_hathor_event(cls, hathor_event: HathorEvents, event_args: EventArguments) -> 'EventType': - if hathor_event == HathorEvents.NETWORK_NEW_TX_ACCEPTED: - metadata = event_args.tx.get_metadata() - - return cls.NEW_VERTEX_VOIDED if metadata.voided_by else cls.NEW_VERTEX_ACCEPTED - - event_map = { - HathorEvents.MANAGER_ON_START: EventType.LOAD_STARTED, - HathorEvents.LOAD_FINISHED: EventType.LOAD_FINISHED, - HathorEvents.REORG_STARTED: EventType.REORG_STARTED, - HathorEvents.REORG_FINISHED: EventType.REORG_FINISHED, - HathorEvents.CONSENSUS_TX_UPDATE: EventType.VERTEX_METADATA_CHANGED - } - - event = event_map.get(hathor_event) + def from_hathor_event(cls, hathor_event: HathorEvents) -> 'EventType': + event = _HATHOR_EVENT_TO_EVENT_TYPE.get(hathor_event) assert event is not None, f'Cannot create EventType from {hathor_event}' return event def data_type(self) -> Type[BaseEventData]: - type_map: Dict[EventType, Type[BaseEventData]] = { - EventType.LOAD_STARTED: EmptyData, - EventType.LOAD_FINISHED: EmptyData, - EventType.NEW_VERTEX_ACCEPTED: TxData, - EventType.NEW_VERTEX_VOIDED: TxData, - EventType.REORG_STARTED: ReorgData, - EventType.REORG_FINISHED: EmptyData, - EventType.VERTEX_METADATA_CHANGED: TxData, - } - - return type_map[self] + return _EVENT_TYPE_TO_EVENT_DATA[self] + + +_HATHOR_EVENT_TO_EVENT_TYPE = { + HathorEvents.MANAGER_ON_START: EventType.LOAD_STARTED, + HathorEvents.LOAD_FINISHED: EventType.LOAD_FINISHED, + HathorEvents.NETWORK_NEW_TX_ACCEPTED: EventType.NEW_VERTEX_ACCEPTED, + HathorEvents.REORG_STARTED: EventType.REORG_STARTED, + HathorEvents.REORG_FINISHED: EventType.REORG_FINISHED, + HathorEvents.CONSENSUS_TX_UPDATE: EventType.VERTEX_METADATA_CHANGED +} + +_EVENT_TYPE_TO_EVENT_DATA: Dict[EventType, Type[BaseEventData]] = { + EventType.LOAD_STARTED: EmptyData, + EventType.LOAD_FINISHED: EmptyData, + EventType.NEW_VERTEX_ACCEPTED: TxData, + EventType.REORG_STARTED: ReorgData, + EventType.REORG_FINISHED: EmptyData, + EventType.VERTEX_METADATA_CHANGED: TxData, +} From 71425e8e14c8b681e5dca58c9e883c535a90decd Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 17 Mar 2023 02:45:21 -0300 Subject: [PATCH 5/6] feat(events): fix CLI tests --- hathor/cli/events_simulator/scenario.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hathor/cli/events_simulator/scenario.py b/hathor/cli/events_simulator/scenario.py index aff5da2e0..718b11b99 100644 --- a/hathor/cli/events_simulator/scenario.py +++ b/hathor/cli/events_simulator/scenario.py @@ -16,7 +16,7 @@ from hathor.event.model.base_event import BaseEvent from hathor.event.model.event_data import TxData, TxMetadata -from hathor.pubsub import HathorEvents +from hathor.event.model.event_type import EventType class Scenario(Enum): @@ -57,7 +57,7 @@ def get_events(self): peer_id='123', id=0, timestamp=0, - type=HathorEvents.NETWORK_NEW_TX_ACCEPTED, + type=EventType.NEW_VERTEX_ACCEPTED, data=_TRANSACTION_DATA_1 ) From 356fe0bca96e7f37668f159aa006b933c3152c9f Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 17 Mar 2023 12:30:00 -0300 Subject: [PATCH 6/6] feat(events): fix resource tests --- tests/resources/event/test_event.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/resources/event/test_event.py b/tests/resources/event/test_event.py index 2ff3985f2..40423d6dc 100644 --- a/tests/resources/event/test_event.py +++ b/tests/resources/event/test_event.py @@ -46,11 +46,11 @@ def test_get_events(web, data): result = response.json_value() expected = { 'events': [ - {'peer_id': '123', 'id': 0, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 0, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None}, - {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None}, - {'peer_id': '123', 'id': 2, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 2, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None} ], 'latest_event_id': 2 @@ -64,7 +64,7 @@ def test_get_events_with_size(web, data): result = response.result.json_value() expected = { 'events': [ - {'peer_id': '123', 'id': 0, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 0, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None} ], 'latest_event_id': 2 @@ -78,9 +78,9 @@ def test_get_events_with_last_ack_event_id(web, data): result = response.result.json_value() expected = { 'events': [ - {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None}, - {'peer_id': '123', 'id': 2, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 2, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None} ], 'latest_event_id': 2 @@ -94,7 +94,7 @@ def test_get_events_with_size_and_last_ack_event_id(web, data): result = response.result.json_value() expected = { 'events': [ - {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'vertex:metadata_changed', 'data': data, + {'peer_id': '123', 'id': 1, 'timestamp': 123456.0, 'type': 'VERTEX_METADATA_CHANGED', 'data': data, 'group_id': None}, ], 'latest_event_id': 2